From e39b7f2136b930ace0916145844e8eedcf3c455f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=95=E7=A6=B9=E9=93=8E?= Date: Sat, 19 Sep 2026 20:32:10 +0800 Subject: [PATCH 01/11] gh-136722: Document the `turtle.TurtleGraphicsError` exception (#157792) Co-authored-by: Stan Ulbrych --- Doc/library/turtle.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index 5dc083c12ccce2..da590bcb8de550 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -2571,6 +2571,25 @@ Public classes * ``a.rotate(angle)`` rotation +Exceptions +========== + +The :mod:`!turtle` module defines the following exception: + +.. exception:: TurtleGraphicsError + + Raised for invalid arguments or operations. + For example, a malformed color string: + + .. doctest:: + :skipif: _tkinter is None + + >>> turtle.color("blau") + Traceback (most recent call last): + ... + turtle.TurtleGraphicsError: bad color string: blau + + .. _turtle-explanation: Explanation From 3229a4e725c8c800b64f0fdf0e3c3943d79afd29 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Sat, 19 Sep 2026 13:53:07 +0100 Subject: [PATCH 02/11] Upgrade `Doc/pylock.toml` (#157793) --- Doc/Makefile | 4 +- Doc/pylock.toml | 204 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 139 insertions(+), 69 deletions(-) diff --git a/Doc/Makefile b/Doc/Makefile index ef6ef8c42e3636..881719394b6366 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -191,8 +191,8 @@ lock: # Dependencies have a 14 day cooldown period to mitigate supply chain attacks, # except for sphinx_linklint and python-docs-theme, which are maintained by # core team members. - uv pip compile requirements.txt \ - --exclude-newer P14D \ + $(UV) pip compile requirements.txt \ + --upgrade --exclude-newer P14D \ --exclude-newer-package sphinx_linklint=PT0S \ --exclude-newer-package python-docs-theme=PT0S \ --no-cache --output-file $(REQUIREMENTS) \ diff --git a/Doc/pylock.toml b/Doc/pylock.toml index 3ad79b3cc6a873..62f144e511fe08 100644 --- a/Doc/pylock.toml +++ b/Doc/pylock.toml @@ -18,9 +18,9 @@ wheels = [{ url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b04 [[packages]] name = "blurb" -version = "2.0.0" -sdist = { url = "https://files.pythonhosted.org/packages/d7/82/8597d891f4b03f3eaefcb4213a811643d558350cac9a69864d127832cc4f/blurb-2.0.0.tar.gz", upload-time = 2025-01-15T12:48:53Z, size = 24666, hashes = { sha256 = "c78d8114294225a4f7a2eabba6e05d36a6a50e45ba9f5a41afabc198350038e0" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/b4/03/374bd9e31b58e8a8e5dc65cc3f68ca7cdd716c32b5e5dcb0e1b76bb75b4a/blurb-2.0.0-py3-none-any.whl", upload-time = 2025-01-15T12:48:49Z, size = 18924, hashes = { sha256 = "f6d0e858dbe94765f6a89b8228217ffdb9c19cff08fc8f2c3153954846d31aa1" } }] +version = "2.1.0" +sdist = { url = "https://files.pythonhosted.org/packages/5b/9e/f38cff22d0e00f0ae5bb67bc57dbf3b6bfc9d61933b6451744568b90be7d/blurb-2.1.0.tar.gz", upload-time = 2026-08-27T15:32:29Z, size = 28097, hashes = { sha256 = "0154689a5aa009174b5e332a6997318e82e1b12b57fce03162ed49ea25c65652" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/01/f4/f4b0958ee24cd7355a4edccf6dbb5c76329544aa25eadb21963838e1e2c9/blurb-2.1.0-py3-none-any.whl", upload-time = 2026-08-27T15:32:28Z, size = 22980, hashes = { sha256 = "dfc96f59f2431a245df96f601df5b7b9a96e39e6887430046fa774fb61c910bb" } }] [[packages]] name = "certifi" @@ -30,62 +30,132 @@ wheels = [{ url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec21 [[packages]] name = "charset-normalizer" -version = "3.4.9" -sdist = { url = "https://files.pythonhosted.org/packages/bd/2a/23f34ec9d04624958e137efdc394888716353190e75f25dd22c7a2c7a8aa/charset_normalizer-3.4.9.tar.gz", upload-time = 2026-07-07T14:34:58Z, size = 152439, hashes = { sha256 = "673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b" } } +version = "3.5.1" +sdist = { url = "https://files.pythonhosted.org/packages/e5/3f/143b048436775b0f76ac3eec145c019e8173ccc2885c8f20319b996d5e83/charset_normalizer-3.5.1.tar.gz", upload-time = 2026-08-15T08:20:44Z, size = 171764, hashes = { sha256 = "6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3" } } wheels = [ - { url = "https://files.pythonhosted.org/packages/70/4a/ecbd131485c07fcdfad54e28946d513e3da22ef3b4bd854dcafae54ec739/charset_normalizer-3.4.9-cp312-cp312-macosx_10_13_universal2.whl", upload-time = 2026-07-07T14:33:15Z, size = 319300, hashes = { sha256 = "45b0cc4e3556cd875e09102988d1ab8356c998b596c9fced84547c8138b487a0" } }, - { url = "https://files.pythonhosted.org/packages/ec/96/5d9364e3342d69f3a045e1777bc47c85c383e6e9466d561b33fdb419d1f9/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-07-07T14:33:17Z, size = 215802, hashes = { sha256 = "9b2aff1c7b3884512b9512c3eaadd9bab39fb45042ffaaa1dd08ff2b9f8109d9" } }, - { url = "https://files.pythonhosted.org/packages/4b/4c/5361f9aa7f2cb58d94f2ab831b3d493f69efb1d239654b4744e3c09527cb/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-07-07T14:33:18Z, size = 237171, hashes = { sha256 = "9104ed0bd76a429d46f9ec0dbc9b08ad1d2dcdf2b00a5a0daa1c145329b35b44" } }, - { url = "https://files.pythonhosted.org/packages/50/78/ce342ca4ff30b2eb49fe6d9578df85974f90c67d294113e94efdd9664cbd/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-07-07T14:33:20Z, size = 233075, hashes = { sha256 = "7b86a2b16095d250c6f58b3d9b2eee6f4147754344f3dab0922f7c9bf7d226c9" } }, - { url = "https://files.pythonhosted.org/packages/01/c4/4fa4c8b3097a11f3c5f09a35b72ed6855fb1d332469504962ab7bafcc702/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-07-07T14:33:21Z, size = 224256, hashes = { sha256 = "5e226f6218febc71f6c1fc2fafb91c226f75bdc1d8fb12d66823716e891608fd" } }, - { url = "https://files.pythonhosted.org/packages/87/3a/ad914516df7e358a81aae018caa5e0470ba827fa6d763b1d2e87d920a5f6/charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_armv7l.whl", upload-time = 2026-07-07T14:33:23Z, size = 208784, hashes = { sha256 = "90c44bc373b7687f6948b693cceaea1348ae0975d7474746559494468e3c1d84" } }, - { url = "https://files.pythonhosted.org/packages/d7/74/3c12f9755717dfe5c5c87da63f35d765fa0c00382ec26bf23f7fae34f2ba/charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-07-07T14:33:24Z, size = 219928, hashes = { sha256 = "9cdef90ae47919cae358d8ab15797a800ed41da7aba5d72419fb510729e2ed4b" } }, - { url = "https://files.pythonhosted.org/packages/33/9a/895095b83e7907abd6d3d99aad3a38ad0d9686cc186cb0c94c24320fe63e/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", upload-time = 2026-07-07T14:33:26Z, size = 218489, hashes = { sha256 = "60f44ade2cf573dad7a277e6f8ca9a51a21dda572b13bd7d8539bb3cd5dbedde" } }, - { url = "https://files.pythonhosted.org/packages/a1/34/ef5c05f412f42520d7709b7d3784d19640839eb7366ded1755511585429f/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_armv7l.whl", upload-time = 2026-07-07T14:33:27Z, size = 210267, hashes = { sha256 = "a1786910334ed46ab1dd73222f2cd1e05c2c3bb39f6dddb4f8b36fc382058a39" } }, - { url = "https://files.pythonhosted.org/packages/83/dc/9b29fa4412b318bf3bfea985c35d67eb55e04b59a7c3f2237168b0e0be6f/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", upload-time = 2026-07-07T14:33:29Z, size = 226030, hashes = { sha256 = "03d07803992c6c7bbc976327f34b18b6160327fc81cb82c9d504720ac0be3b62" } }, - { url = "https://files.pythonhosted.org/packages/0e/42/6dbc00b8cd16011691203e33570fa42ed5746599a2e878112d16eab403a3/charset_normalizer-3.4.9-cp312-cp312-win32.whl", upload-time = 2026-07-07T14:33:30Z, size = 151185, hashes = { sha256 = "78841cccf1af7b40f6f716338d50c0902dbe88d9f800b3c973b7a9a0a693a642" } }, - { url = "https://files.pythonhosted.org/packages/80/cc/f920afd1a23c58ccd53c1d36085a71893a4737ff5e66e0371efab6809850/charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl", upload-time = 2026-07-07T14:33:32Z, size = 162557, hashes = { sha256 = "4b3dac63058cc36820b0dd072f89898604e2d39686fe05321729d00d8ac185a0" } }, - { url = "https://files.pythonhosted.org/packages/f0/e6/0386d43a261ff4e4b30c5857af7df877254b46bec7b9d1b74b6bf969a90b/charset_normalizer-3.4.9-cp312-cp312-win_arm64.whl", upload-time = 2026-07-07T14:33:33Z, size = 152665, hashes = { sha256 = "78fa18e436a1a0e58dbd7e02fc4473f3f32cceb12df9dfca542d075961c307d2" } }, - { url = "https://files.pythonhosted.org/packages/b2/06/97ec2aeae780b31d742b6352218b43841a6871e2564578ca522dce4a45c3/charset_normalizer-3.4.9-cp313-cp313-macosx_10_13_universal2.whl", upload-time = 2026-07-07T14:33:35Z, size = 317688, hashes = { sha256 = "440eede837960000d74978f0eba527be106b5b9aee0daf779d395276ed0b0614" } }, - { url = "https://files.pythonhosted.org/packages/d0/39/8ff066c672434225f8d25f8b739f992af250944392173dcc88362681c9bf/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-07-07T14:33:36Z, size = 214982, hashes = { sha256 = "21e764fd1e70b6a3e205a0e46f3051701f98a8cb3fad66eeb80e48bb502f8698" } }, - { url = "https://files.pythonhosted.org/packages/92/8f/3a47a3667c83c2df9483d91644c6c107de3bf8874aa1793da9d3012eb986/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-07-07T14:33:38Z, size = 236460, hashes = { sha256 = "e4fd89cc178bced6ad29cb3e6dd4aa63fa5017c3524dbd0b25998fb64a87cc8b" } }, - { url = "https://files.pythonhosted.org/packages/f1/60/b22cdbee7e4013dab8b0d7647fc6181120fbbbc8f7025c226d15bd5a47fc/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-07-07T14:33:40Z, size = 232003, hashes = { sha256 = "bd47ba7fc3ca94896759ea0109775132d3e7ab921fbf54038e1bab2e46c313c9" } }, - { url = "https://files.pythonhosted.org/packages/ea/f8/72eb13dcabe7257035cea8aefd922caad2f110d252bf9f67c4c2ca763aee/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-07-07T14:33:41Z, size = 223149, hashes = { sha256 = "84fd18bcc17526fc2b3c1af7d2b9217d32c9c04448c16ec693b9b4f1985c3d33" } }, - { url = "https://files.pythonhosted.org/packages/b0/3e/faee8f9de92b14ee1198e9163252bb15efee7301b31256a3b6d9ebfdd0dd/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_armv7l.whl", upload-time = 2026-07-07T14:33:43Z, size = 207901, hashes = { sha256 = "5b10cd92fc5c498b35a8635df6d5a100207f88b63a4dc1de7ef9a548e1e2cd63" } }, - { url = "https://files.pythonhosted.org/packages/3a/25/45f30093ae27dd7b92a793b61882a38685f993700113ca36e0c9c14965e1/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-07-07T14:33:44Z, size = 219176, hashes = { sha256 = "a4fbdde9dd4a9ce5fd52c2b3a347bb50cc89483ef783f1cb00d408c13f7a96c0" } }, - { url = "https://files.pythonhosted.org/packages/48/18/c8f397329c35e32f6a837e488986f4ae03bd2abebc453b48714991630c2f/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", upload-time = 2026-07-07T14:33:46Z, size = 217356, hashes = { sha256 = "416c229f77e5ea25b3dfd4b582f8d73d7e43c22320302b9ab128a2d3a0b38efe" } }, - { url = "https://files.pythonhosted.org/packages/86/7e/5ce0bba863470fd1902d5e5843968951bddf38abe4742fc97116ef4598b3/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_armv7l.whl", upload-time = 2026-07-07T14:33:47Z, size = 209614, hashes = { sha256 = "75286256590a6320cf106a0d28970d3560aad9ee09aa7b34fb40524792436d35" } }, - { url = "https://files.pythonhosted.org/packages/6c/ef/2473d3c4d869155be4af1191111d59c4d5c4e0173026f7e85b176e23bf65/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", upload-time = 2026-07-07T14:33:49Z, size = 224991, hashes = { sha256 = "69b157c5d3292bcd443faca052f3096f637f1e074b98212a933c074ae23dc3b8" } }, - { url = "https://files.pythonhosted.org/packages/d0/a3/53ddae3db108a088156aa8ddfafd411ebbc1340f48c5573f697b27f69a39/charset_normalizer-3.4.9-cp313-cp313-win32.whl", upload-time = 2026-07-07T14:33:50Z, size = 150622, hashes = { sha256 = "51307f5c71007673a2bf8232ad973483d281e74cb99c8c5a990af1eefa6277d9" } }, - { url = "https://files.pythonhosted.org/packages/e8/ef/6953a77c7cf2c2ff9998e6f575ab3e380119f100223381565a4f94c1f836/charset_normalizer-3.4.9-cp313-cp313-win_amd64.whl", upload-time = 2026-07-07T14:33:52Z, size = 161947, hashes = { sha256 = "fe2c7201c642b7c308f1675355ad7ff7b66acfe3541625efe5a3ad38f29d6115" } }, - { url = "https://files.pythonhosted.org/packages/6e/fb/d560d1d1555debbfe7849d9cac6145c1b537709d79576bf22557ed803b82/charset_normalizer-3.4.9-cp313-cp313-win_arm64.whl", upload-time = 2026-07-07T14:33:53Z, size = 152594, hashes = { sha256 = "611057cc5d5c0afc743ba8be6bd828c17e0aaa8643f9d0a9b9bb7dea80eb8012" } }, - { url = "https://files.pythonhosted.org/packages/7e/8d/496817fa0944239ecae662dd57ea765cfeaec6a735f9f025d4b7b72e7143/charset_normalizer-3.4.9-cp314-cp314-macosx_10_15_universal2.whl", upload-time = 2026-07-07T14:33:54Z, size = 317253, hashes = { sha256 = "0327fcd59a935777d83410750c50600ee9571af2846f71ce40f25b13da1ef380" } }, - { url = "https://files.pythonhosted.org/packages/2b/f9/ef4a69ea338ad3c0deceea0f5f7d2380ae8b52132b06d652cb0d2cd86706/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-07-07T14:33:56Z, size = 215898, hashes = { sha256 = "8a79d9f4d8001473a30c163556b3c3bfebec837495a412dde78b51672f6134f9" } }, - { url = "https://files.pythonhosted.org/packages/8c/e7/5ddfd76fc061eb52de219658a4aa431cbacadf0a0219c8854f00da50d289/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-07-07T14:33:57Z, size = 236718, hashes = { sha256 = "33bdcc2a32c0a0e861f60841a512c8acc658c87c2ac59d89e3a46dacf7d866e4" } }, - { url = "https://files.pythonhosted.org/packages/49/ba/768fa3f36048d81c477a0ce61f813bc1454d80917ccfe550abd9f44f5e24/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-07-07T14:33:59Z, size = 232519, hashes = { sha256 = "f840ed6d8ecba8255df8c42b87fadeda98ddfc6eeec05e2dc66e26d46dd6f58a" } }, - { url = "https://files.pythonhosted.org/packages/f4/c4/b3e049d2aa3766180c78507110543d9d50894cc97f57de543f1be521dcdc/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-07-07T14:34:01Z, size = 223143, hashes = { sha256 = "c25fe15c70c59eb7c5ce8c06a1f3fa1da0ecc5ea1e7a5922c40fd2fa9b0d5046" } }, - { url = "https://files.pythonhosted.org/packages/19/79/55c32d06d76ae4feafe053f061f3e3ab70bcf19f4007797ce8c3efda7830/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_armv7l.whl", upload-time = 2026-07-07T14:34:03Z, size = 206742, hashes = { sha256 = "f7fb7d750cfa0a070d2c24e831fd3481019a60dd317ea2b39acbcebc08b6ed81" } }, - { url = "https://files.pythonhosted.org/packages/10/e0/47c079dd82d217c807479cd59ffd30af56307ea31c108b75758970459ad3/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-07-07T14:34:04Z, size = 219191, hashes = { sha256 = "4d1c96a7a18b9690a4d46df09e3e3382406ae3213727cd1019ebade1c4a81917" } }, - { url = "https://files.pythonhosted.org/packages/42/ab/b9bc2e77d6b44a7e46ef62ec5cac1c9a6ba7b9135a5d560f002696ec9995/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", upload-time = 2026-07-07T14:34:06Z, size = 218328, hashes = { sha256 = "a4cfde78a9f2880208d16a93b795726a3017d5977e08d1e162a7a31322479c41" } }, - { url = "https://files.pythonhosted.org/packages/f1/78/c9c71d599f5aa2d42bcdd35cbbd46d7f535351a57e40ff7d8e5a7e219401/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_armv7l.whl", upload-time = 2026-07-07T14:34:07Z, size = 207406, hashes = { sha256 = "d4d6fcde76f94f5cb9e43e9e9a61f16dacefd228cbbf6f1a09bd9b219a92f1a1" } }, - { url = "https://files.pythonhosted.org/packages/f6/39/c914445c321a845097ce4f6ac7de9a18228a77b766272125a1ce00d851eb/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", upload-time = 2026-07-07T14:34:09Z, size = 225157, hashes = { sha256 = "898f0e9068ca27d37f8e83a5b962821df851532e6c4a7d615c1c033f9da6eedf" } }, - { url = "https://files.pythonhosted.org/packages/9b/f2/c0d4b8508565a36bc5c624e88ed297f5b0b1095011034d7f5b83a69908b5/charset_normalizer-3.4.9-cp314-cp314-win32.whl", upload-time = 2026-07-07T14:34:10Z, size = 151095, hashes = { sha256 = "c1c948747b03be832dceed96ca815cef7360de9aa19d37c730f8e3f6101aca48" } }, - { url = "https://files.pythonhosted.org/packages/49/fd/a1d26144398c67486422a72bf5812cda22cb4ccfcd95a290fb41ceb4b8e2/charset_normalizer-3.4.9-cp314-cp314-win_amd64.whl", upload-time = 2026-07-07T14:34:12Z, size = 162796, hashes = { sha256 = "16b65ea0f2465b6fb52aa22de5eca612aa964ddfec00a912e26f4656cbef890b" } }, - { url = "https://files.pythonhosted.org/packages/20/95/d75e82f8ce9fd323ebf059c16c9aadefb22a1ecde13b7840b35835e4886c/charset_normalizer-3.4.9-cp314-cp314-win_arm64.whl", upload-time = 2026-07-07T14:34:14Z, size = 153334, hashes = { sha256 = "40a126142a56b2dfc0aacbad1de8310cbf60da7656db0e6b16eebd48e3e93519" } }, - { url = "https://files.pythonhosted.org/packages/00/5e/17398df3a139985ba9d11ed072531986f408c8fca952835ef1ab1820c02b/charset_normalizer-3.4.9-cp314-cp314t-macosx_10_15_universal2.whl", upload-time = 2026-07-07T14:34:15Z, size = 338848, hashes = { sha256 = "609b3ba8fcc0fb5ab7af00719d0fb6ad0cb518e48e7712d12fd68f1327951198" } }, - { url = "https://files.pythonhosted.org/packages/cd/91/7253a32e86b7e1d1239b1b36ba6dd0f021a21107ab33054b53119cc083b9/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-07-07T14:34:17Z, size = 223022, hashes = { sha256 = "51447e9aa2684679af07ca5021c3db526e0284347ebf4ffcec1154c3350cfe32" } }, - { url = "https://files.pythonhosted.org/packages/cb/32/2e64bd2be10e89c61e57ebe6a93fd98ae88eb7ebe414b5121f22c96c69eb/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-07-07T14:34:18Z, size = 241590, hashes = { sha256 = "cc1b0fff8ead343dae06305f954eb8468ba0ec1a97881f42489d198e4ce3c632" } }, - { url = "https://files.pythonhosted.org/packages/3d/ef/d96ec496cfea0c21db43b0ad03891308b02388d054cc902cf0e5a1ad6a88/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-07-07T14:34:20Z, size = 239584, hashes = { sha256 = "fa36ec09ef71d158186bc79e359ff5fdd6e7996fe8ab638f00d6b93139ba4fcf" } }, - { url = "https://files.pythonhosted.org/packages/d4/ce/9af95f7876194bd7a14e3dfe4a4de2e0bff02666a3910d72beafd06cc297/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-07-07T14:34:22Z, size = 230224, hashes = { sha256 = "df115d4d83168fdf2cae48ef1ff6d1cb4c466364e30861b37121de0f3bf1b990" } }, - { url = "https://files.pythonhosted.org/packages/52/94/af74dde74a3996bd959c350709bfe50e297823d70a8c1cbd54b838880863/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_armv7l.whl", upload-time = 2026-07-07T14:34:23Z, size = 212667, hashes = { sha256 = "f86c6358749bd4fda175388691e3ba8c46e24c5347d0afd20f9b7edfc9faf07d" } }, - { url = "https://files.pythonhosted.org/packages/ee/f0/f1c4fe746c395922961b5916ed1d7d6e7d4c84851d19ed43cc89980ec953/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-07-07T14:34:25Z, size = 227179, hashes = { sha256 = "32286a2c8d167e897177b673176c1e3e00d4057caf5d2b64eef9a3666b03018e" } }, - { url = "https://files.pythonhosted.org/packages/e4/56/6c745619ac397e8871e2bcd3cea1eec86b877488f33888b3aef5c3ed506e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", upload-time = 2026-07-07T14:34:27Z, size = 225372, hashes = { sha256 = "83aed2c10721ddd90f68140685391b50811a880af20654c59af6b6c66c40513c" } }, - { url = "https://files.pythonhosted.org/packages/78/ad/98aae8630ac71f16711968e38a5acfecce41b778bf2f0312851020f565a8/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_armv7l.whl", upload-time = 2026-07-07T14:34:28Z, size = 215222, hashes = { sha256 = "cd6c3d4b783c556fa00bf540854e42f135e2f256abd29669fcd0da0f2dec79c2" } }, - { url = "https://files.pythonhosted.org/packages/f7/40/9593d54209765207a7f11073c06494c1721e4ca4a0a426c597679bf7f91e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", upload-time = 2026-07-07T14:34:30Z, size = 231958, hashes = { sha256 = "ee2f2a527e3c1a6e6411eb4209642e138b544a2d72fe5d0d76daf77b24063534" } }, - { url = "https://files.pythonhosted.org/packages/b1/27/693ee5e8a18191eb38647360c51cd505013e2bd3b366aa43fd5344c21e3c/charset_normalizer-3.4.9-cp314-cp314t-win32.whl", upload-time = 2026-07-07T14:34:31Z, size = 155580, hashes = { sha256 = "0d861473f743244d349b50f850d10eb87aeb22bbdcc8e64f79273c94af5a8226" } }, - { url = "https://files.pythonhosted.org/packages/80/3f/bd97d3d9c613013d07cb7733d299385b41df37f0471310f5a73dc359f0b8/charset_normalizer-3.4.9-cp314-cp314t-win_amd64.whl", upload-time = 2026-07-07T14:34:33Z, size = 167620, hashes = { sha256 = "9b8e0f3107e2200b76f6054de99016eac3ee6762713587b36baaa7e4bd2ae177" } }, - { url = "https://files.pythonhosted.org/packages/3d/c6/eee9dca4439b1061f76373f06ea855678cc4a64c1c3c90b50e479edbb8eb/charset_normalizer-3.4.9-cp314-cp314t-win_arm64.whl", upload-time = 2026-07-07T14:34:35Z, size = 158037, hashes = { sha256 = "19ac87f93086ce37b86e098888555c4b4bc48102279bae3350098c0ed664b501" } }, - { url = "https://files.pythonhosted.org/packages/98/2b/f97f1c193fb855c345d678f5077d6926034db0722df74c8f057020e05a25/charset_normalizer-3.4.9-py3-none-any.whl", upload-time = 2026-07-07T14:34:56Z, size = 64538, hashes = { sha256 = "68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5" } }, + { url = "https://files.pythonhosted.org/packages/30/27/78873dc8b6a56357517b74b6bb9568b80450e7bb4f6ef7e3fa9d22aa0bd7/charset_normalizer-3.5.1-cp312-cp312-macosx_10_13_universal2.whl", upload-time = 2026-08-15T08:17:10Z, size = 344456, hashes = { sha256 = "5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f" } }, + { url = "https://files.pythonhosted.org/packages/9a/4c/be49ada26b1f0232d57aa89bbebf997a5cc2332a5616b6eca26ff680044d/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-08-15T08:17:11Z, size = 238530, hashes = { sha256 = "4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa" } }, + { url = "https://files.pythonhosted.org/packages/76/84/6f1290fa07ae6978d3960caa3eb1b8019bf9284ab7c2297b00c099ef4250/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", upload-time = 2026-08-15T08:17:12Z, size = 230200, hashes = { sha256 = "1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369" } }, + { url = "https://files.pythonhosted.org/packages/e7/a0/47b18adeed31c8f16ba9700f32c1b18594cfa09f47eb672a488c273c22bf/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-08-15T08:17:14Z, size = 262222, hashes = { sha256 = "e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893" } }, + { url = "https://files.pythonhosted.org/packages/38/fe/341861ac118dae06f3ec0eb487488af52128f2ef2faf0b11003944d22259/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-08-15T08:17:16Z, size = 258951, hashes = { sha256 = "7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0" } }, + { url = "https://files.pythonhosted.org/packages/6f/89/bb5108dc6c3651dca963f2b0a3ba19bbcb370c94e1b6d3e0e844a58e6dca/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-08-15T08:17:17Z, size = 248801, hashes = { sha256 = "b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08" } }, + { url = "https://files.pythonhosted.org/packages/b1/ba/ef83ae3aca816393decfa3530976f38a79812d707b80b580ac33b83f9877/charset_normalizer-3.5.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-08-15T08:17:19Z, size = 244070, hashes = { sha256 = "f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada" } }, + { url = "https://files.pythonhosted.org/packages/f6/0b/c5292a2462d69b7378ea89793bbb5b2b6fcf6f7dd6d1667f9619094ad553/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_aarch64.whl", upload-time = 2026-08-15T08:17:20Z, size = 240110, hashes = { sha256 = "96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9" } }, + { url = "https://files.pythonhosted.org/packages/46/22/111e5be3b740d5c2a5bfcedb3d237b6591e5c2e82ae9d6ffcb121fe0909c/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_armv7l.whl", upload-time = 2026-08-15T08:17:21Z, size = 232836, hashes = { sha256 = "5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e" } }, + { url = "https://files.pythonhosted.org/packages/f9/d2/d2aad6fe0dbb44b194bf3becb60f5a0ac48446ade999a47fe7bb41eb09a7/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_ppc64le.whl", upload-time = 2026-08-15T08:17:23Z, size = 262712, hashes = { sha256 = "aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6" } }, + { url = "https://files.pythonhosted.org/packages/35/5a/337e4663a5eae6de99db940ee8066d4145caafb61327db62deda15313cce/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_riscv64.whl", upload-time = 2026-08-15T08:17:25Z, size = 242977, hashes = { sha256 = "7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf" } }, + { url = "https://files.pythonhosted.org/packages/ca/85/f82f8a92e31c7519410e2e1afdc630f28ec47490ce2c09a11c1a43cbb459/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_s390x.whl", upload-time = 2026-08-15T08:17:26Z, size = 260207, hashes = { sha256 = "4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71" } }, + { url = "https://files.pythonhosted.org/packages/b7/52/643d11ffd60e9ac2fd1fb87e167a19285b9eefeff4a40e63c87cbfbeab36/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_x86_64.whl", upload-time = 2026-08-15T08:17:27Z, size = 250562, hashes = { sha256 = "ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573" } }, + { url = "https://files.pythonhosted.org/packages/62/16/46556278c2168d12df9da7fede5dc6fc70e60301b26a82bbeec238c9cfe3/charset_normalizer-3.5.1-cp312-cp312-win32.whl", upload-time = 2026-08-15T08:17:29Z, size = 178507, hashes = { sha256 = "cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2" } }, + { url = "https://files.pythonhosted.org/packages/9d/7a/4c6c298171e6b3e745633180ff59350fc0ca0db1ffd28df1e369e0579f71/charset_normalizer-3.5.1-cp312-cp312-win_amd64.whl", upload-time = 2026-08-15T08:17:30Z, size = 200551, hashes = { sha256 = "3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2" } }, + { url = "https://files.pythonhosted.org/packages/cd/d7/eb95a042f0dd22e304b0b6472b154f3546a1a039a9ee89ccb2a7f61591fc/charset_normalizer-3.5.1-cp312-cp312-win_arm64.whl", upload-time = 2026-08-15T08:17:32Z, size = 180700, hashes = { sha256 = "88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a" } }, + { url = "https://files.pythonhosted.org/packages/bc/61/2cb6ad133dbbb449fa2d37ccae973232f4827e799af258d15e589a3d1e9e/charset_normalizer-3.5.1-cp313-cp313-android_24_arm64_v8a.whl", upload-time = 2026-08-15T08:17:33Z, size = 211584, hashes = { sha256 = "4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9" } }, + { url = "https://files.pythonhosted.org/packages/18/57/a305c968be1ca13f3dd1b32f445877e97addf55d80b65c7cb35fac82b777/charset_normalizer-3.5.1-cp313-cp313-android_24_x86_64.whl", upload-time = 2026-08-15T08:17:35Z, size = 223359, hashes = { sha256 = "88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491" } }, + { url = "https://files.pythonhosted.org/packages/09/0a/d3646670292ce8d8f8cc11ac067d44885e697a5591f57a9221128da5e7b3/charset_normalizer-3.5.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", upload-time = 2026-08-15T08:17:36Z, size = 194464, hashes = { sha256 = "9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7" } }, + { url = "https://files.pythonhosted.org/packages/de/93/d51ec556e01042fed6f993ea859311bc7917b466684182fbbceb6ca24762/charset_normalizer-3.5.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", upload-time = 2026-08-15T08:17:37Z, size = 197676, hashes = { sha256 = "977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e" } }, + { url = "https://files.pythonhosted.org/packages/a4/a0/562247944386f7d4ef94467e84876600cc1e0f1b93239aaa9213d2bc3cbd/charset_normalizer-3.5.1-cp313-cp313-macosx_10_13_universal2.whl", upload-time = 2026-08-15T08:17:39Z, size = 340473, hashes = { sha256 = "e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d" } }, + { url = "https://files.pythonhosted.org/packages/31/e7/1d994be1b93d41e9502b8b0460eaa88a1dd8df335df415db87d6c3e91ab2/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-08-15T08:17:40Z, size = 240156, hashes = { sha256 = "94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a" } }, + { url = "https://files.pythonhosted.org/packages/09/53/27923ce5cc6cbccb832037b27dca98882d9c53e9b69e866bbbef4aae7fc8/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", upload-time = 2026-08-15T08:17:42Z, size = 228246, hashes = { sha256 = "d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe" } }, + { url = "https://files.pythonhosted.org/packages/ce/48/5a97e84d63af1d55c07439cb80e56d99a8efb4295700eb4e18c0d1615d2c/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-08-15T08:17:43Z, size = 263660, hashes = { sha256 = "0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac" } }, + { url = "https://files.pythonhosted.org/packages/7a/c2/071575791dcc88316c0a9a65ce38897a82e4cfe4a325f0f7fe1b1ac47bcf/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-08-15T08:17:45Z, size = 260354, hashes = { sha256 = "394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e" } }, + { url = "https://files.pythonhosted.org/packages/fb/af/63240b0c0248c075c2535a1f1bd992821d8251b9f173abc13329661d09e4/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-08-15T08:17:46Z, size = 250638, hashes = { sha256 = "62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3" } }, + { url = "https://files.pythonhosted.org/packages/4d/66/70dfad64f15be09c15ccfee81330a7e515895dbe296dd23114e9a231268a/charset_normalizer-3.5.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-08-15T08:17:47Z, size = 244583, hashes = { sha256 = "fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876" } }, + { url = "https://files.pythonhosted.org/packages/c0/24/ef36367d38b9ddd4bccbf72888c342e8de1f5ae506fa0b2dcf970e2732a1/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_aarch64.whl", upload-time = 2026-08-15T08:17:49Z, size = 242038, hashes = { sha256 = "c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6" } }, + { url = "https://files.pythonhosted.org/packages/db/ab/55e683ba0fff2e43adafc10daa3001eac90fdaa419a97227d5a7067eedde/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_armv7l.whl", upload-time = 2026-08-15T08:17:50Z, size = 233677, hashes = { sha256 = "485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2" } }, + { url = "https://files.pythonhosted.org/packages/bd/67/0f40eaf8d1b6e7cf15e82382a2965efaca787fc1c2794b7021d37aaf5036/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_ppc64le.whl", upload-time = 2026-08-15T08:17:52Z, size = 264491, hashes = { sha256 = "5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591" } }, + { url = "https://files.pythonhosted.org/packages/5c/64/12b4c2a11ee8df4fcc518c78b0d93e3a92bd3d5253d1617ce74ff0e8c7ef/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_riscv64.whl", upload-time = 2026-08-15T08:17:54Z, size = 245196, hashes = { sha256 = "90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c" } }, + { url = "https://files.pythonhosted.org/packages/37/2e/651d910af6d0fba325eee1cda37ec5443462ed25360e666c144166eb6091/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_s390x.whl", upload-time = 2026-08-15T08:17:55Z, size = 261660, hashes = { sha256 = "35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c" } }, + { url = "https://files.pythonhosted.org/packages/90/c6/b09e05e6db7f64338e0dc067c79577b1138da86c1e38369096851d96be88/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_x86_64.whl", upload-time = 2026-08-15T08:17:57Z, size = 252618, hashes = { sha256 = "fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f" } }, + { url = "https://files.pythonhosted.org/packages/76/4e/362d4f9fdcdf5556fb2aa3ce7d4a58ebce03ed1ff03aa1d9aca8d02f13f3/charset_normalizer-3.5.1-cp313-cp313-pyemscripten_2025_0_wasm32.whl", upload-time = 2026-08-15T08:17:58Z, size = 140362, hashes = { sha256 = "9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4" } }, + { url = "https://files.pythonhosted.org/packages/b4/d4/703be739b26acce318bd29eb3b25b7209e1b1f527f9eae3d1f1f01fdde2b/charset_normalizer-3.5.1-cp313-cp313-win32.whl", upload-time = 2026-08-15T08:18:00Z, size = 177755, hashes = { sha256 = "d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3" } }, + { url = "https://files.pythonhosted.org/packages/8a/33/56d97ade41c8db611e727168c52ae46c9224c362ec28d4b65d7e9869e8da/charset_normalizer-3.5.1-cp313-cp313-win_amd64.whl", upload-time = 2026-08-15T08:18:01Z, size = 199295, hashes = { sha256 = "aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6" } }, + { url = "https://files.pythonhosted.org/packages/5b/75/5b20dd1e6573a01a08158fe104104fa2c8abf941745596954185726cd46c/charset_normalizer-3.5.1-cp313-cp313-win_arm64.whl", upload-time = 2026-08-15T08:18:02Z, size = 179856, hashes = { sha256 = "fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0" } }, + { url = "https://files.pythonhosted.org/packages/29/cd/2b812ce5e888f1ce69a5350281e58aab07ae64a958ecae8912f30865718e/charset_normalizer-3.5.1-cp314-cp314-android_24_arm64_v8a.whl", upload-time = 2026-08-15T08:18:04Z, size = 212318, hashes = { sha256 = "774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8" } }, + { url = "https://files.pythonhosted.org/packages/9e/4a/a6ee107430768a5334e6d63f31f148a04a1a491ef161a1ac9415a73f2fa8/charset_normalizer-3.5.1-cp314-cp314-android_24_x86_64.whl", upload-time = 2026-08-15T08:18:05Z, size = 224897, hashes = { sha256 = "26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102" } }, + { url = "https://files.pythonhosted.org/packages/c3/d9/35ae3f64f29d0179c35c3baefe575904df2913dde519129c7f75995a2b1d/charset_normalizer-3.5.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", upload-time = 2026-08-15T08:18:07Z, size = 194848, hashes = { sha256 = "09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5" } }, + { url = "https://files.pythonhosted.org/packages/74/76/f2fc7380f056cc273a53af37f50d08ad54b2c59f61078f31432edcf1c2bd/charset_normalizer-3.5.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", upload-time = 2026-08-15T08:18:08Z, size = 198163, hashes = { sha256 = "4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3" } }, + { url = "https://files.pythonhosted.org/packages/e9/40/095ce62fa078483cccc1fa2b36e6bc9580b85422a20ee9f925341c50e44f/charset_normalizer-3.5.1-cp314-cp314-macosx_10_15_universal2.whl", upload-time = 2026-08-15T08:18:10Z, size = 341823, hashes = { sha256 = "c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c" } }, + { url = "https://files.pythonhosted.org/packages/f1/5a/0e58b1c04a1596e0256f407274a92d5fb2ee21324409d1fab1da48a65b5b/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-08-15T08:18:11Z, size = 242458, hashes = { sha256 = "2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0" } }, + { url = "https://files.pythonhosted.org/packages/22/95/b4618ce912e6db0b1aae89ba788e38e8a7eba0f3025cc66e8c0699f977b2/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", upload-time = 2026-08-15T08:18:13Z, size = 226717, hashes = { sha256 = "6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96" } }, + { url = "https://files.pythonhosted.org/packages/8a/76/c681192bbda3d55356db5dadd64381d5202b37c6b598fcda5282e88b5d3d/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-08-15T08:18:14Z, size = 266111, hashes = { sha256 = "ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc" } }, + { url = "https://files.pythonhosted.org/packages/88/be/55127bfca72c0cff6c022488d140d7c5b04c771e3b72e9bdb4836d54979d/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-08-15T08:18:16Z, size = 263128, hashes = { sha256 = "f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f" } }, + { url = "https://files.pythonhosted.org/packages/e0/91/39c3af510b0aa32bbda03374259200f28430febfd1bf5e511fe765282ce5/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-08-15T08:18:18Z, size = 251240, hashes = { sha256 = "15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90" } }, + { url = "https://files.pythonhosted.org/packages/1c/a5/cbe418bbc6ecdfc3e05a0116002897c4b403a5e838d697e64c78e9f0190d/charset_normalizer-3.5.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-08-15T08:18:19Z, size = 245282, hashes = { sha256 = "823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506" } }, + { url = "https://files.pythonhosted.org/packages/cc/a4/689bb42e8e7cd492f3cb64907c6bc00ad247ec9a3628cd3f8eed126e8ae1/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_aarch64.whl", upload-time = 2026-08-15T08:18:21Z, size = 244597, hashes = { sha256 = "01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5" } }, + { url = "https://files.pythonhosted.org/packages/c1/ce/9962938e179cf9f699d3f1e7b3114b5d7642dee6a893745229f9dd04f274/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_armv7l.whl", upload-time = 2026-08-15T08:18:22Z, size = 231376, hashes = { sha256 = "329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e" } }, + { url = "https://files.pythonhosted.org/packages/85/54/46000450ada53bd9eac5429a2c8c54cd2d9b39c0c255f229aea9af0948a5/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_ppc64le.whl", upload-time = 2026-08-15T08:18:24Z, size = 266715, hashes = { sha256 = "bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5" } }, + { url = "https://files.pythonhosted.org/packages/3d/bb/618749d70f792b44252a777bf89bfb86823b9bbc1ea13fe8ce759b07f38a/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_riscv64.whl", upload-time = 2026-08-15T08:18:25Z, size = 245848, hashes = { sha256 = "fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3" } }, + { url = "https://files.pythonhosted.org/packages/7e/3f/ffb64458527c7668031d5eb095d978de561958dc9f5b53f8e488a533e603/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_s390x.whl", upload-time = 2026-08-15T08:18:27Z, size = 264521, hashes = { sha256 = "6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3" } }, + { url = "https://files.pythonhosted.org/packages/4f/ab/74a55fd803916a35ac461daf002708191aac19b546b80dc8cabfedc63d98/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_x86_64.whl", upload-time = 2026-08-15T08:18:28Z, size = 253054, hashes = { sha256 = "9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36" } }, + { url = "https://files.pythonhosted.org/packages/a0/2a/6a9034b7d3c60b17499afb482df5878bf9fa20b50cc3887d5ef017a833db/charset_normalizer-3.5.1-cp314-cp314-pyemscripten_2026_0_wasm32.whl", upload-time = 2026-08-15T08:18:30Z, size = 140580, hashes = { sha256 = "f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7" } }, + { url = "https://files.pythonhosted.org/packages/f3/46/1d362e1a00d035d66b9869e1281eee115907f7e390a16a07824ab5737360/charset_normalizer-3.5.1-cp314-cp314-win32.whl", upload-time = 2026-08-15T08:18:31Z, size = 180325, hashes = { sha256 = "1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b" } }, + { url = "https://files.pythonhosted.org/packages/7a/7c/4938c329b6a9d446f6a59aa2092ff7118f274209b5ed0e26893d1d30a63c/charset_normalizer-3.5.1-cp314-cp314-win_amd64.whl", upload-time = 2026-08-15T08:18:33Z, size = 204175, hashes = { sha256 = "c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b" } }, + { url = "https://files.pythonhosted.org/packages/ac/33/eeb384dbd8dec570661354592f4f2e1b2fcc92585624d146a000caf53841/charset_normalizer-3.5.1-cp314-cp314-win_arm64.whl", upload-time = 2026-08-15T08:18:34Z, size = 184123, hashes = { sha256 = "4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687" } }, + { url = "https://files.pythonhosted.org/packages/1c/6c/c73fa9d5a85f6ab05395de61c5f6984e0a9ff40bb5ff888d46dff02526c6/charset_normalizer-3.5.1-cp314-cp314t-macosx_10_15_universal2.whl", upload-time = 2026-08-15T08:18:36Z, size = 381682, hashes = { sha256 = "fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348" } }, + { url = "https://files.pythonhosted.org/packages/30/c7/63565f860921457feba93bae6c86fb7746deb4cffeed2f375cb845318146/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-08-15T08:18:37Z, size = 240826, hashes = { sha256 = "e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef" } }, + { url = "https://files.pythonhosted.org/packages/06/ae/7ae8807410dfa33f8e6f1715740adeaafa8a816cc4cb33508f54b1f7c896/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", upload-time = 2026-08-15T08:18:39Z, size = 227861, hashes = { sha256 = "7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885" } }, + { url = "https://files.pythonhosted.org/packages/e9/a3/887c1642f0da26000b0e0652d91071113c0e72cea33952e225cf589f49a9/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-08-15T08:18:40Z, size = 260758, hashes = { sha256 = "a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375" } }, + { url = "https://files.pythonhosted.org/packages/3e/11/e6f5b9a3d0e55b0ef7505cd3765cdd48f22db89994c947b316f52f801fd8/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-08-15T08:18:42Z, size = 259950, hashes = { sha256 = "256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1" } }, + { url = "https://files.pythonhosted.org/packages/1b/ee/e4e10a94d51cd1ee638aa7e00b65399e6b2a4e8376ab6d2eac9f95586671/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-08-15T08:18:43Z, size = 249329, hashes = { sha256 = "58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65" } }, + { url = "https://files.pythonhosted.org/packages/c4/25/d5f4198819e6059735a84e8d0bfb72dc33976da67b97adcd3fb5a5e07ec6/charset_normalizer-3.5.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-08-15T08:18:45Z, size = 243137, hashes = { sha256 = "0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5" } }, + { url = "https://files.pythonhosted.org/packages/a5/e9/e925ca7569cf9fb9701fd82503fee73eea5268fdb856bdd64947092d3daa/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_aarch64.whl", upload-time = 2026-08-15T08:18:46Z, size = 242820, hashes = { sha256 = "c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af" } }, + { url = "https://files.pythonhosted.org/packages/34/17/672c251a888ed2aebcdd2fe830ad0104e25ff83c43f5c4f9c15e9fc6853c/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_armv7l.whl", upload-time = 2026-08-15T08:18:48Z, size = 230504, hashes = { sha256 = "52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1" } }, + { url = "https://files.pythonhosted.org/packages/3f/fc/f6a85abebd42ce4da2f1db0aa56cc6a0df1995e318b3875d14401b8381d1/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", upload-time = 2026-08-15T08:18:49Z, size = 263087, hashes = { sha256 = "2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9" } }, + { url = "https://files.pythonhosted.org/packages/98/66/7c42677e739ba66746b297e2046918d793078094dc239e1e72768cffccc6/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_riscv64.whl", upload-time = 2026-08-15T08:18:51Z, size = 243269, hashes = { sha256 = "9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a" } }, + { url = "https://files.pythonhosted.org/packages/de/d8/a50b79237f417af10f8c2a501ce8d1ca87829a22e69117891ca4ba20a69e/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_s390x.whl", upload-time = 2026-08-15T08:18:53Z, size = 258766, hashes = { sha256 = "496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032" } }, + { url = "https://files.pythonhosted.org/packages/2e/1d/0fc91aeaeb3c83b748f532399ce67cf84604b48297405d740000f7a9e786/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_x86_64.whl", upload-time = 2026-08-15T08:18:54Z, size = 250814, hashes = { sha256 = "85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e" } }, + { url = "https://files.pythonhosted.org/packages/ae/10/3d8c777cf9024615295aa1b808324ad5b4a77855869c00824bad74ffaf8a/charset_normalizer-3.5.1-cp314-cp314t-win32.whl", upload-time = 2026-08-15T08:18:56Z, size = 191074, hashes = { sha256 = "58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4" } }, + { url = "https://files.pythonhosted.org/packages/4d/81/ae557d3c44d1a1d688696d60563413a0866a91b7ebc50f20df838be3d8c8/charset_normalizer-3.5.1-cp314-cp314t-win_amd64.whl", upload-time = 2026-08-15T08:18:57Z, size = 216476, hashes = { sha256 = "acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00" } }, + { url = "https://files.pythonhosted.org/packages/27/e9/61c01fb8b804692569c036b3fc50495814502dcf13a60649c6055390b02c/charset_normalizer-3.5.1-cp314-cp314t-win_arm64.whl", upload-time = 2026-08-15T08:18:59Z, size = 194115, hashes = { sha256 = "fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f" } }, + { url = "https://files.pythonhosted.org/packages/4a/4e/8544831ef59d8f27ce92c80871380fdacc8076a8a56ed62f82e54f991333/charset_normalizer-3.5.1-cp315-cp315-macosx_10_15_universal2.whl", upload-time = 2026-08-15T08:19:01Z, size = 342048, hashes = { sha256 = "9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af" } }, + { url = "https://files.pythonhosted.org/packages/7f/a6/e3b46852424246065355644f4fb6dbccc0239a42a2eee27ecfc8957f0bcd/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-08-15T08:19:02Z, size = 242997, hashes = { sha256 = "2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8" } }, + { url = "https://files.pythonhosted.org/packages/03/3b/0cc9a26777334ab2f2e3089b948bbf4e4fe72ea70b897715ef6415043ec8/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", upload-time = 2026-08-15T08:19:03Z, size = 237014, hashes = { sha256 = "baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90" } }, + { url = "https://files.pythonhosted.org/packages/8c/c2/027335f0aa337a2a2e121bac1ad88c4f02ba6053ea0926802784f3db11af/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-08-15T08:19:05Z, size = 266174, hashes = { sha256 = "8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20" } }, + { url = "https://files.pythonhosted.org/packages/86/d3/e367787febe4e74769dec0f406f2c3c8d1b955fce5aee1fd0f94e8367a45/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-08-15T08:19:07Z, size = 263361, hashes = { sha256 = "8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449" } }, + { url = "https://files.pythonhosted.org/packages/af/3d/391b193eb9f3e84b02f9314088c386debdc0debee843535aaea2e2c6715d/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-08-15T08:19:08Z, size = 252143, hashes = { sha256 = "5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a" } }, + { url = "https://files.pythonhosted.org/packages/2e/57/de221f1745a90d418199761967e2776bfe2c275a1194220985e8c1d37833/charset_normalizer-3.5.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-08-15T08:19:10Z, size = 252086, hashes = { sha256 = "854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0" } }, + { url = "https://files.pythonhosted.org/packages/c8/e3/d119f86a01f9331e8186175f24873b1d74a7ee9e2e4b4d68f9947dae5afd/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_aarch64.whl", upload-time = 2026-08-15T08:19:11Z, size = 245231, hashes = { sha256 = "21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e" } }, + { url = "https://files.pythonhosted.org/packages/26/de/d8e48c135ae480879539cdb179c8d3b50c7879497d75dd899b5763b69cee/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_armv7l.whl", upload-time = 2026-08-15T08:19:13Z, size = 241546, hashes = { sha256 = "838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2" } }, + { url = "https://files.pythonhosted.org/packages/67/c4/217755fd1abc50d326c252922cd642002758095a81ff45010337b8b3ef65/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_ppc64le.whl", upload-time = 2026-08-15T08:19:14Z, size = 267033, hashes = { sha256 = "195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626" } }, + { url = "https://files.pythonhosted.org/packages/b8/d7/34d8e404e358d2adcc5a228c2134643af00104c8fb0bf525f3688d756f05/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_riscv64.whl", upload-time = 2026-08-15T08:19:16Z, size = 252045, hashes = { sha256 = "978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5" } }, + { url = "https://files.pythonhosted.org/packages/5e/fa/40414471acf0aa0692ca77305aa00e434fcd8288f0941c93c30e9a5f8f2f/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_s390x.whl", upload-time = 2026-08-15T08:19:18Z, size = 264866, hashes = { sha256 = "cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774" } }, + { url = "https://files.pythonhosted.org/packages/32/90/fcc850bae791abd2e0c041847f13e270aa08692a79f3e00de6d2dce1cb50/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_x86_64.whl", upload-time = 2026-08-15T08:19:19Z, size = 253932, hashes = { sha256 = "687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7" } }, + { url = "https://files.pythonhosted.org/packages/af/af/53afe99068b3c10b4cbae592a52ef72a7c92c0188440e83ee3a078fd8f75/charset_normalizer-3.5.1-cp315-cp315-win32.whl", upload-time = 2026-08-15T08:19:21Z, size = 180320, hashes = { sha256 = "706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9" } }, + { url = "https://files.pythonhosted.org/packages/c9/bc/f46a132041b29e4a8779ed712d3df1bf112e94ca8de58b66d7ec2c0cf8b9/charset_normalizer-3.5.1-cp315-cp315-win_amd64.whl", upload-time = 2026-08-15T08:19:23Z, size = 204174, hashes = { sha256 = "92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712" } }, + { url = "https://files.pythonhosted.org/packages/a1/5d/9ed554480eda8e447b673648628fdc29574d23dbad01fe11837adedd1cae/charset_normalizer-3.5.1-cp315-cp315-win_arm64.whl", upload-time = 2026-08-15T08:19:24Z, size = 184126, hashes = { sha256 = "5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7" } }, + { url = "https://files.pythonhosted.org/packages/3b/32/9b8929bf384061ee1fe5d9c27c6f9776d3d824039ad4e14c88ec00c7808e/charset_normalizer-3.5.1-cp315-cp315t-macosx_10_15_universal2.whl", upload-time = 2026-08-15T08:19:26Z, size = 381441, hashes = { sha256 = "59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663" } }, + { url = "https://files.pythonhosted.org/packages/96/10/e9aa7923d3ddac652c99a1c5f7be494e737e151566a44abe018daf757f2c/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-08-15T08:19:27Z, size = 241742, hashes = { sha256 = "9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11" } }, + { url = "https://files.pythonhosted.org/packages/28/53/a2d249ebddf47b889a100c0bdcb61a2f9dbb8bc24ef325cc062e4f476877/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", upload-time = 2026-08-15T08:19:29Z, size = 235298, hashes = { sha256 = "e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc" } }, + { url = "https://files.pythonhosted.org/packages/7d/07/469f78af590f7d5cd48e20d8dbfa3d66deeff9ba37768c04d886b5afd45c/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-08-15T08:19:30Z, size = 262500, hashes = { sha256 = "ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a" } }, + { url = "https://files.pythonhosted.org/packages/55/66/3bb56a47f7dcba014055b1a1d33c6f08bbe9c1e74dba154cfa25f90ae885/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-08-15T08:19:32Z, size = 258888, hashes = { sha256 = "19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4" } }, + { url = "https://files.pythonhosted.org/packages/ff/c1/2adc2800903fb013210349313b710a5376856578d9e33e6b9a1d8b36714a/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", upload-time = 2026-08-15T08:19:33Z, size = 250243, hashes = { sha256 = "cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004" } }, + { url = "https://files.pythonhosted.org/packages/95/b5/a18d0dd1157ab655cc2cb14a545f4a4784bbad70ab3502412e36097502d9/charset_normalizer-3.5.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-08-15T08:19:35Z, size = 249871, hashes = { sha256 = "04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b" } }, + { url = "https://files.pythonhosted.org/packages/ad/c3/525f508cd1e58d0450ac55ed40ac75bc3a97482c59def5278456a5fbf03c/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_aarch64.whl", upload-time = 2026-08-15T08:19:36Z, size = 243580, hashes = { sha256 = "9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263" } }, + { url = "https://files.pythonhosted.org/packages/7c/c1/49a91fe7e97c8140094ca5c64161ab623a70d9f636bf834eace14048acb5/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_armv7l.whl", upload-time = 2026-08-15T08:19:38Z, size = 239807, hashes = { sha256 = "252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee" } }, + { url = "https://files.pythonhosted.org/packages/d3/58/56a48c296601274c4689b864a8e2dfb209b81dfcb39472753ce95eea662b/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", upload-time = 2026-08-15T08:19:39Z, size = 264083, hashes = { sha256 = "6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c" } }, + { url = "https://files.pythonhosted.org/packages/10/4c/dc48409274a1817ff349711d26c62aa0c597df865d4d69ef79160c859193/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_riscv64.whl", upload-time = 2026-08-15T08:19:41Z, size = 250317, hashes = { sha256 = "77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e" } }, + { url = "https://files.pythonhosted.org/packages/81/58/d325912115caec62d6bdd77bbab5e0b7da5d234a9f20affdffcbcb530d0b/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_s390x.whl", upload-time = 2026-08-15T08:19:43Z, size = 258173, hashes = { sha256 = "a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d" } }, + { url = "https://files.pythonhosted.org/packages/34/f7/b13b1ccae2c8ec63980d13be1890eb73f8aeabbfce02a24aabc0908788f5/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_x86_64.whl", upload-time = 2026-08-15T08:19:44Z, size = 251960, hashes = { sha256 = "4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61" } }, + { url = "https://files.pythonhosted.org/packages/1e/25/ed3f9919c5aef8cc818be1f972f565f7610d7b2076b8ebb98839516ffc3c/charset_normalizer-3.5.1-cp315-cp315t-win32.whl", upload-time = 2026-08-15T08:19:46Z, size = 191186, hashes = { sha256 = "ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f" } }, + { url = "https://files.pythonhosted.org/packages/69/d5/43c2b3e9d8267092b913eb8b0603f0f71993c395632886bd37a7223f96cf/charset_normalizer-3.5.1-cp315-cp315t-win_amd64.whl", upload-time = 2026-08-15T08:19:47Z, size = 215947, hashes = { sha256 = "35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb" } }, + { url = "https://files.pythonhosted.org/packages/a8/76/9aad3e9c8865e5e0efa9a7f6f81c37a67635a985145ecd44528a81e088ee/charset_normalizer-3.5.1-cp315-cp315t-win_arm64.whl", upload-time = 2026-08-15T08:19:49Z, size = 193909, hashes = { sha256 = "fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a" } }, + { url = "https://files.pythonhosted.org/packages/5b/97/fb4e82231aba271ffd775a1b4993b0defc4e3059f286ae41d9433409fe85/charset_normalizer-3.5.1-cp37-abi3-macosx_10_9_universal2.whl", upload-time = 2026-08-15T08:19:50Z, size = 331467, hashes = { sha256 = "41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2" } }, + { url = "https://files.pythonhosted.org/packages/9f/2f/fe3f187327aac18e2d54e9d2b08e15d27bf9b642d9e51c219f130fc34d1a/charset_normalizer-3.5.1-cp37-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", upload-time = 2026-08-15T08:19:52Z, size = 253057, hashes = { sha256 = "a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99" } }, + { url = "https://files.pythonhosted.org/packages/d7/c7/9e48cee5c161fe24da823b61bf381921d77cb994a0a4de148e95018c1984/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", upload-time = 2026-08-15T08:19:54Z, size = 240930, hashes = { sha256 = "cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2" } }, + { url = "https://files.pythonhosted.org/packages/49/e0/716601f3cc69be7b198951150c75ead1ece33c3c8036ff6ffa46029659a0/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", upload-time = 2026-08-15T08:19:55Z, size = 230822, hashes = { sha256 = "343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235" } }, + { url = "https://files.pythonhosted.org/packages/d3/05/71bfc5caa0abcc45aea1f6a4d50ac68e59605ddc7666fe8494f4cd229665/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", upload-time = 2026-08-15T08:19:57Z, size = 260037, hashes = { sha256 = "ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598" } }, + { url = "https://files.pythonhosted.org/packages/c3/92/de7e32ed05341e7a9c4c877c318418197b7f2d66a3b68d561bf2ac57ca3e/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", upload-time = 2026-08-15T08:19:59Z, size = 255097, hashes = { sha256 = "4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96" } }, + { url = "https://files.pythonhosted.org/packages/f5/7b/ade0a122600319dfa0b1000ab0f9731c94a817904cf3c5de408c73a4ede7/charset_normalizer-3.5.1-cp37-abi3-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", upload-time = 2026-08-15T08:20:00Z, size = 250166, hashes = { sha256 = "b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962" } }, + { url = "https://files.pythonhosted.org/packages/75/9c/019fbb9f4834491a160951349b1a3714439376f66e5f7cf18b4f18f0c7aa/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_aarch64.whl", upload-time = 2026-08-15T08:20:02Z, size = 241821, hashes = { sha256 = "a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3" } }, + { url = "https://files.pythonhosted.org/packages/2b/b8/11d4840bfc99330cc7fbcc2681ee5a044553a6e77655508d8f9b2bff7b34/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_armv7l.whl", upload-time = 2026-08-15T08:20:04Z, size = 232529, hashes = { sha256 = "36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950" } }, + { url = "https://files.pythonhosted.org/packages/18/96/2b3a21492d9f65171ac75d872f5018260013d00bfa0ff70ec9f179148cbd/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_ppc64le.whl", upload-time = 2026-08-15T08:20:05Z, size = 260348, hashes = { sha256 = "4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8" } }, + { url = "https://files.pythonhosted.org/packages/d6/aa/a69a2028e8bd052476c245460ab19d7de595de084dd968f2d75cd50c3e25/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_riscv64.whl", upload-time = 2026-08-15T08:20:07Z, size = 247234, hashes = { sha256 = "2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031" } }, + { url = "https://files.pythonhosted.org/packages/35/8a/3d130aeabcaf3d2466af76b7b141c08d9e89c9016ab4b7cdd0f7dc2d1c62/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_s390x.whl", upload-time = 2026-08-15T08:20:09Z, size = 256917, hashes = { sha256 = "3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072" } }, + { url = "https://files.pythonhosted.org/packages/80/c2/a7379b840292d0c1ab9fbd17d1f3967aa81794dc95bc74be8999d7fedcf7/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_x86_64.whl", upload-time = 2026-08-15T08:20:10Z, size = 254846, hashes = { sha256 = "e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d" } }, + { url = "https://files.pythonhosted.org/packages/01/65/d43b714731bb2f40d4053dfa00ecfc1c5a301f8e3316c5db3a09af59fe94/charset_normalizer-3.5.1-cp37-abi3-win32.whl", upload-time = 2026-08-15T08:20:12Z, size = 174216, hashes = { sha256 = "dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc" } }, + { url = "https://files.pythonhosted.org/packages/35/4f/b911ed898b26a09789eba9c9200c999aff6c61b4bafaf4838e56d1a1e1a3/charset_normalizer-3.5.1-cp37-abi3-win_amd64.whl", upload-time = 2026-08-15T08:20:13Z, size = 199764, hashes = { sha256 = "70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959" } }, + { url = "https://files.pythonhosted.org/packages/f0/a7/920baf467bfd9bf689f3b318340f37aee4572a71f162bd8db51da55ba4fa/charset_normalizer-3.5.1-cp37-abi3-win_arm64.whl", upload-time = 2026-08-15T08:20:15Z, size = 287318, hashes = { sha256 = "87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e" } }, + { url = "https://files.pythonhosted.org/packages/cc/61/d01fc49b8dea277640b55a9e15960dbca9fdc8c9fde18e572d39c59f4019/charset_normalizer-3.5.1-py3-none-any.whl", upload-time = 2026-08-15T08:20:43Z, size = 68658, hashes = { sha256 = "6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6" } }, ] [[packages]] @@ -103,9 +173,9 @@ wheels = [{ url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929 [[packages]] name = "idna" -version = "3.18" -sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", upload-time = 2026-06-02T14:34:07Z, size = 196711, hashes = { sha256 = "ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", upload-time = 2026-06-02T14:34:06Z, size = 65455, hashes = { sha256 = "7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2" } }] +version = "3.19" +sdist = { url = "https://files.pythonhosted.org/packages/5f/f7/abb373e5757eaec4b922b92f97ec8d6d7e057cf06778247604fbc4e7c3f3/idna-3.19.tar.gz", upload-time = 2026-08-18T05:14:24Z, size = 215237, hashes = { sha256 = "5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/57/b0/0e52c878c53f245edd3a11020f20979b3f490f245af532c7cae3027754b5/idna-3.19-py3-none-any.whl", upload-time = 2026-08-18T05:14:22Z, size = 68550, hashes = { sha256 = "815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4" } }] [[packages]] name = "imagesize" @@ -150,9 +220,9 @@ wheels = [{ url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf [[packages]] name = "python-docs-theme" -version = "2026.7" -sdist = { url = "https://files.pythonhosted.org/packages/54/ba/6de432a297e933eeee26a950298254061d3738b183b0d4c01d512a6a2575/python_docs_theme-2026.7.tar.gz", upload-time = 2026-07-27T20:12:04Z, size = 38838, hashes = { sha256 = "465431be2ebc5239e8f41b0acfae0cf8d842b50ec2fea549f61d9e6a3802432d" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/28/11/4dcaea01fd7bb557159f16b8015906b7a002327704972facac4af706307d/python_docs_theme-2026.7-py3-none-any.whl", upload-time = 2026-07-27T20:12:03Z, size = 47030, hashes = { sha256 = "6099e550bdce042d709db29375228a4fd51bfb238b7fad413782f2b402190c9e" } }] +version = "2026.9" +sdist = { url = "https://files.pythonhosted.org/packages/5a/5e/fee7dbfd6a5ebf27f4a91c8cdf204f35f0744fd1fbde7f50cd479d1d890c/python_docs_theme-2026.9.tar.gz", upload-time = 2026-09-19T08:41:45Z, size = 40572, hashes = { sha256 = "1a400cb5e6ac6c8b4788eb0a98067a8c35e8aea15e38941e90a7f764582702fc" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/68/e1/0d603158c9d9a59cd05dfa98a1682c2fffbc387f1e3a724794480f8acaab/python_docs_theme-2026.9-py3-none-any.whl", upload-time = 2026-09-19T08:41:43Z, size = 49214, hashes = { sha256 = "1a4bdc4f9c664c35a58714af0a98efee4ecb7c3bc4ee0752782c953164ac8fc3" } }] [[packages]] name = "requests" @@ -186,9 +256,9 @@ wheels = [{ url = "https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc [[packages]] name = "sphinx-linklint" -version = "2.0.0" -sdist = { url = "https://files.pythonhosted.org/packages/f6/99/f9947b30fd11e782855a13de1aac7d08634edba1c193a0ee01bf5338531c/sphinx_linklint-2.0.0.tar.gz", upload-time = 2026-08-25T12:47:33Z, size = 23297, hashes = { sha256 = "e7ea4d3b1bd83665e9c2ab9fd92c6c645c805956d2e8ca6b0f528f3a9638910d" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/d7/3d/6b96af48e139357e1e041a710d943c4bb79ad149c7aab074df784b4395ec/sphinx_linklint-2.0.0-py3-none-any.whl", upload-time = 2026-08-25T12:47:32Z, size = 13390, hashes = { sha256 = "12aa64f3b3faaa6e8a979a7d1f2c38617866652b670e3d19fa0f60a6ce3657ef" } }] +version = "2.0.1" +sdist = { url = "https://files.pythonhosted.org/packages/96/25/f5dc4e284565e931bba2fc730df1d20cb465961ac471c01575c2de830265/sphinx_linklint-2.0.1.tar.gz", upload-time = 2026-08-26T12:06:49Z, size = 40515, hashes = { sha256 = "b0079a667282537529a8b10e1e0477c4af3486a4aa3f309fe0457d200ac69472" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/7f/83/4b78c062448ee95bdbb27bac0c4cc89319e4ae318214044cb46b29a36ad2/sphinx_linklint-2.0.1-py3-none-any.whl", upload-time = 2026-08-26T12:06:47Z, size = 13277, hashes = { sha256 = "c2b58122ea38d8c1d5d5a67d525cf290be8d3f30424fb45cc1049d32ad0fc096" } }] [[packages]] name = "sphinx-notfound-page" From 4d3b405df82ab7b92348c242e026b4093ac211a5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 19 Sep 2026 15:56:08 +0200 Subject: [PATCH 03/11] gh-156939: Document that PyUnicodeObject ends with null character (#157708) Document also that PyUnicode_READ() and PyUnicode_READ_CHAR() accept reading the trailing null character, and that PyUnicode_GetLength() doesn't count the trailing null character. --- Doc/c-api/unicode.rst | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 8ac4e137709555..3b635fa7fa3744 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -16,6 +16,13 @@ points must be below 1114112 (which is the full Unicode range). UTF-8 representation is created on demand and cached in the Unicode object. +.. impl-detail:: + + The internal buffer always includes an extra trailing null character for + compatibility with null terminated C strings. This extra character is not + counted in :c:func:`PyUnicode_GetLength` nor in the various *size* arguments + of the functions below. + .. note:: The :c:type:`Py_UNICODE` representation has been removed since Python 3.12 with deprecated APIs. @@ -164,11 +171,15 @@ access to internal read-only data of Unicode objects: .. versionadded:: 3.3 -.. c:function:: Py_UCS4 PyUnicode_READ(int kind, void *data, \ - Py_ssize_t index) +.. c:function:: Py_UCS4 PyUnicode_READ(int kind, void *data, Py_ssize_t index) Read a code point from a canonical representation *data* (as obtained with - :c:func:`PyUnicode_DATA`). No checks or ready calls are performed. + :c:func:`PyUnicode_DATA`). No checks are performed. + + .. impl-detail:: + + Accept reading the trailing null character at index + :c:func:`PyUnicode_GetLength`. .. versionadded:: 3.3 @@ -179,6 +190,11 @@ access to internal read-only data of Unicode objects: representation. This is less efficient than :c:func:`PyUnicode_READ` if you do multiple consecutive reads. + .. impl-detail:: + + Accept reading the trailing null character at index + :c:func:`PyUnicode_GetLength`. + .. versionadded:: 3.3 @@ -716,6 +732,10 @@ APIs: On error, set an exception and return ``-1``. + .. impl-detail:: + + The length does not count the trailing null character. + .. versionadded:: 3.3 @@ -794,6 +814,11 @@ APIs: Return character on success, ``-1`` on error with an exception set. + .. impl-detail:: + + Do not accept reading the trailing null character at index + :c:func:`PyUnicode_GetLength`. + .. versionadded:: 3.3 From c81693b92699cdc553ba63337609b4bc7f81d224 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Sat, 19 Sep 2026 11:01:01 -0400 Subject: [PATCH 04/11] gh-157763: Soft-deprecate `ctypes.util.test` (GH-157776) --- Lib/ctypes/util.py | 57 ++----------------- ...-09-18-17-33-31.gh-issue-157763.Wd0_Uo.rst | 2 + 2 files changed, 7 insertions(+), 52 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-09-18-17-33-31.gh-issue-157763.Wd0_Uo.rst diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 2b01506f3d4ffa..f4fb05c29b4ca4 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -416,7 +416,7 @@ def find_library(name): # On platforms which provide dl_iterate_phdr(), dllist() is implemented # in _ctypes. try: - from _ctypes import dllist + from _ctypes import dllist as dllist except ImportError: pass @@ -525,55 +525,8 @@ def decorator(func): return decorator -################################################################ -# test code - def test(): - from ctypes import cdll - if os.name == "nt": - print(cdll.msvcrt) - print(cdll.load("msvcrt")) - print(find_library("msvcrt")) - - if os.name == "posix": - # find and load_version - print(find_library("m")) - print(find_library("c")) - print(find_library("bz2")) - - # load - if sys.platform == "darwin": - print(cdll.LoadLibrary("libm.dylib")) - print(cdll.LoadLibrary("libcrypto.dylib")) - print(cdll.LoadLibrary("libSystem.dylib")) - print(cdll.LoadLibrary("System.framework/System")) - # issue-26439 - fix broken test call for AIX - elif sys.platform.startswith("aix"): - from ctypes import CDLL - if sys.maxsize < 2**32: - print(f"Using CDLL(name, os.RTLD_MEMBER): {CDLL('libc.a(shr.o)', os.RTLD_MEMBER)}") - print(f"Using cdll.LoadLibrary(): {cdll.LoadLibrary('libc.a(shr.o)')}") - # librpm.so is only available as 32-bit shared library - print(find_library("rpm")) - print(cdll.LoadLibrary("librpm.so")) - else: - print(f"Using CDLL(name, os.RTLD_MEMBER): {CDLL('libc.a(shr_64.o)', os.RTLD_MEMBER)}") - print(f"Using cdll.LoadLibrary(): {cdll.LoadLibrary('libc.a(shr_64.o)')}") - print(f"crypt\t:: {find_library('crypt')}") - print(f"crypt\t:: {cdll.LoadLibrary(find_library('crypt'))}") - print(f"crypto\t:: {find_library('crypto')}") - print(f"crypto\t:: {cdll.LoadLibrary(find_library('crypto'))}") - else: - print(cdll.LoadLibrary("libm.so")) - print(cdll.LoadLibrary("libcrypt.so")) - print(find_library("crypt")) - - try: - dllist - except NameError: - print('dllist() not available') - else: - print(dllist()) - -if __name__ == "__main__": - test() + """ + This function is a no-op and is soft-deprecated since Python 3.16. + Do not use. + """ diff --git a/Misc/NEWS.d/next/Library/2026-09-18-17-33-31.gh-issue-157763.Wd0_Uo.rst b/Misc/NEWS.d/next/Library/2026-09-18-17-33-31.gh-issue-157763.Wd0_Uo.rst new file mode 100644 index 00000000000000..712fe6310579b1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-09-18-17-33-31.gh-issue-157763.Wd0_Uo.rst @@ -0,0 +1,2 @@ +The undocumented :func:`!ctypes.util.test` function is now :term:`soft +deprecated` and a no-op at runtime. From da72cc70ca00f9677d219631ec397d5f47c926df Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 19 Sep 2026 18:06:36 +0300 Subject: [PATCH 05/11] gh-157487: Add structured version info for ctypes (GH-157488) Add constants ctypes.LIBFFI_VERSION, ctypes.libffi_version, ctypes.LIBFFI_VERSION_INFO and ctypes.libffi_version_info, which provide information about the version of the libffi library in use. They are only available with libffi 3.5 or later. Co-authored-by: Claude Opus 5 (1M context) --- Doc/library/ctypes.rst | 44 ++++++++++ Doc/whatsnew/3.16.rst | 7 ++ Lib/ctypes/__init__.py | 6 ++ Lib/test/pythoninfo.py | 11 +++ Lib/test/test_ctypes/test_values.py | 34 +++++++ ...-09-14-12-05-02.gh-issue-157487.ID-qIv.rst | 4 + Modules/_ctypes/_ctypes.c | 88 +++++++++++++++++++ 7 files changed, 194 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-09-14-12-05-02.gh-issue-157487.ID-qIv.rst diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 169459881328ab..8946ee7a02da48 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -3383,3 +3383,47 @@ Exceptions .. availability:: Windows .. versionadded:: 3.14 + + +Library version +^^^^^^^^^^^^^^^ + +The following constants are only available if :mod:`!ctypes` was built with +libffi 3.5 or later, which is the first version providing this information. + +.. data:: LIBFFI_VERSION + + The version string of the libffi library that was used for building + the module, like ``'3.5.2'``. + This may be different from the libffi library actually used at runtime, + which is available as :const:`libffi_version`. + + .. versionadded:: next + +.. data:: libffi_version + + The version string of the libffi library actually loaded by the interpreter. + + .. versionadded:: next + +.. data:: LIBFFI_VERSION_INFO + + A named tuple containing the three components of the libffi library + version that was used for building the module: + *major*, *minor*, and *patch*. + All values are integers. + The components can also be accessed by name, + so ``ctypes.LIBFFI_VERSION_INFO[0]`` is equivalent to + ``ctypes.LIBFFI_VERSION_INFO.major`` and so on. + This may be different from the libffi library actually used at runtime, + which is available as :const:`libffi_version_info`. + + .. versionadded:: next + +.. data:: libffi_version_info + + A named tuple containing the version of the libffi library + actually loaded by the interpreter, + with the same fields as :const:`LIBFFI_VERSION_INFO`. + + .. versionadded:: next diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index d24fed49d1f95e..7e02924babe952 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -184,6 +184,13 @@ ctypes through a function signature. (Contributed by Peter Bierma in :gh:`153903`.) +* Added constants :const:`~ctypes.LIBFFI_VERSION`, + :const:`~ctypes.libffi_version`, :const:`~ctypes.LIBFFI_VERSION_INFO` + and :const:`~ctypes.libffi_version_info`, which provide information + about the version of the libffi library in use. + They are only available with libffi 3.5 or later. + (Contributed by Serhiy Storchaka in :gh:`157487`.) + curses ------ diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index 890168cc9809fd..2e6893e3b8e513 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -12,6 +12,12 @@ from _ctypes import RTLD_LOCAL, RTLD_GLOBAL from _ctypes import ArgumentError from _ctypes import SIZEOF_TIME_T +try: + from _ctypes import (LIBFFI_VERSION, libffi_version, + LIBFFI_VERSION_INFO, libffi_version_info) +except ImportError: + # libffi < 3.5 does not provide version information. + pass from _ctypes import CField from struct import calcsize as _calcsize diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index b59e2acb9376f1..a6099cda28f07c 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -745,6 +745,16 @@ def collect_zstd(info_add): copy_attributes(info_add, _zstd, 'zstd.%s', attributes) +def collect_ctypes(info_add): + try: + import _ctypes + except ImportError: + return + + attributes = ('LIBFFI_VERSION', 'libffi_version') + copy_attributes(info_add, _ctypes, 'ctypes.%s', attributes) + + def collect_expat(info_add): try: from xml.parsers import expat @@ -1353,6 +1363,7 @@ def collect_info(info): collect_curses, collect_datetime, collect_decimal, + collect_ctypes, collect_expat, collect_fips, collect_gdb, diff --git a/Lib/test/test_ctypes/test_values.py b/Lib/test/test_ctypes/test_values.py index 8d1ee25ace5479..82c928c9f6406c 100644 --- a/Lib/test/test_ctypes/test_values.py +++ b/Lib/test/test_ctypes/test_values.py @@ -3,14 +3,48 @@ """ import _imp +import ctypes import importlib.util import sys import unittest from ctypes import (Structure, CDLL, POINTER, pythonapi, c_ubyte, c_char_p, c_int) +from test import support from test.support import import_helper, thread_unsafe +class LibffiVersionTest(unittest.TestCase): + + def _test_libffi_version(self, v, string): + self.assertIsInstance(v[:], tuple) + self.assertEqual(len(v), 3) + self.assertIsInstance(v[0], int) + self.assertIsInstance(v[1], int) + self.assertIsInstance(v[2], int) + self.assertIsInstance(v.major, int) + self.assertIsInstance(v.minor, int) + self.assertIsInstance(v.patch, int) + self.assertEqual(v[0], v.major) + self.assertEqual(v[1], v.minor) + self.assertEqual(v[2], v.patch) + self.assertGreaterEqual(v.major, 3) + self.assertGreaterEqual(v.minor, 0) + self.assertGreaterEqual(v.patch, 0) + self.assertEqual(string, '%d.%d.%d' % v) + + @unittest.skipUnless(hasattr(ctypes, 'LIBFFI_VERSION_INFO'), + 'requires libffi >= 3.5') + def test_libffi_version(self): + if support.verbose: + print(f'LIBFFI_VERSION = {ctypes.LIBFFI_VERSION}', flush=True) + print(f'libffi_version = {ctypes.libffi_version}', flush=True) + print(f'LIBFFI_VERSION_INFO = {ctypes.LIBFFI_VERSION_INFO}', flush=True) + print(f'libffi_version_info = {ctypes.libffi_version_info}', flush=True) + self._test_libffi_version(ctypes.LIBFFI_VERSION_INFO, ctypes.LIBFFI_VERSION) + self._test_libffi_version(ctypes.libffi_version_info, ctypes.libffi_version) + self.assertEqual(ctypes.LIBFFI_VERSION_INFO[0], ctypes.libffi_version_info[0]) + + class ValuesTestCase(unittest.TestCase): def setUp(self): diff --git a/Misc/NEWS.d/next/Library/2026-09-14-12-05-02.gh-issue-157487.ID-qIv.rst b/Misc/NEWS.d/next/Library/2026-09-14-12-05-02.gh-issue-157487.ID-qIv.rst new file mode 100644 index 00000000000000..95aa332ca90859 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-09-14-12-05-02.gh-issue-157487.ID-qIv.rst @@ -0,0 +1,4 @@ +Add constants :const:`ctypes.LIBFFI_VERSION`, :const:`ctypes.libffi_version`, +:const:`ctypes.LIBFFI_VERSION_INFO` and :const:`ctypes.libffi_version_info`, +which provide information about the version of the libffi library in use. +They are only available with libffi 3.5 or later. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 3882b9a5ddff3c..97f33b1be8561f 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -6386,6 +6386,89 @@ _ctypes_add_objects(PyObject *mod) } +#ifdef FFI_VERSION_NUMBER +PyDoc_STRVAR(libffi_version_info__doc__, +"ctypes.libffi_version_info\n\ +\n\ +libffi version information as a named tuple."); + +static PyStructSequence_Field libffi_version_info_fields[] = { + {"major", "Major release number"}, + {"minor", "Minor release number"}, + {"patch", "Patch release number"}, + {0} +}; + +static PyStructSequence_Desc libffi_version_info_desc = { + "ctypes.libffi_version_info", /* name */ + libffi_version_info__doc__, /* doc */ + libffi_version_info_fields, /* fields */ + 3 +}; + +static PyObject * +make_libffi_version_info(PyTypeObject *type, unsigned long number) +{ + PyObject *version; + int pos = 0; + unsigned long major = number / 10000; + unsigned long minor = (number % 10000) / 100; + unsigned long patch = number % 100; + + version = PyStructSequence_New(type); + if (version == NULL) { + return NULL; + } + +#define SetItem(VALUE) \ + PyStructSequence_SET_ITEM(version, pos++, VALUE); \ + if (PyErr_Occurred()) { \ + Py_DECREF(version); \ + return NULL; \ + } + + SetItem(PyLong_FromUnsignedLong(major)) + SetItem(PyLong_FromUnsignedLong(minor)) + SetItem(PyLong_FromUnsignedLong(patch)) +#undef SetItem + + return version; +} + +static int +_ctypes_add_version_constants(PyObject *mod) +{ + if (PyModule_AddStringConstant(mod, "LIBFFI_VERSION", + FFI_VERSION_STRING) < 0) { + return -1; + } + if (PyModule_AddStringConstant(mod, "libffi_version", + ffi_get_version()) < 0) { + return -1; + } + PyTypeObject *version_type; + version_type = PyStructSequence_NewType(&libffi_version_info_desc); + if (version_type == NULL) { + return -1; + } + if (PyModule_Add(mod, "LIBFFI_VERSION_INFO", + make_libffi_version_info(version_type, FFI_VERSION_NUMBER)) < 0) + { + Py_DECREF(version_type); + return -1; + } + if (PyModule_Add(mod, "libffi_version_info", + make_libffi_version_info(version_type, + ffi_get_version_number())) < 0) + { + Py_DECREF(version_type); + return -1; + } + Py_DECREF(version_type); + return 0; +} +#endif + static int _ctypes_mod_exec(PyObject *mod) { @@ -6440,6 +6523,11 @@ _ctypes_mod_exec(PyObject *mod) if (_ctypes_add_objects(mod) < 0) { return -1; } +#ifdef FFI_VERSION_NUMBER + if (_ctypes_add_version_constants(mod) < 0) { + return -1; + } +#endif return 0; } From 5bbf4fad6d539f84659671ecc52ee13916d5a703 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Sat, 19 Sep 2026 16:23:54 +0100 Subject: [PATCH 06/11] gh-95779: Refuse to run `make doctest` under a mismatched Python (#156203) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- Doc/conf.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Doc/conf.py b/Doc/conf.py index 084906ac17cf94..1666f7b3b435cd 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -636,3 +636,40 @@ "library/threadsafety.rst": "builtins/threadsafety.rst", "library/time-complexity.rst": "builtins/time-complexity.rst", } + +# Refuse to run the doctest builder under a mismatched Python +# ----------------------------------------------------------- + + +def _check_doctest_interpreter(app): + # The doctests are executed by the interpreter running Sphinx, + # so refuse to run them if its version doesn't match the source tree. + if app.builder.name != "doctest": + return + + running_version = f"{sys.version_info.major}.{sys.version_info.minor}" + if running_version != version: + from sphinx.util import logging as sphinx_logging + + logger = sphinx_logging.getLogger(__name__) + logger.error( + "The doctests are executed by the Python running Sphinx, " + "which is Python %s, however this source tree is Python %s, " + "so they would test Python %s rather than the code " + "documented here.\n" + "Recreate the venv with a matching interpreter, for example: " + "'make clean-venv && make venv PYTHON=../python'.", + running_version, + version, + running_version, + ) + raise SystemExit(1) + + +def setup(app): + app.connect("builder-inited", _check_doctest_interpreter) + return { + "version": "1.0", + "parallel_read_safe": True, + "parallel_write_safe": True, + } From e8ac9c4369b383d38806245bf5789689af1e19cd Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 19 Sep 2026 18:43:24 +0300 Subject: [PATCH 07/11] gh-135683: Honor raiseExceptions when opening the file fails in FileHandler (GH-154542) FileHandler and WatchedFileHandler opened the file outside the try block that reports errors via handleError(), so an error while opening the file was raised instead of being handled, ignoring raiseExceptions. Co-authored-by: Vinay Sajip Co-authored-by: Claude Opus 4.8 (1M context) --- Lib/logging/__init__.py | 7 +++- Lib/logging/handlers.py | 9 ++++- Lib/test/test_logging.py | 40 +++++++++++++++++++ ...-07-23-14-13-39.gh-issue-135683.droBu7.rst | 3 ++ 4 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-07-23-14-13-39.gh-issue-135683.droBu7.rst diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 53becca4e3a696..549a6b3c457b2c 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -1263,7 +1263,12 @@ def emit(self, record): """ if self.stream is None: if self.mode != 'w' or not self._closed: - self.stream = self._open() + # Report an error while opening the file, like emit errors. + try: + self.stream = self._open() + except Exception: + self.handleError(record) + return if self.stream: StreamHandler.emit(self, record) diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index fb6b5f3b411b22..e225a21da408fa 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -563,8 +563,13 @@ def emit(self, record): If underlying file has changed, reopen the file before emitting the record to it. """ - self.reopenIfNeeded() - logging.FileHandler.emit(self, record) + # Report an error while reopening the file, like emit errors. + try: + self.reopenIfNeeded() + except Exception: + self.handleError(record) + else: + logging.FileHandler.emit(self, record) class SocketHandler(logging.Handler): diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 7cd0df3ea0b62d..b1852ee43b594f 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -6503,6 +6503,46 @@ def test_emit_after_closing_in_write_mode(self): with open(self.fn) as fp: self.assertEqual(fp.read().strip(), '1') + def _check_open_error(self, h): + # gh-135683: an error while opening the file in emit() respects + # raiseExceptions, like an error during the actual write. + r = logging.makeLogRecord({}) + old_raise = logging.raiseExceptions + self.addCleanup(setattr, logging, 'raiseExceptions', old_raise) + + logging.raiseExceptions = True + with support.captured_stderr() as stderr: + h.handle(r) + self.assertIn('\nFileNotFoundError:', stderr.getvalue()) + + logging.raiseExceptions = False + with support.captured_stderr() as stderr: + h.handle(r) + self.assertEqual('', stderr.getvalue()) + + def test_emit_open_error(self): + # FileHandler with delay: the failing open happens in emit(). + d = tempfile.mkdtemp() + self.addCleanup(os_helper.rmtree, d) + h = logging.FileHandler(os.path.join(d, 'missing', 'a.log'), + encoding='utf-8', delay=True) + self.addCleanup(h.close) + self._check_open_error(h) + + @unittest.skipIf(os.name == 'nt', + 'WatchedFileHandler not appropriate for Windows.') + def test_emit_reopen_error(self): + # WatchedFileHandler: reopenIfNeeded() fails after the dir is removed. + d = tempfile.mkdtemp() + self.addCleanup(os_helper.rmtree, d) + subdir = os.path.join(d, 'sub') + os.mkdir(subdir) + h = logging.handlers.WatchedFileHandler( + os.path.join(subdir, 'b.log'), encoding='utf-8') + self.addCleanup(h.close) + os_helper.rmtree(subdir) + self._check_open_error(h) + class RotatingFileHandlerTest(BaseFileTest): def test_should_not_rollover(self): # If file is empty rollover never occurs diff --git a/Misc/NEWS.d/next/Library/2026-07-23-14-13-39.gh-issue-135683.droBu7.rst b/Misc/NEWS.d/next/Library/2026-07-23-14-13-39.gh-issue-135683.droBu7.rst new file mode 100644 index 00000000000000..532ae22d017a56 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-23-14-13-39.gh-issue-135683.droBu7.rst @@ -0,0 +1,3 @@ +:class:`logging.FileHandler` and :class:`logging.handlers.WatchedFileHandler` +now honor :data:`logging.raiseExceptions` for errors that occur while opening +the file, like for other errors during logging. From 6b5d4143f3c68ceebcce846d229bd4958545226b Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 19 Sep 2026 18:48:39 +0300 Subject: [PATCH 08/11] gh-113318: Better implementation of @getter and @setter in Argument Clinic (GH-156066) The value of a @setter is now a parameter, which can use a converter, and a @getter can define a return converter. Declaring the value is optional. The accessors of an attribute are now collected in a Property, so the entry of PyGetSetDef is identified by the Python name instead of the C basename, and is composed without the help of the preprocessor unless some accessor is compiled conditionally. --- Lib/test/clinic.test.c | 208 +++--- Lib/test/test_clinic.py | 348 +++++++-- Lib/test/test_ctypes/test_delattr.py | 4 +- Lib/test/test_exceptions.py | 12 +- Lib/test/test_funcattrs.py | 2 +- Lib/test/test_raise.py | 2 +- ...-08-14-13-15-35.gh-issue-113318.oHjvUR.rst | 7 + Modules/_asynciomodule.c | 80 +-- Modules/_ctypes/_ctypes.c | 68 +- Modules/_ctypes/clinic/_ctypes.c.h | 252 +++---- Modules/_io/clinic/bufferedio.c.h | 38 +- Modules/_io/clinic/stringio.c.h | 38 +- Modules/_io/clinic/textio.c.h | 140 +--- Modules/_sqlite/clinic/cursor.c.h | 37 +- Modules/_sqlite/cursor.c | 11 +- Modules/_ssl.c | 103 ++- Modules/_zstd/clinic/decompressor.c.h | 18 +- Modules/_zstd/clinic/zstddict.c.h | 66 +- Modules/clinic/_asynciomodule.c.h | 291 +++----- Modules/clinic/_ssl.c.h | 675 ++++++------------ Modules/clinic/hmacmodule.c.h | 38 +- Objects/clinic/exceptions.c.h | 146 ++-- Objects/clinic/frameobject.c.h | 212 +----- Objects/clinic/funcobject.c.h | 121 ++-- Objects/exceptions.c | 30 +- Objects/frameobject.c | 20 +- Objects/funcobject.c | 19 +- Python/clinic/traceback.c.h | 38 +- Python/traceback.c | 8 +- Tools/clinic/libclinic/app.py | 8 +- Tools/clinic/libclinic/clanguage.py | 76 +- Tools/clinic/libclinic/converter.py | 12 +- Tools/clinic/libclinic/dsl_parser.py | 90 ++- Tools/clinic/libclinic/function.py | 45 ++ Tools/clinic/libclinic/language.py | 3 + Tools/clinic/libclinic/parse_args.py | 176 +++-- 36 files changed, 1431 insertions(+), 2011 deletions(-) create mode 100644 Misc/NEWS.d/next/Tools-Demos/2026-08-14-13-15-35.gh-issue-113318.oHjvUR.rst diff --git a/Lib/test/clinic.test.c b/Lib/test/clinic.test.c index cd7a4b0396d08f..fa71df7f4f9d0e 100644 --- a/Lib/test/clinic.test.c +++ b/Lib/test/clinic.test.c @@ -5381,133 +5381,164 @@ Test_meth_coexist_impl(TestObj *self) /*[clinic end generated code: output=7edf4e95b29f06fa input=2a1d75b5e6fec6dd]*/ /*[clinic input] -@getter -Test.property +@setter +@deleter +Test.settable [clinic start generated code]*/ -#if !defined(Test_property_DOCSTR) -# define Test_property_DOCSTR NULL -#endif -#if defined(TEST_PROPERTY_GETSETDEF) -# undef TEST_PROPERTY_GETSETDEF -# define TEST_PROPERTY_GETSETDEF {"property", (getter)Test_property_get, (setter)Test_property_set, Test_property_DOCSTR}, -#else -# define TEST_PROPERTY_GETSETDEF {"property", (getter)Test_property_get, NULL, Test_property_DOCSTR}, -#endif +static int +Test_settable_set_impl(TestObj *self, PyObject *value); -static PyObject * -Test_property_get_impl(TestObj *self); +static int +Test_settable_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) +{ + int return_value = -1; + PyObject *value = NULL; + + if (arg != NULL) { + value = arg; + } + return_value = Test_settable_set_impl((TestObj *)self, value); + + return return_value; +} + +static int +Test_settable_set_impl(TestObj *self, PyObject *value) +/*[clinic end generated code: output=46832806d93e5391 input=c5e1780ba116abdc]*/ + +/*[clinic input] +@getter +Test.int_property -> int +[clinic start generated code]*/ + +static int +Test_int_property_get_impl(TestObj *self); static PyObject * -Test_property_get(PyObject *self, void *Py_UNUSED(context)) +Test_int_property_get(PyObject *self, void *Py_UNUSED(context)) { - return Test_property_get_impl((TestObj *)self); + PyObject *return_value = NULL; + int _return_value; + + _return_value = Test_int_property_get_impl((TestObj *)self); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; } -static PyObject * -Test_property_get_impl(TestObj *self) -/*[clinic end generated code: output=b38d68abd3466a6e input=2d92b3449fbc7d2b]*/ +static int +Test_int_property_get_impl(TestObj *self) +/*[clinic end generated code: output=0d0b1028eefad645 input=d9617980a2010b06]*/ /*[clinic input] @setter -Test.property +Test.int_property + value: int [clinic start generated code]*/ -#if !defined(Test_property_DOCSTR) -# define Test_property_DOCSTR NULL -#endif -#if defined(TEST_PROPERTY_GETSETDEF) -# undef TEST_PROPERTY_GETSETDEF -# define TEST_PROPERTY_GETSETDEF {"property", (getter)Test_property_get, (setter)Test_property_set, Test_property_DOCSTR}, -#else -# define TEST_PROPERTY_GETSETDEF {"property", NULL, (setter)Test_property_set, NULL}, -#endif - static int -Test_property_set_impl(TestObj *self, PyObject *value); +Test_int_property_set_impl(TestObj *self, int value); static int -Test_property_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +Test_int_property_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + int value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, - "attribute 'property' of '%.100s' objects cannot be deleted", + "attribute 'int_property' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } - return_value = Test_property_set_impl((TestObj *)self, value); + value = PyLong_AsInt(arg); + if (value == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = Test_int_property_set_impl((TestObj *)self, value); +exit: return return_value; } static int -Test_property_set_impl(TestObj *self, PyObject *value) -/*[clinic end generated code: output=ec103a151cf51d25 input=3bc3f46a23c83a88]*/ +Test_int_property_set_impl(TestObj *self, int value) +/*[clinic end generated code: output=75d998b3c5aabb83 input=3830ff9462d00c65]*/ /*[clinic input] -@setter -@deleter -Test.settable_and_deletable +@getter +Test.property [clinic start generated code]*/ -#if !defined(Test_settable_and_deletable_DOCSTR) -# define Test_settable_and_deletable_DOCSTR NULL -#endif -#if defined(TEST_SETTABLE_AND_DELETABLE_GETSETDEF) -# undef TEST_SETTABLE_AND_DELETABLE_GETSETDEF -# define TEST_SETTABLE_AND_DELETABLE_GETSETDEF {"settable_and_deletable", (getter)Test_settable_and_deletable_get, (setter)Test_settable_and_deletable_set, Test_settable_and_deletable_DOCSTR}, -#else -# define TEST_SETTABLE_AND_DELETABLE_GETSETDEF {"settable_and_deletable", NULL, (setter)Test_settable_and_deletable_set, NULL}, -#endif +static PyObject * +Test_property_get_impl(TestObj *self); + +static PyObject * +Test_property_get(PyObject *self, void *Py_UNUSED(context)) +{ + return Test_property_get_impl((TestObj *)self); +} + +static PyObject * +Test_property_get_impl(TestObj *self) +/*[clinic end generated code: output=2b6f95ae685a9efc input=2d92b3449fbc7d2b]*/ + +/*[clinic input] +@setter +Test.property +[clinic start generated code]*/ static int -Test_settable_and_deletable_set_impl(TestObj *self, PyObject *value); +Test_property_set_impl(TestObj *self, PyObject *value); static int -Test_settable_and_deletable_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +Test_property_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; - return_value = Test_settable_and_deletable_set_impl((TestObj *)self, value); + if (arg == NULL) { + PyErr_Format(PyExc_AttributeError, + "attribute 'property' of '%.100s' objects cannot be deleted", + Py_TYPE(self)->tp_name); + return -1; + } + value = arg; + return_value = Test_property_set_impl((TestObj *)self, value); return return_value; } static int -Test_settable_and_deletable_set_impl(TestObj *self, PyObject *value) -/*[clinic end generated code: output=479986d499b2f56d input=f5647f3511b9daea]*/ +Test_property_set_impl(TestObj *self, PyObject *value) +/*[clinic end generated code: output=b54a80ff88efca4c input=3bc3f46a23c83a88]*/ /*[clinic input] @setter Test.setter_first_with_docstr [clinic start generated code]*/ -#if !defined(Test_setter_first_with_docstr_DOCSTR) -# define Test_setter_first_with_docstr_DOCSTR NULL -#endif -#if defined(TEST_SETTER_FIRST_WITH_DOCSTR_GETSETDEF) -# undef TEST_SETTER_FIRST_WITH_DOCSTR_GETSETDEF -# define TEST_SETTER_FIRST_WITH_DOCSTR_GETSETDEF {"setter_first_with_docstr", (getter)Test_setter_first_with_docstr_get, (setter)Test_setter_first_with_docstr_set, Test_setter_first_with_docstr_DOCSTR}, -#else -# define TEST_SETTER_FIRST_WITH_DOCSTR_GETSETDEF {"setter_first_with_docstr", NULL, (setter)Test_setter_first_with_docstr_set, NULL}, -#endif - static int Test_setter_first_with_docstr_set_impl(TestObj *self, PyObject *value); static int -Test_setter_first_with_docstr_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +Test_setter_first_with_docstr_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'setter_first_with_docstr' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = arg; return_value = Test_setter_first_with_docstr_set_impl((TestObj *)self, value); return return_value; @@ -5515,7 +5546,7 @@ Test_setter_first_with_docstr_set(PyObject *self, PyObject *value, void *Py_UNUS static int Test_setter_first_with_docstr_set_impl(TestObj *self, PyObject *value) -/*[clinic end generated code: output=eac8bafcaa50aa51 input=31a045ce11bbe961]*/ +/*[clinic end generated code: output=fdd579cfe3b261e4 input=31a045ce11bbe961]*/ /*[clinic input] @getter @@ -5526,20 +5557,6 @@ my silly docstring PyDoc_STRVAR(Test_setter_first_with_docstr__doc__, "my silly docstring"); -#if defined(Test_setter_first_with_docstr_DOCSTR) -# undef Test_setter_first_with_docstr_DOCSTR -#endif -#define Test_setter_first_with_docstr_DOCSTR Test_setter_first_with_docstr__doc__ - -#if !defined(Test_setter_first_with_docstr_DOCSTR) -# define Test_setter_first_with_docstr_DOCSTR NULL -#endif -#if defined(TEST_SETTER_FIRST_WITH_DOCSTR_GETSETDEF) -# undef TEST_SETTER_FIRST_WITH_DOCSTR_GETSETDEF -# define TEST_SETTER_FIRST_WITH_DOCSTR_GETSETDEF {"setter_first_with_docstr", (getter)Test_setter_first_with_docstr_get, (setter)Test_setter_first_with_docstr_set, Test_setter_first_with_docstr_DOCSTR}, -#else -# define TEST_SETTER_FIRST_WITH_DOCSTR_GETSETDEF {"setter_first_with_docstr", (getter)Test_setter_first_with_docstr_get, NULL, Test_setter_first_with_docstr_DOCSTR}, -#endif static PyObject * Test_setter_first_with_docstr_get_impl(TestObj *self); @@ -5552,7 +5569,20 @@ Test_setter_first_with_docstr_get(PyObject *self, void *Py_UNUSED(context)) static PyObject * Test_setter_first_with_docstr_get_impl(TestObj *self) -/*[clinic end generated code: output=fe6e3aa844a24920 input=10af4e43b3cb34dc]*/ +/*[clinic end generated code: output=e93e3e68b0473d74 input=10af4e43b3cb34dc]*/ + +/*[clinic input] +dump buffer +[clinic start generated code]*/ +#define TEST_SETTABLE_GETSETDEF {"settable", (getter)NULL, (setter)Test_settable_set, NULL}, + +#define TEST_INT_PROPERTY_GETSETDEF {"int_property", (getter)Test_int_property_get, (setter)Test_int_property_set, NULL}, + +#define TEST_PROPERTY_GETSETDEF {"property", (getter)Test_property_get, (setter)Test_property_set, NULL}, + +#define TEST_SETTER_FIRST_WITH_DOCSTR_GETSETDEF {"setter_first_with_docstr", (getter)Test_setter_first_with_docstr_get, (setter)Test_setter_first_with_docstr_set, Test_setter_first_with_docstr__doc__}, + +/*[clinic end generated code: output=011497a4f5a2e835 input=524ce2e021e4eba6]*/ /*[clinic input] output push @@ -6367,3 +6397,13 @@ static PyObject * test_critical_section_object2_impl(PyObject *module, PyObject *a, PyObject *b) /*[clinic end generated code: output=d73a1657c18df17a input=638824e41419a466]*/ + +/*[clinic input] +dump buffer +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/ + +/*[clinic input] +dump buffer +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/ diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index 20da30f445d28c..f5334f70768dc4 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -21,7 +21,8 @@ with test_tools.imports_under_tool('clinic'): import libclinic from libclinic import ClinicError, unspecified, NULL, fail - from libclinic.converters import int_converter, str_converter, self_converter + from libclinic.converters import ( + int_converter, object_converter, str_converter, self_converter) from libclinic.function import ( Module, Class, Function, FunctionKind, Parameter, permute_optional_groups, permute_right_option_groups, @@ -797,10 +798,22 @@ def test_ignore_preprocessor_in_comments(self): """) self.clinic.parse(raw) + def test_var_keyword_non_dict(self): + err = "'var_keyword_object' is not a valid converter" + block = """ + /*[clinic input] + my_test_func + + **kwds: object + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=4) + def test_getset_in_ifdef(self): block = """ /*[clinic input] output everything block + output methoddef_ifndef buffer class Foo "FooObject *" "&Foo_Type" [clinic start generated code]*/ #ifdef CONDITION @@ -811,54 +824,117 @@ class Foo "FooObject *" "&Foo_Type" /*[clinic input] @setter Foo.property + value: object [clinic start generated code]*/ #endif + /*[clinic input] + dump buffer + [clinic start generated code]*/ """ generated = self.clinic.parse(dedent(block)) self.assertIn("#if defined(CONDITION)", generated) # The getset is undefined if the condition is false. - self.assertIn("#ifndef FOO_PROPERTY_GETSETDEF\n" - " #define FOO_PROPERTY_GETSETDEF\n" - "#endif /* !defined(FOO_PROPERTY_GETSETDEF) */", + self.assertIn("#else\n" + "# define FOO_PROPERTY_GETSETDEF\n" + "#endif", generated) - def test_getset_duplicate(self): - for annotation in "@getter", "@setter": - with self.subTest(annotation=annotation): - self.clinic = _make_clinic(filename="test.c") - block = f""" - /*[clinic input] - class Foo "FooObject *" "&Foo_Type" - [clinic start generated code]*/ - /*[clinic input] - {annotation} - Foo.property - [clinic start generated code]*/ - /*[clinic input] - {annotation} - Foo.property - [clinic start generated code]*/ - """ - kind = 'setter' if annotation == '@setter' else 'getter' - err = f"Cannot apply @{kind} to 'Foo.property' twice" - self.expect_failure(block, err, lineno=10) + def test_getset_partially_in_ifdef(self): + block = """ + /*[clinic input] + output everything block + output methoddef_ifndef buffer + class Foo "FooObject *" "&Foo_Type" + [clinic start generated code]*/ + #ifdef CONDITION + /*[clinic input] + @getter + Foo.property + [clinic start generated code]*/ + #endif + /*[clinic input] + @setter + Foo.property + value: object + [clinic start generated code]*/ + /*[clinic input] + dump buffer + [clinic start generated code]*/ + """ + generated = self.clinic.parse(dedent(block)) + # Only the conditional getter announces itself. + self.assertIn("#if defined(CONDITION)\n" + "\n" + "#define FOO_PROPERTY_GETTER Foo_property_get\n", + generated) + self.assertIn("#define FOO_PROPERTY_SETTER Foo_property_set\n" + "#if defined(FOO_PROPERTY_GETTER) " + "|| defined(FOO_PROPERTY_SETTER)", + generated) + self.assertIn('# define FOO_PROPERTY_GETSETDEF {"property", ' + '(getter)FOO_PROPERTY_GETTER, ' + '(setter)FOO_PROPERTY_SETTER, FOO_PROPERTY_DOCSTR},', + generated) - def test_getset_different_c_basename(self): + def test_getset_several_implementations(self): block = """ /*[clinic input] + output everything block + output methoddef_ifndef buffer class Foo "FooObject *" "&Foo_Type" [clinic start generated code]*/ + #ifdef CONDITION /*[clinic input] @getter - Foo.property as foo_get + Foo.property as foo_property_special + [clinic start generated code]*/ + #else + /*[clinic input] + @getter + Foo.property as foo_property_generic + [clinic start generated code]*/ + #endif + /*[clinic input] + dump buffer + [clinic start generated code]*/ + """ + # Implementations guarded by preprocessor conditions can share the + # entry; which of them is compiled is only known to the preprocessor. + generated = self.clinic.parse(dedent(block)) + self.assertIn("#if defined(CONDITION)\n" + "\n" + "#define FOO_PROPERTY_GETTER " + "foo_property_special_get\n", + generated) + self.assertIn("#if !defined(CONDITION)\n" + "\n" + "#define FOO_PROPERTY_GETTER " + "foo_property_generic_get\n", + generated) + + def test_getset_after_dump(self): + block = """ + /*[clinic input] + output everything block + output methoddef_ifndef buffer + class Foo "FooObject *" "&Foo_Type" + [clinic start generated code]*/ + /*[clinic input] + @getter + Foo.property + [clinic start generated code]*/ + /*[clinic input] + dump buffer [clinic start generated code]*/ /*[clinic input] @setter - Foo.property as foo_set + Foo.property + value: object [clinic start generated code]*/ """ - err = "The accessors of 'Foo.property' must have the same C basename" - self.expect_failure(block, err, lineno=10) + err = ("All accessors of 'Foo.property' must be defined before " + "its PyGetSetDef entry is dumped") + self.expect_failure(block, err, lineno=15) def test_setter_deletion_check(self): block = """ @@ -869,10 +945,11 @@ class Foo "FooObject *" "&Foo_Type" /*[clinic input] @setter Foo.property + value: object [clinic start generated code]*/ """ generated = self.clinic.parse(dedent(block)) - self.assertIn("if (value == NULL) {", generated) + self.assertIn("if (arg == NULL) {", generated) self.assertIn("\"attribute 'property' of '%.100s' objects " "cannot be deleted\"", generated) @@ -888,21 +965,65 @@ class Foo "FooObject *" "&Foo_Type" @setter @deleter Foo.property + value: object = NULL [clinic start generated code]*/ """ generated = self.clinic.parse(dedent(block)) - self.assertNotIn("if (value == NULL) {", generated) + self.assertNotIn("if (arg == NULL) {", generated) - def test_var_keyword_non_dict(self): - err = "'var_keyword_object' is not a valid converter" + def test_getset_duplicate(self): + # Only a setter defines the new value. + for annotation, parameter, err in ( + ("@getter", "", "Cannot apply @getter to 'Foo.property' twice"), + ("@setter", "value: object", + "The setter of 'Foo.property' is already defined"), + ): + with self.subTest(annotation=annotation): + self.clinic = _make_clinic(filename="test.c") + block = f""" + /*[clinic input] + class Foo "FooObject *" "&Foo_Type" + [clinic start generated code]*/ + /*[clinic input] + {annotation} + Foo.property + {parameter} + [clinic start generated code]*/ + /*[clinic input] + {annotation} + Foo.property + {parameter} + [clinic start generated code]*/ + """ + self.expect_failure(block, err, lineno=11) + + def test_getset_different_c_basename(self): block = """ /*[clinic input] - my_test_func - - **kwds: object + output everything block + output methoddef_ifndef buffer + class Foo "FooObject *" "&Foo_Type" + [clinic start generated code]*/ + /*[clinic input] + @getter + Foo.property as foo_get + [clinic start generated code]*/ + /*[clinic input] + @setter + Foo.property as foo_set + value: object + [clinic start generated code]*/ + /*[clinic input] + dump buffer [clinic start generated code]*/ """ - self.expect_failure(block, err, lineno=4) + # The accessors are identified by the Python name, not by the + # C basename. + generated = self.clinic.parse(dedent(block)) + self.assertIn('#define FOO_PROPERTY_GETSETDEF {"property", ' + '(getter)foo_get_get, (setter)foo_set_set, NULL},', + generated) + class ParseFileUnitTest(TestCase): def expect_parsing_failure( @@ -2883,29 +3004,132 @@ class Foo "" "" self.expect_failure(block, expected_error, lineno=1) def test_invalid_getset(self): - annotations = ["@getter", "@setter"] - for annotation in annotations: - with self.subTest(annotation=annotation): + block = """ + module foo + class Foo "" "" + @setter + Foo.property -> int + """ + expected_error = "@setter methods cannot define a return type" + self.expect_failure(block, expected_error, lineno=3) + + block = """ + module foo + class Foo "" "" + @getter + Foo.property + obj: int + / + """ + expected_error = "@getter methods cannot define parameters" + self.expect_failure(block, expected_error) + + block = """ + module foo + class Foo "" "" + @setter + Foo.property + obj: int + value: int + / + """ + expected_error = "@setter methods must define exactly one parameter" + self.expect_failure(block, expected_error) + + def test_setter_value_default(self): + block = """ + module m + class Foo "" "" + @setter + Foo.property + value: object = None + """ + expected_error = "the value of @setter cannot have a default value" + self.expect_failure(block, expected_error) + + block = """ + module m + class Foo "" "" + @setter + @deleter + Foo.property + value: object + """ + expected_error = ("the value of @setter with @deleter must have " + "a default value, used to delete the attribute") + self.expect_failure(block, expected_error) + + block = """ + module m + class Foo "" "" + @setter + @deleter + Foo.property + value: object = None + """ + expected_error = ("the value of @setter with @deleter can only have " + "NULL as a default value") + self.expect_failure(block, expected_error) + + def test_setter_value_kind(self): + expected_error = "the value of @setter must be a positional parameter" + block = """ + module m + class Foo "" "" + @setter + Foo.property + + * + value: object + """ + self.expect_failure(block, expected_error) + + for parameter in "*args: tuple", "**kwargs: dict": + with self.subTest(parameter=parameter): block = f""" - module foo + module m class Foo "" "" - {annotation} - Foo.property -> int - """ - expected_error = "@getter and @setter methods cannot define a return type" - self.expect_failure(block, expected_error, lineno=3) + @setter + Foo.property - block = f""" - module foo - class Foo "" "" - {annotation} - Foo.property - obj: int - / + {parameter} """ - expected_error = "@getter and @setter methods cannot define parameters" self.expect_failure(block, expected_error) + def test_setter_implicit_parameter(self): + function = self.parse_function(""" + module foo + class Foo "" "" + @setter + Foo.property + """, signatures_in_block=3, function_index=2) + self.assertEqual(function.kind, FunctionKind.SETTER) + value = function.parameters['value'] + self.assertIsInstance(value.converter, object_converter) + self.assertIs(value.default, unspecified) + + def test_setter_and_deleter_implicit_parameter(self): + function = self.parse_function(""" + module foo + class Foo "" "" + @setter + @deleter + Foo.property + """, signatures_in_block=3, function_index=2) + self.assertEqual(function.kind, FunctionKind.SETTER_AND_DELETER) + value = function.parameters['value'] + self.assertIsInstance(value.converter, object_converter) + self.assertIs(value.default, NULL) + + def test_getter_return_converter(self): + function = self.parse_function(""" + module foo + class Foo "" "" + @getter + Foo.property -> int + """, signatures_in_block=3, function_index=2) + self.assertEqual(function.return_converter.type, "int") + def test_setter_docstring(self): block = """ module foo @@ -2918,7 +3142,7 @@ class Foo "" "" bar [clinic start generated code]*/ """ - expected_error = "docstrings are only supported for @getter, not @setter" + expected_error = "docstrings are only supported for @getter" self.expect_failure(block, expected_error) def test_duplicate_getset(self): @@ -2946,8 +3170,8 @@ class Foo "" "" {dup[1]} Foo.property -> int """ - expected_error = (f"Can't set {dup[1]}, " - f"function is not a normal callable") + expected_error = (f"Can't set {dup[1]}, function is not " + f"a normal callable") self.expect_failure(block, expected_error, lineno=3) def test_deleter_without_setter(self): @@ -2981,16 +3205,6 @@ class Foo "" "" expected_error = "Cannot apply @deleter twice to the same function!" self.expect_failure(block, expected_error, lineno=4) - def test_setter_and_deleter(self): - function = self.parse_function(""" - module foo - class Foo "" "" - @setter - @deleter - Foo.property - """, signatures_in_block=3, function_index=2) - self.assertEqual(function.kind, FunctionKind.SETTER_AND_DELETER) - def test_getset_no_class(self): for annotation in "@getter", "@setter": with self.subTest(annotation=annotation): diff --git a/Lib/test/test_ctypes/test_delattr.py b/Lib/test/test_ctypes/test_delattr.py index 689bf327176f09..468712d52df475 100644 --- a/Lib/test/test_ctypes/test_delattr.py +++ b/Lib/test/test_ctypes/test_delattr.py @@ -9,12 +9,12 @@ class X(Structure): class TestCase(unittest.TestCase): def test_simple(self): - with self.assertRaises(TypeError): + with self.assertRaises(AttributeError): del c_int(42).value def test_chararray(self): chararray = (c_char * 5)() - with self.assertRaises(TypeError): + with self.assertRaises(AttributeError): del chararray.value def test_pointer_contents(self): diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 026c2bf6b31e73..4cdd269c7761ff 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -748,17 +748,17 @@ def test_object_attributes(self): self.assertIsNone(getattr(exc, name)) def test_invalid_delattr(self): - TE = TypeError + AE = AttributeError try: raise IndexError(4) except Exception as e: exc = e - msg = "may not be deleted" - self.assertRaisesRegex(TE, msg, delattr, exc, 'args') - self.assertRaisesRegex(TE, msg, delattr, exc, '__traceback__') - self.assertRaisesRegex(TE, msg, delattr, exc, '__cause__') - self.assertRaisesRegex(TE, msg, delattr, exc, '__context__') + msg = "cannot be deleted" + self.assertRaisesRegex(AE, msg, delattr, exc, 'args') + self.assertRaisesRegex(AE, msg, delattr, exc, '__traceback__') + self.assertRaisesRegex(AE, msg, delattr, exc, '__cause__') + self.assertRaisesRegex(AE, msg, delattr, exc, '__context__') def testNoneClearsTracebackAttr(self): try: diff --git a/Lib/test/test_funcattrs.py b/Lib/test/test_funcattrs.py index b2fa10d7458012..9ebb76febd5d63 100644 --- a/Lib/test/test_funcattrs.py +++ b/Lib/test/test_funcattrs.py @@ -229,7 +229,7 @@ def not_generic(): pass for func in (not_generic, lambda_): with self.subTest(func=func): self.assertEqual(func.__type_params__, ()) - with self.assertRaises(TypeError): + with self.assertRaises(AttributeError): del func.__type_params__ with self.assertRaises(TypeError): func.__type_params__ = 42 diff --git a/Lib/test/test_raise.py b/Lib/test/test_raise.py index 645ef291a58499..fa4306d2077357 100644 --- a/Lib/test/test_raise.py +++ b/Lib/test/test_raise.py @@ -257,7 +257,7 @@ def test_attrs(self): self.assertIs(tb.tb_next.tb_next, None) # Invalid assignments - with self.assertRaises(TypeError): + with self.assertRaises(AttributeError): del tb.tb_next with self.assertRaises(TypeError): diff --git a/Misc/NEWS.d/next/Tools-Demos/2026-08-14-13-15-35.gh-issue-113318.oHjvUR.rst b/Misc/NEWS.d/next/Tools-Demos/2026-08-14-13-15-35.gh-issue-113318.oHjvUR.rst new file mode 100644 index 00000000000000..5af26352642a6e --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2026-08-14-13-15-35.gh-issue-113318.oHjvUR.rst @@ -0,0 +1,7 @@ +The value of a setter generated by Argument Clinic is now a parameter, which +can use a converter, and a getter can define a return converter. +It is optional to declare the value of the setter. +The accessors of the same attribute are now identified by the Python name of +that attribute instead of the C basename, so they can use different C +basenames, and several implementations of the same accessor can be defined +in different preprocessor conditional blocks. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 9d047c39d27e25..18e731336d6da1 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1354,85 +1354,67 @@ _asyncio_Future__asyncio_awaited_by_get_impl(FutureObj *self) /*[clinic input] @critical_section @getter -_asyncio.Future._asyncio_future_blocking +_asyncio.Future._asyncio_future_blocking -> bool [clinic start generated code]*/ -static PyObject * +static int _asyncio_Future__asyncio_future_blocking_get_impl(FutureObj *self) -/*[clinic end generated code: output=a558a2c51e38823b input=58da92efc03b617d]*/ +/*[clinic end generated code: output=32944de3df031979 input=2a51a0cf31a96826]*/ { - if (future_is_alive(self) && self->fut_blocking) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } + return future_is_alive(self) && self->fut_blocking; } /*[clinic input] @critical_section @setter _asyncio.Future._asyncio_future_blocking + value: bool [clinic start generated code]*/ static int -_asyncio_Future__asyncio_future_blocking_set_impl(FutureObj *self, - PyObject *value) -/*[clinic end generated code: output=0686d1cb024a7453 input=3fd4a5f95df788b7]*/ - +_asyncio_Future__asyncio_future_blocking_set_impl(FutureObj *self, int value) +/*[clinic end generated code: output=be2d5cb1cad6dd30 input=81780cb7b89f28e1]*/ { if (future_ensure_alive(self)) { return -1; } - - int is_true = PyObject_IsTrue(value); - if (is_true < 0) { - return -1; - } - self->fut_blocking = is_true; + self->fut_blocking = value; return 0; } /*[clinic input] @critical_section @getter -_asyncio.Future._log_traceback +_asyncio.Future._log_traceback -> bool [clinic start generated code]*/ -static PyObject * +static int _asyncio_Future__log_traceback_get_impl(FutureObj *self) -/*[clinic end generated code: output=2724433b238593c7 input=91e5144ea4117d8e]*/ +/*[clinic end generated code: output=ba1356634182ac25 input=50f4db8eca9d1fb4]*/ { - asyncio_state *state = get_asyncio_state_by_def((PyObject *)self); - ENSURE_FUTURE_ALIVE(state, self) - if (self->fut_log_tb) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; + if (future_ensure_alive(self)) { + return -1; } + return self->fut_log_tb; } /*[clinic input] @critical_section @setter _asyncio.Future._log_traceback + value: bool [clinic start generated code]*/ static int -_asyncio_Future__log_traceback_set_impl(FutureObj *self, PyObject *value) -/*[clinic end generated code: output=9ce8e19504f42f54 input=30ac8217754b08c2]*/ +_asyncio_Future__log_traceback_set_impl(FutureObj *self, int value) +/*[clinic end generated code: output=ad84ae67ef80e3ad input=30c0f841c945c73f]*/ { - int is_true = PyObject_IsTrue(value); - if (is_true < 0) { - return -1; - } - if (is_true) { + if (value) { PyErr_SetString(PyExc_ValueError, "_log_traceback can only be set to False"); return -1; } - self->fut_log_tb = is_true; + self->fut_log_tb = value; return 0; } /*[clinic input] @@ -2420,36 +2402,28 @@ TaskObj_traverse(PyObject *op, visitproc visit, void *arg) /*[clinic input] @critical_section @getter -_asyncio.Task._log_destroy_pending +_asyncio.Task._log_destroy_pending -> bool [clinic start generated code]*/ -static PyObject * +static int _asyncio_Task__log_destroy_pending_get_impl(TaskObj *self) -/*[clinic end generated code: output=e6c2a47d029ac93b input=17127298cd4c720b]*/ +/*[clinic end generated code: output=98b5f7bad24a2381 input=a87002bdf72e380b]*/ { - if (self->task_log_destroy_pending) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } + return self->task_log_destroy_pending; } /*[clinic input] @critical_section @setter _asyncio.Task._log_destroy_pending + value: bool [clinic start generated code]*/ static int -_asyncio_Task__log_destroy_pending_set_impl(TaskObj *self, PyObject *value) -/*[clinic end generated code: output=7ebc030bb92ec5ce input=49b759c97d1216a4]*/ +_asyncio_Task__log_destroy_pending_set_impl(TaskObj *self, int value) +/*[clinic end generated code: output=132bbf2b4c627777 input=533fea7776daa075]*/ { - int is_true = PyObject_IsTrue(value); - if (is_true < 0) { - return -1; - } - self->task_log_destroy_pending = is_true; + self->task_log_destroy_pending = value; return 0; } diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 97f33b1be8561f..f0945e48aa3bf0 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -600,12 +600,11 @@ _ctypes_CType_Type___pointer_type___get_impl(PyObject *self) @setter @deleter _ctypes.CType_Type.__pointer_type__ - [clinic start generated code]*/ static int _ctypes_CType_Type___pointer_type___set_impl(PyObject *self, PyObject *value) -/*[clinic end generated code: output=6259be8ea21693fa input=7e24bceb1676349b]*/ +/*[clinic end generated code: output=6259be8ea21693fa input=07e8b7a8fcc1efc1]*/ { ctypes_state *st = get_module_state_by_def(Py_TYPE(self)); StgInfo *info; @@ -1482,33 +1481,20 @@ class _ctypes.PyCArrayType_Type "CDataObject *" "clinic_state()->PyCArrayType_Ty @critical_section @setter _ctypes.PyCArrayType_Type.raw + value: Py_buffer [clinic start generated code]*/ static int -_ctypes_PyCArrayType_Type_raw_set_impl(CDataObject *self, PyObject *value) -/*[clinic end generated code: output=cf9b2a9fd92e9ecb input=a3717561efc45efd]*/ +_ctypes_PyCArrayType_Type_raw_set_impl(CDataObject *self, Py_buffer *value) +/*[clinic end generated code: output=273e537dc31f4bbd input=90775c9408b1bb59]*/ { - char *ptr; - Py_ssize_t size; - Py_buffer view; - - if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0) - return -1; - size = view.len; - ptr = view.buf; - if (size > self->b_size) { + if (value->len > self->b_size) { PyErr_SetString(PyExc_ValueError, "byte string too long"); - goto fail; + return -1; } - - memcpy(self->b_ptr, ptr, size); - - PyBuffer_Release(&view); + memcpy(self->b_ptr, value->buf, value->len); return 0; - fail: - PyBuffer_Release(&view); - return -1; } /*[clinic input] @@ -1547,44 +1533,25 @@ _ctypes_PyCArrayType_Type_value_get_impl(CDataObject *self) /*[clinic input] @critical_section @setter -@deleter _ctypes.PyCArrayType_Type.value + value: object(subclass_of='&PyBytes_Type', type='PyBytesObject *') [clinic start generated code]*/ static int -_ctypes_PyCArrayType_Type_value_set_impl(CDataObject *self, PyObject *value) -/*[clinic end generated code: output=39ad655636a28dd5 input=167f0935cbb8d489]*/ +_ctypes_PyCArrayType_Type_value_set_impl(CDataObject *self, + PyBytesObject *value) +/*[clinic end generated code: output=21cbd436230dc33e input=47d40501c4ecae23]*/ { - const char *ptr; - Py_ssize_t size; - - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "can't delete attribute"); - return -1; - } - - if (!PyBytes_Check(value)) { - PyErr_Format(PyExc_TypeError, - "bytes expected instead of %s instance", - Py_TYPE(value)->tp_name); - return -1; - } else - Py_INCREF(value); - size = PyBytes_GET_SIZE(value); + Py_ssize_t size = PyBytes_GET_SIZE(value); if (size > self->b_size) { PyErr_SetString(PyExc_ValueError, "byte string too long"); - Py_DECREF(value); return -1; } - ptr = PyBytes_AS_STRING(value); - memcpy(self->b_ptr, ptr, size); + memcpy(self->b_ptr, PyBytes_AS_STRING(value), size); if (size < self->b_size) self->b_ptr[size] = '\0'; - Py_DECREF(value); - return 0; } @@ -5414,22 +5381,15 @@ class _ctypes.Simple "CDataObject *" "clinic_state()->Simple_Type" /*[clinic input] @critical_section @setter -@deleter _ctypes.Simple.value [clinic start generated code]*/ static int _ctypes_Simple_value_set_impl(CDataObject *self, PyObject *value) -/*[clinic end generated code: output=f267186118939863 input=4e6c1143d17c2c3f]*/ +/*[clinic end generated code: output=f267186118939863 input=977af9dc9e71e857]*/ { PyObject *result; - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "can't delete attribute"); - return -1; - } - ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self))); StgInfo *info; if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) { diff --git a/Modules/_ctypes/clinic/_ctypes.c.h b/Modules/_ctypes/clinic/_ctypes.c.h index 221b110cd15d2d..b5a64b8730a772 100644 --- a/Modules/_ctypes/clinic/_ctypes.c.h +++ b/Modules/_ctypes/clinic/_ctypes.c.h @@ -31,16 +31,6 @@ _ctypes_CType_Type___sizeof__(PyObject *self, PyTypeObject *cls, PyObject *const return _ctypes_CType_Type___sizeof___impl(self, cls); } -#if !defined(_ctypes_CType_Type___pointer_type___DOCSTR) -# define _ctypes_CType_Type___pointer_type___DOCSTR NULL -#endif -#if defined(_CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF) -# undef _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF -# define _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF {"__pointer_type__", (getter)_ctypes_CType_Type___pointer_type___get, (setter)_ctypes_CType_Type___pointer_type___set, _ctypes_CType_Type___pointer_type___DOCSTR}, -#else -# define _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF {"__pointer_type__", (getter)_ctypes_CType_Type___pointer_type___get, NULL, _ctypes_CType_Type___pointer_type___DOCSTR}, -#endif - static PyObject * _ctypes_CType_Type___pointer_type___get_impl(PyObject *self); @@ -50,24 +40,18 @@ _ctypes_CType_Type___pointer_type___get(PyObject *self, void *Py_UNUSED(context) return _ctypes_CType_Type___pointer_type___get_impl(self); } -#if !defined(_ctypes_CType_Type___pointer_type___DOCSTR) -# define _ctypes_CType_Type___pointer_type___DOCSTR NULL -#endif -#if defined(_CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF) -# undef _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF -# define _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF {"__pointer_type__", (getter)_ctypes_CType_Type___pointer_type___get, (setter)_ctypes_CType_Type___pointer_type___set, _ctypes_CType_Type___pointer_type___DOCSTR}, -#else -# define _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF {"__pointer_type__", NULL, (setter)_ctypes_CType_Type___pointer_type___set, NULL}, -#endif - static int _ctypes_CType_Type___pointer_type___set_impl(PyObject *self, PyObject *value); static int -_ctypes_CType_Type___pointer_type___set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ctypes_CType_Type___pointer_type___set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value = NULL; + if (arg != NULL) { + value = arg; + } return_value = _ctypes_CType_Type___pointer_type___set_impl(self, value); return return_value; @@ -459,47 +443,37 @@ PyCPointerType_from_param(PyObject *type, PyTypeObject *cls, PyObject *const *ar return return_value; } -#if !defined(_ctypes_PyCArrayType_Type_raw_DOCSTR) -# define _ctypes_PyCArrayType_Type_raw_DOCSTR NULL -#endif -#if defined(_CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF) -# undef _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF -# define _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF {"raw", (getter)_ctypes_PyCArrayType_Type_raw_get, (setter)_ctypes_PyCArrayType_Type_raw_set, _ctypes_PyCArrayType_Type_raw_DOCSTR}, -#else -# define _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF {"raw", NULL, (setter)_ctypes_PyCArrayType_Type_raw_set, NULL}, -#endif - static int -_ctypes_PyCArrayType_Type_raw_set_impl(CDataObject *self, PyObject *value); +_ctypes_PyCArrayType_Type_raw_set_impl(CDataObject *self, Py_buffer *value); static int -_ctypes_PyCArrayType_Type_raw_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ctypes_PyCArrayType_Type_raw_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + Py_buffer value = {NULL, NULL}; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'raw' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + if (PyObject_GetBuffer(arg, &value, PyBUF_SIMPLE) != 0) { + goto exit; + } Py_BEGIN_CRITICAL_SECTION(self); - return_value = _ctypes_PyCArrayType_Type_raw_set_impl((CDataObject *)self, value); + return_value = _ctypes_PyCArrayType_Type_raw_set_impl((CDataObject *)self, &value); Py_END_CRITICAL_SECTION(); +exit: + /* Cleanup for value */ + if (value.obj) { + PyBuffer_Release(&value); + } + return return_value; } -#if !defined(_ctypes_PyCArrayType_Type_raw_DOCSTR) -# define _ctypes_PyCArrayType_Type_raw_DOCSTR NULL -#endif -#if defined(_CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF) -# undef _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF -# define _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF {"raw", (getter)_ctypes_PyCArrayType_Type_raw_get, (setter)_ctypes_PyCArrayType_Type_raw_set, _ctypes_PyCArrayType_Type_raw_DOCSTR}, -#else -# define _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF {"raw", (getter)_ctypes_PyCArrayType_Type_raw_get, NULL, _ctypes_PyCArrayType_Type_raw_DOCSTR}, -#endif - static PyObject * _ctypes_PyCArrayType_Type_raw_get_impl(CDataObject *self); @@ -515,16 +489,6 @@ _ctypes_PyCArrayType_Type_raw_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ctypes_PyCArrayType_Type_value_DOCSTR) -# define _ctypes_PyCArrayType_Type_value_DOCSTR NULL -#endif -#if defined(_CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF) -# undef _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF -# define _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF {"value", (getter)_ctypes_PyCArrayType_Type_value_get, (setter)_ctypes_PyCArrayType_Type_value_set, _ctypes_PyCArrayType_Type_value_DOCSTR}, -#else -# define _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF {"value", (getter)_ctypes_PyCArrayType_Type_value_get, NULL, _ctypes_PyCArrayType_Type_value_DOCSTR}, -#endif - static PyObject * _ctypes_PyCArrayType_Type_value_get_impl(CDataObject *self); @@ -540,28 +504,32 @@ _ctypes_PyCArrayType_Type_value_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ctypes_PyCArrayType_Type_value_DOCSTR) -# define _ctypes_PyCArrayType_Type_value_DOCSTR NULL -#endif -#if defined(_CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF) -# undef _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF -# define _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF {"value", (getter)_ctypes_PyCArrayType_Type_value_get, (setter)_ctypes_PyCArrayType_Type_value_set, _ctypes_PyCArrayType_Type_value_DOCSTR}, -#else -# define _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF {"value", NULL, (setter)_ctypes_PyCArrayType_Type_value_set, NULL}, -#endif - static int -_ctypes_PyCArrayType_Type_value_set_impl(CDataObject *self, PyObject *value); +_ctypes_PyCArrayType_Type_value_set_impl(CDataObject *self, + PyBytesObject *value); static int -_ctypes_PyCArrayType_Type_value_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ctypes_PyCArrayType_Type_value_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyBytesObject *value; + if (arg == NULL) { + PyErr_Format(PyExc_AttributeError, + "attribute 'value' of '%.100s' objects cannot be deleted", + Py_TYPE(self)->tp_name); + return -1; + } + if (!PyBytes_Check(arg)) { + PyErr_Format(PyExc_TypeError, "attribute 'value' must be bytes, not %T", arg); + goto exit; + } + value = (PyBytesObject *)arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = _ctypes_PyCArrayType_Type_value_set_impl((CDataObject *)self, value); Py_END_CRITICAL_SECTION(); +exit: return return_value; } @@ -817,24 +785,18 @@ _ctypes_PyCData___ctypes_from_outparam__(PyObject *self, PyObject *Py_UNUSED(ign return _ctypes_PyCData___ctypes_from_outparam___impl(self); } -#if !defined(_ctypes_CFuncPtr_errcheck_DOCSTR) -# define _ctypes_CFuncPtr_errcheck_DOCSTR NULL -#endif -#if defined(_CTYPES_CFUNCPTR_ERRCHECK_GETSETDEF) -# undef _CTYPES_CFUNCPTR_ERRCHECK_GETSETDEF -# define _CTYPES_CFUNCPTR_ERRCHECK_GETSETDEF {"errcheck", (getter)_ctypes_CFuncPtr_errcheck_get, (setter)_ctypes_CFuncPtr_errcheck_set, _ctypes_CFuncPtr_errcheck_DOCSTR}, -#else -# define _CTYPES_CFUNCPTR_ERRCHECK_GETSETDEF {"errcheck", NULL, (setter)_ctypes_CFuncPtr_errcheck_set, NULL}, -#endif - static int _ctypes_CFuncPtr_errcheck_set_impl(PyCFuncPtrObject *self, PyObject *value); static int -_ctypes_CFuncPtr_errcheck_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ctypes_CFuncPtr_errcheck_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value = NULL; + if (arg != NULL) { + value = arg; + } Py_BEGIN_CRITICAL_SECTION(self); return_value = _ctypes_CFuncPtr_errcheck_set_impl((PyCFuncPtrObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -844,20 +806,6 @@ _ctypes_CFuncPtr_errcheck_set(PyObject *self, PyObject *value, void *Py_UNUSED(c PyDoc_STRVAR(_ctypes_CFuncPtr_errcheck__doc__, "a function to check for errors"); -#if defined(_ctypes_CFuncPtr_errcheck_DOCSTR) -# undef _ctypes_CFuncPtr_errcheck_DOCSTR -#endif -#define _ctypes_CFuncPtr_errcheck_DOCSTR _ctypes_CFuncPtr_errcheck__doc__ - -#if !defined(_ctypes_CFuncPtr_errcheck_DOCSTR) -# define _ctypes_CFuncPtr_errcheck_DOCSTR NULL -#endif -#if defined(_CTYPES_CFUNCPTR_ERRCHECK_GETSETDEF) -# undef _CTYPES_CFUNCPTR_ERRCHECK_GETSETDEF -# define _CTYPES_CFUNCPTR_ERRCHECK_GETSETDEF {"errcheck", (getter)_ctypes_CFuncPtr_errcheck_get, (setter)_ctypes_CFuncPtr_errcheck_set, _ctypes_CFuncPtr_errcheck_DOCSTR}, -#else -# define _CTYPES_CFUNCPTR_ERRCHECK_GETSETDEF {"errcheck", (getter)_ctypes_CFuncPtr_errcheck_get, NULL, _ctypes_CFuncPtr_errcheck_DOCSTR}, -#endif static PyObject * _ctypes_CFuncPtr_errcheck_get_impl(PyCFuncPtrObject *self); @@ -874,24 +822,18 @@ _ctypes_CFuncPtr_errcheck_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ctypes_CFuncPtr_restype_DOCSTR) -# define _ctypes_CFuncPtr_restype_DOCSTR NULL -#endif -#if defined(_CTYPES_CFUNCPTR_RESTYPE_GETSETDEF) -# undef _CTYPES_CFUNCPTR_RESTYPE_GETSETDEF -# define _CTYPES_CFUNCPTR_RESTYPE_GETSETDEF {"restype", (getter)_ctypes_CFuncPtr_restype_get, (setter)_ctypes_CFuncPtr_restype_set, _ctypes_CFuncPtr_restype_DOCSTR}, -#else -# define _CTYPES_CFUNCPTR_RESTYPE_GETSETDEF {"restype", NULL, (setter)_ctypes_CFuncPtr_restype_set, NULL}, -#endif - static int _ctypes_CFuncPtr_restype_set_impl(PyCFuncPtrObject *self, PyObject *value); static int -_ctypes_CFuncPtr_restype_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ctypes_CFuncPtr_restype_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value = NULL; + if (arg != NULL) { + value = arg; + } Py_BEGIN_CRITICAL_SECTION(self); return_value = _ctypes_CFuncPtr_restype_set_impl((PyCFuncPtrObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -901,20 +843,6 @@ _ctypes_CFuncPtr_restype_set(PyObject *self, PyObject *value, void *Py_UNUSED(co PyDoc_STRVAR(_ctypes_CFuncPtr_restype__doc__, "specify the result type"); -#if defined(_ctypes_CFuncPtr_restype_DOCSTR) -# undef _ctypes_CFuncPtr_restype_DOCSTR -#endif -#define _ctypes_CFuncPtr_restype_DOCSTR _ctypes_CFuncPtr_restype__doc__ - -#if !defined(_ctypes_CFuncPtr_restype_DOCSTR) -# define _ctypes_CFuncPtr_restype_DOCSTR NULL -#endif -#if defined(_CTYPES_CFUNCPTR_RESTYPE_GETSETDEF) -# undef _CTYPES_CFUNCPTR_RESTYPE_GETSETDEF -# define _CTYPES_CFUNCPTR_RESTYPE_GETSETDEF {"restype", (getter)_ctypes_CFuncPtr_restype_get, (setter)_ctypes_CFuncPtr_restype_set, _ctypes_CFuncPtr_restype_DOCSTR}, -#else -# define _CTYPES_CFUNCPTR_RESTYPE_GETSETDEF {"restype", (getter)_ctypes_CFuncPtr_restype_get, NULL, _ctypes_CFuncPtr_restype_DOCSTR}, -#endif static PyObject * _ctypes_CFuncPtr_restype_get_impl(PyCFuncPtrObject *self); @@ -931,24 +859,18 @@ _ctypes_CFuncPtr_restype_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ctypes_CFuncPtr_argtypes_DOCSTR) -# define _ctypes_CFuncPtr_argtypes_DOCSTR NULL -#endif -#if defined(_CTYPES_CFUNCPTR_ARGTYPES_GETSETDEF) -# undef _CTYPES_CFUNCPTR_ARGTYPES_GETSETDEF -# define _CTYPES_CFUNCPTR_ARGTYPES_GETSETDEF {"argtypes", (getter)_ctypes_CFuncPtr_argtypes_get, (setter)_ctypes_CFuncPtr_argtypes_set, _ctypes_CFuncPtr_argtypes_DOCSTR}, -#else -# define _CTYPES_CFUNCPTR_ARGTYPES_GETSETDEF {"argtypes", NULL, (setter)_ctypes_CFuncPtr_argtypes_set, NULL}, -#endif - static int _ctypes_CFuncPtr_argtypes_set_impl(PyCFuncPtrObject *self, PyObject *value); static int -_ctypes_CFuncPtr_argtypes_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ctypes_CFuncPtr_argtypes_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value = NULL; + if (arg != NULL) { + value = arg; + } Py_BEGIN_CRITICAL_SECTION(self); return_value = _ctypes_CFuncPtr_argtypes_set_impl((PyCFuncPtrObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -958,20 +880,6 @@ _ctypes_CFuncPtr_argtypes_set(PyObject *self, PyObject *value, void *Py_UNUSED(c PyDoc_STRVAR(_ctypes_CFuncPtr_argtypes__doc__, "specify the argument types"); -#if defined(_ctypes_CFuncPtr_argtypes_DOCSTR) -# undef _ctypes_CFuncPtr_argtypes_DOCSTR -#endif -#define _ctypes_CFuncPtr_argtypes_DOCSTR _ctypes_CFuncPtr_argtypes__doc__ - -#if !defined(_ctypes_CFuncPtr_argtypes_DOCSTR) -# define _ctypes_CFuncPtr_argtypes_DOCSTR NULL -#endif -#if defined(_CTYPES_CFUNCPTR_ARGTYPES_GETSETDEF) -# undef _CTYPES_CFUNCPTR_ARGTYPES_GETSETDEF -# define _CTYPES_CFUNCPTR_ARGTYPES_GETSETDEF {"argtypes", (getter)_ctypes_CFuncPtr_argtypes_get, (setter)_ctypes_CFuncPtr_argtypes_set, _ctypes_CFuncPtr_argtypes_DOCSTR}, -#else -# define _CTYPES_CFUNCPTR_ARGTYPES_GETSETDEF {"argtypes", (getter)_ctypes_CFuncPtr_argtypes_get, NULL, _ctypes_CFuncPtr_argtypes_DOCSTR}, -#endif static PyObject * _ctypes_CFuncPtr_argtypes_get_impl(PyCFuncPtrObject *self); @@ -988,24 +896,22 @@ _ctypes_CFuncPtr_argtypes_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ctypes_Simple_value_DOCSTR) -# define _ctypes_Simple_value_DOCSTR NULL -#endif -#if defined(_CTYPES_SIMPLE_VALUE_GETSETDEF) -# undef _CTYPES_SIMPLE_VALUE_GETSETDEF -# define _CTYPES_SIMPLE_VALUE_GETSETDEF {"value", (getter)_ctypes_Simple_value_get, (setter)_ctypes_Simple_value_set, _ctypes_Simple_value_DOCSTR}, -#else -# define _CTYPES_SIMPLE_VALUE_GETSETDEF {"value", NULL, (setter)_ctypes_Simple_value_set, NULL}, -#endif - static int _ctypes_Simple_value_set_impl(CDataObject *self, PyObject *value); static int -_ctypes_Simple_value_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ctypes_Simple_value_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; + if (arg == NULL) { + PyErr_Format(PyExc_AttributeError, + "attribute 'value' of '%.100s' objects cannot be deleted", + Py_TYPE(self)->tp_name); + return -1; + } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = _ctypes_Simple_value_set_impl((CDataObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -1013,16 +919,6 @@ _ctypes_Simple_value_set(PyObject *self, PyObject *value, void *Py_UNUSED(contex return return_value; } -#if !defined(_ctypes_Simple_value_DOCSTR) -# define _ctypes_Simple_value_DOCSTR NULL -#endif -#if defined(_CTYPES_SIMPLE_VALUE_GETSETDEF) -# undef _CTYPES_SIMPLE_VALUE_GETSETDEF -# define _CTYPES_SIMPLE_VALUE_GETSETDEF {"value", (getter)_ctypes_Simple_value_get, (setter)_ctypes_Simple_value_set, _ctypes_Simple_value_DOCSTR}, -#else -# define _CTYPES_SIMPLE_VALUE_GETSETDEF {"value", (getter)_ctypes_Simple_value_get, NULL, _ctypes_Simple_value_DOCSTR}, -#endif - static PyObject * _ctypes_Simple_value_get_impl(CDataObject *self); @@ -1058,4 +954,18 @@ Simple_from_outparm(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py } return Simple_from_outparm_impl(self, cls); } -/*[clinic end generated code: output=b89feb50c654de3f input=a9049054013a1b77]*/ +#define _CTYPES_CTYPE_TYPE___POINTER_TYPE___GETSETDEF {"__pointer_type__", (getter)_ctypes_CType_Type___pointer_type___get, (setter)_ctypes_CType_Type___pointer_type___set, NULL}, + +#define _CTYPES_PYCARRAYTYPE_TYPE_RAW_GETSETDEF {"raw", (getter)_ctypes_PyCArrayType_Type_raw_get, (setter)_ctypes_PyCArrayType_Type_raw_set, NULL}, + +#define _CTYPES_PYCARRAYTYPE_TYPE_VALUE_GETSETDEF {"value", (getter)_ctypes_PyCArrayType_Type_value_get, (setter)_ctypes_PyCArrayType_Type_value_set, NULL}, + +#define _CTYPES_CFUNCPTR_ERRCHECK_GETSETDEF {"errcheck", (getter)_ctypes_CFuncPtr_errcheck_get, (setter)_ctypes_CFuncPtr_errcheck_set, _ctypes_CFuncPtr_errcheck__doc__}, + +#define _CTYPES_CFUNCPTR_RESTYPE_GETSETDEF {"restype", (getter)_ctypes_CFuncPtr_restype_get, (setter)_ctypes_CFuncPtr_restype_set, _ctypes_CFuncPtr_restype__doc__}, + +#define _CTYPES_CFUNCPTR_ARGTYPES_GETSETDEF {"argtypes", (getter)_ctypes_CFuncPtr_argtypes_get, (setter)_ctypes_CFuncPtr_argtypes_set, _ctypes_CFuncPtr_argtypes__doc__}, + +#define _CTYPES_SIMPLE_VALUE_GETSETDEF {"value", (getter)_ctypes_Simple_value_get, (setter)_ctypes_Simple_value_set, NULL}, + +/*[clinic end generated code: output=1d322c90c81649fd input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index b7c0ca2c4b919b..3ca28c5a390736 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -343,16 +343,6 @@ _io__Buffered_simple_flush(PyObject *self, PyObject *Py_UNUSED(ignored)) return return_value; } -#if !defined(_io__Buffered_closed_DOCSTR) -# define _io__Buffered_closed_DOCSTR NULL -#endif -#if defined(_IO__BUFFERED_CLOSED_GETSETDEF) -# undef _IO__BUFFERED_CLOSED_GETSETDEF -# define _IO__BUFFERED_CLOSED_GETSETDEF {"closed", (getter)_io__Buffered_closed_get, (setter)_io__Buffered_closed_set, _io__Buffered_closed_DOCSTR}, -#else -# define _IO__BUFFERED_CLOSED_GETSETDEF {"closed", (getter)_io__Buffered_closed_get, NULL, _io__Buffered_closed_DOCSTR}, -#endif - static PyObject * _io__Buffered_closed_get_impl(buffered *self); @@ -483,16 +473,6 @@ _io__Buffered_writable(PyObject *self, PyObject *Py_UNUSED(ignored)) return return_value; } -#if !defined(_io__Buffered_name_DOCSTR) -# define _io__Buffered_name_DOCSTR NULL -#endif -#if defined(_IO__BUFFERED_NAME_GETSETDEF) -# undef _IO__BUFFERED_NAME_GETSETDEF -# define _IO__BUFFERED_NAME_GETSETDEF {"name", (getter)_io__Buffered_name_get, (setter)_io__Buffered_name_set, _io__Buffered_name_DOCSTR}, -#else -# define _IO__BUFFERED_NAME_GETSETDEF {"name", (getter)_io__Buffered_name_get, NULL, _io__Buffered_name_DOCSTR}, -#endif - static PyObject * _io__Buffered_name_get_impl(buffered *self); @@ -508,16 +488,6 @@ _io__Buffered_name_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_io__Buffered_mode_DOCSTR) -# define _io__Buffered_mode_DOCSTR NULL -#endif -#if defined(_IO__BUFFERED_MODE_GETSETDEF) -# undef _IO__BUFFERED_MODE_GETSETDEF -# define _IO__BUFFERED_MODE_GETSETDEF {"mode", (getter)_io__Buffered_mode_get, (setter)_io__Buffered_mode_set, _io__Buffered_mode_DOCSTR}, -#else -# define _IO__BUFFERED_MODE_GETSETDEF {"mode", (getter)_io__Buffered_mode_get, NULL, _io__Buffered_mode_DOCSTR}, -#endif - static PyObject * _io__Buffered_mode_get_impl(buffered *self); @@ -1265,4 +1235,10 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=3ee17211d2010462 input=a9049054013a1b77]*/ +#define _IO__BUFFERED_CLOSED_GETSETDEF {"closed", (getter)_io__Buffered_closed_get, (setter)NULL, NULL}, + +#define _IO__BUFFERED_NAME_GETSETDEF {"name", (getter)_io__Buffered_name_get, (setter)NULL, NULL}, + +#define _IO__BUFFERED_MODE_GETSETDEF {"mode", (getter)_io__Buffered_mode_get, (setter)NULL, NULL}, + +/*[clinic end generated code: output=cac02514680dfc60 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/stringio.c.h b/Modules/_io/clinic/stringio.c.h index d6d4afb9b63c62..e9c6c39dc64b04 100644 --- a/Modules/_io/clinic/stringio.c.h +++ b/Modules/_io/clinic/stringio.c.h @@ -477,16 +477,6 @@ _io_StringIO___setstate__(PyObject *self, PyObject *state) return return_value; } -#if !defined(_io_StringIO_closed_DOCSTR) -# define _io_StringIO_closed_DOCSTR NULL -#endif -#if defined(_IO_STRINGIO_CLOSED_GETSETDEF) -# undef _IO_STRINGIO_CLOSED_GETSETDEF -# define _IO_STRINGIO_CLOSED_GETSETDEF {"closed", (getter)_io_StringIO_closed_get, (setter)_io_StringIO_closed_set, _io_StringIO_closed_DOCSTR}, -#else -# define _IO_STRINGIO_CLOSED_GETSETDEF {"closed", (getter)_io_StringIO_closed_get, NULL, _io_StringIO_closed_DOCSTR}, -#endif - static PyObject * _io_StringIO_closed_get_impl(stringio *self); @@ -502,16 +492,6 @@ _io_StringIO_closed_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_io_StringIO_line_buffering_DOCSTR) -# define _io_StringIO_line_buffering_DOCSTR NULL -#endif -#if defined(_IO_STRINGIO_LINE_BUFFERING_GETSETDEF) -# undef _IO_STRINGIO_LINE_BUFFERING_GETSETDEF -# define _IO_STRINGIO_LINE_BUFFERING_GETSETDEF {"line_buffering", (getter)_io_StringIO_line_buffering_get, (setter)_io_StringIO_line_buffering_set, _io_StringIO_line_buffering_DOCSTR}, -#else -# define _IO_STRINGIO_LINE_BUFFERING_GETSETDEF {"line_buffering", (getter)_io_StringIO_line_buffering_get, NULL, _io_StringIO_line_buffering_DOCSTR}, -#endif - static PyObject * _io_StringIO_line_buffering_get_impl(stringio *self); @@ -527,16 +507,6 @@ _io_StringIO_line_buffering_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_io_StringIO_newlines_DOCSTR) -# define _io_StringIO_newlines_DOCSTR NULL -#endif -#if defined(_IO_STRINGIO_NEWLINES_GETSETDEF) -# undef _IO_STRINGIO_NEWLINES_GETSETDEF -# define _IO_STRINGIO_NEWLINES_GETSETDEF {"newlines", (getter)_io_StringIO_newlines_get, (setter)_io_StringIO_newlines_set, _io_StringIO_newlines_DOCSTR}, -#else -# define _IO_STRINGIO_NEWLINES_GETSETDEF {"newlines", (getter)_io_StringIO_newlines_get, NULL, _io_StringIO_newlines_DOCSTR}, -#endif - static PyObject * _io_StringIO_newlines_get_impl(stringio *self); @@ -551,4 +521,10 @@ _io_StringIO_newlines_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -/*[clinic end generated code: output=730c34b2a6c0500b input=a9049054013a1b77]*/ +#define _IO_STRINGIO_CLOSED_GETSETDEF {"closed", (getter)_io_StringIO_closed_get, (setter)NULL, NULL}, + +#define _IO_STRINGIO_LINE_BUFFERING_GETSETDEF {"line_buffering", (getter)_io_StringIO_line_buffering_get, (setter)NULL, NULL}, + +#define _IO_STRINGIO_NEWLINES_GETSETDEF {"newlines", (getter)_io_StringIO_newlines_get, (setter)NULL, NULL}, + +/*[clinic end generated code: output=6fa0c0dd69543304 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index 10d0f1390cccbb..f782ec19714663 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -209,20 +209,6 @@ PyDoc_STRVAR(_io__TextIOBase_encoding__doc__, "Encoding of the text stream.\n" "\n" "Subclasses should override."); -#if defined(_io__TextIOBase_encoding_DOCSTR) -# undef _io__TextIOBase_encoding_DOCSTR -#endif -#define _io__TextIOBase_encoding_DOCSTR _io__TextIOBase_encoding__doc__ - -#if !defined(_io__TextIOBase_encoding_DOCSTR) -# define _io__TextIOBase_encoding_DOCSTR NULL -#endif -#if defined(_IO__TEXTIOBASE_ENCODING_GETSETDEF) -# undef _IO__TEXTIOBASE_ENCODING_GETSETDEF -# define _IO__TEXTIOBASE_ENCODING_GETSETDEF {"encoding", (getter)_io__TextIOBase_encoding_get, (setter)_io__TextIOBase_encoding_set, _io__TextIOBase_encoding_DOCSTR}, -#else -# define _IO__TEXTIOBASE_ENCODING_GETSETDEF {"encoding", (getter)_io__TextIOBase_encoding_get, NULL, _io__TextIOBase_encoding_DOCSTR}, -#endif static PyObject * _io__TextIOBase_encoding_get_impl(PyObject *self); @@ -239,20 +225,6 @@ PyDoc_STRVAR(_io__TextIOBase_newlines__doc__, "Only line endings translated during reading are considered.\n" "\n" "Subclasses should override."); -#if defined(_io__TextIOBase_newlines_DOCSTR) -# undef _io__TextIOBase_newlines_DOCSTR -#endif -#define _io__TextIOBase_newlines_DOCSTR _io__TextIOBase_newlines__doc__ - -#if !defined(_io__TextIOBase_newlines_DOCSTR) -# define _io__TextIOBase_newlines_DOCSTR NULL -#endif -#if defined(_IO__TEXTIOBASE_NEWLINES_GETSETDEF) -# undef _IO__TEXTIOBASE_NEWLINES_GETSETDEF -# define _IO__TEXTIOBASE_NEWLINES_GETSETDEF {"newlines", (getter)_io__TextIOBase_newlines_get, (setter)_io__TextIOBase_newlines_set, _io__TextIOBase_newlines_DOCSTR}, -#else -# define _IO__TEXTIOBASE_NEWLINES_GETSETDEF {"newlines", (getter)_io__TextIOBase_newlines_get, NULL, _io__TextIOBase_newlines_DOCSTR}, -#endif static PyObject * _io__TextIOBase_newlines_get_impl(PyObject *self); @@ -267,20 +239,6 @@ PyDoc_STRVAR(_io__TextIOBase_errors__doc__, "The error setting of the decoder or encoder.\n" "\n" "Subclasses should override."); -#if defined(_io__TextIOBase_errors_DOCSTR) -# undef _io__TextIOBase_errors_DOCSTR -#endif -#define _io__TextIOBase_errors_DOCSTR _io__TextIOBase_errors__doc__ - -#if !defined(_io__TextIOBase_errors_DOCSTR) -# define _io__TextIOBase_errors_DOCSTR NULL -#endif -#if defined(_IO__TEXTIOBASE_ERRORS_GETSETDEF) -# undef _IO__TEXTIOBASE_ERRORS_GETSETDEF -# define _IO__TEXTIOBASE_ERRORS_GETSETDEF {"errors", (getter)_io__TextIOBase_errors_get, (setter)_io__TextIOBase_errors_set, _io__TextIOBase_errors_DOCSTR}, -#else -# define _IO__TEXTIOBASE_ERRORS_GETSETDEF {"errors", (getter)_io__TextIOBase_errors_get, NULL, _io__TextIOBase_errors_DOCSTR}, -#endif static PyObject * _io__TextIOBase_errors_get_impl(PyObject *self); @@ -1182,16 +1140,6 @@ _io_TextIOWrapper_close(PyObject *self, PyObject *Py_UNUSED(ignored)) return return_value; } -#if !defined(_io_TextIOWrapper_name_DOCSTR) -# define _io_TextIOWrapper_name_DOCSTR NULL -#endif -#if defined(_IO_TEXTIOWRAPPER_NAME_GETSETDEF) -# undef _IO_TEXTIOWRAPPER_NAME_GETSETDEF -# define _IO_TEXTIOWRAPPER_NAME_GETSETDEF {"name", (getter)_io_TextIOWrapper_name_get, (setter)_io_TextIOWrapper_name_set, _io_TextIOWrapper_name_DOCSTR}, -#else -# define _IO_TEXTIOWRAPPER_NAME_GETSETDEF {"name", (getter)_io_TextIOWrapper_name_get, NULL, _io_TextIOWrapper_name_DOCSTR}, -#endif - static PyObject * _io_TextIOWrapper_name_get_impl(textio *self); @@ -1207,16 +1155,6 @@ _io_TextIOWrapper_name_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_io_TextIOWrapper_closed_DOCSTR) -# define _io_TextIOWrapper_closed_DOCSTR NULL -#endif -#if defined(_IO_TEXTIOWRAPPER_CLOSED_GETSETDEF) -# undef _IO_TEXTIOWRAPPER_CLOSED_GETSETDEF -# define _IO_TEXTIOWRAPPER_CLOSED_GETSETDEF {"closed", (getter)_io_TextIOWrapper_closed_get, (setter)_io_TextIOWrapper_closed_set, _io_TextIOWrapper_closed_DOCSTR}, -#else -# define _IO_TEXTIOWRAPPER_CLOSED_GETSETDEF {"closed", (getter)_io_TextIOWrapper_closed_get, NULL, _io_TextIOWrapper_closed_DOCSTR}, -#endif - static PyObject * _io_TextIOWrapper_closed_get_impl(textio *self); @@ -1232,16 +1170,6 @@ _io_TextIOWrapper_closed_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_io_TextIOWrapper_newlines_DOCSTR) -# define _io_TextIOWrapper_newlines_DOCSTR NULL -#endif -#if defined(_IO_TEXTIOWRAPPER_NEWLINES_GETSETDEF) -# undef _IO_TEXTIOWRAPPER_NEWLINES_GETSETDEF -# define _IO_TEXTIOWRAPPER_NEWLINES_GETSETDEF {"newlines", (getter)_io_TextIOWrapper_newlines_get, (setter)_io_TextIOWrapper_newlines_set, _io_TextIOWrapper_newlines_DOCSTR}, -#else -# define _IO_TEXTIOWRAPPER_NEWLINES_GETSETDEF {"newlines", (getter)_io_TextIOWrapper_newlines_get, NULL, _io_TextIOWrapper_newlines_DOCSTR}, -#endif - static PyObject * _io_TextIOWrapper_newlines_get_impl(textio *self); @@ -1257,16 +1185,6 @@ _io_TextIOWrapper_newlines_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_io_TextIOWrapper_errors_DOCSTR) -# define _io_TextIOWrapper_errors_DOCSTR NULL -#endif -#if defined(_IO_TEXTIOWRAPPER_ERRORS_GETSETDEF) -# undef _IO_TEXTIOWRAPPER_ERRORS_GETSETDEF -# define _IO_TEXTIOWRAPPER_ERRORS_GETSETDEF {"errors", (getter)_io_TextIOWrapper_errors_get, (setter)_io_TextIOWrapper_errors_set, _io_TextIOWrapper_errors_DOCSTR}, -#else -# define _IO_TEXTIOWRAPPER_ERRORS_GETSETDEF {"errors", (getter)_io_TextIOWrapper_errors_get, NULL, _io_TextIOWrapper_errors_DOCSTR}, -#endif - static PyObject * _io_TextIOWrapper_errors_get_impl(textio *self); @@ -1282,16 +1200,6 @@ _io_TextIOWrapper_errors_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_io_TextIOWrapper__CHUNK_SIZE_DOCSTR) -# define _io_TextIOWrapper__CHUNK_SIZE_DOCSTR NULL -#endif -#if defined(_IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF) -# undef _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF -# define _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF {"_CHUNK_SIZE", (getter)_io_TextIOWrapper__CHUNK_SIZE_get, (setter)_io_TextIOWrapper__CHUNK_SIZE_set, _io_TextIOWrapper__CHUNK_SIZE_DOCSTR}, -#else -# define _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF {"_CHUNK_SIZE", (getter)_io_TextIOWrapper__CHUNK_SIZE_get, NULL, _io_TextIOWrapper__CHUNK_SIZE_DOCSTR}, -#endif - static PyObject * _io_TextIOWrapper__CHUNK_SIZE_get_impl(textio *self); @@ -1307,30 +1215,22 @@ _io_TextIOWrapper__CHUNK_SIZE_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_io_TextIOWrapper__CHUNK_SIZE_DOCSTR) -# define _io_TextIOWrapper__CHUNK_SIZE_DOCSTR NULL -#endif -#if defined(_IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF) -# undef _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF -# define _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF {"_CHUNK_SIZE", (getter)_io_TextIOWrapper__CHUNK_SIZE_get, (setter)_io_TextIOWrapper__CHUNK_SIZE_set, _io_TextIOWrapper__CHUNK_SIZE_DOCSTR}, -#else -# define _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF {"_CHUNK_SIZE", NULL, (setter)_io_TextIOWrapper__CHUNK_SIZE_set, NULL}, -#endif - static int _io_TextIOWrapper__CHUNK_SIZE_set_impl(textio *self, PyObject *value); static int -_io_TextIOWrapper__CHUNK_SIZE_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_io_TextIOWrapper__CHUNK_SIZE_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute '_CHUNK_SIZE' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = _io_TextIOWrapper__CHUNK_SIZE_set_impl((textio *)self, value); Py_END_CRITICAL_SECTION(); @@ -1338,16 +1238,6 @@ _io_TextIOWrapper__CHUNK_SIZE_set(PyObject *self, PyObject *value, void *Py_UNUS return return_value; } -#if !defined(_io_TextIOWrapper_buffer_DOCSTR) -# define _io_TextIOWrapper_buffer_DOCSTR NULL -#endif -#if defined(_IO_TEXTIOWRAPPER_BUFFER_GETSETDEF) -# undef _IO_TEXTIOWRAPPER_BUFFER_GETSETDEF -# define _IO_TEXTIOWRAPPER_BUFFER_GETSETDEF {"buffer", (getter)_io_TextIOWrapper_buffer_get, (setter)_io_TextIOWrapper_buffer_set, _io_TextIOWrapper_buffer_DOCSTR}, -#else -# define _IO_TEXTIOWRAPPER_BUFFER_GETSETDEF {"buffer", (getter)_io_TextIOWrapper_buffer_get, NULL, _io_TextIOWrapper_buffer_DOCSTR}, -#endif - static PyObject * _io_TextIOWrapper_buffer_get_impl(textio *self); @@ -1362,4 +1252,22 @@ _io_TextIOWrapper_buffer_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -/*[clinic end generated code: output=e93032a0691ff0e4 input=a9049054013a1b77]*/ +#define _IO__TEXTIOBASE_ENCODING_GETSETDEF {"encoding", (getter)_io__TextIOBase_encoding_get, (setter)NULL, _io__TextIOBase_encoding__doc__}, + +#define _IO__TEXTIOBASE_NEWLINES_GETSETDEF {"newlines", (getter)_io__TextIOBase_newlines_get, (setter)NULL, _io__TextIOBase_newlines__doc__}, + +#define _IO__TEXTIOBASE_ERRORS_GETSETDEF {"errors", (getter)_io__TextIOBase_errors_get, (setter)NULL, _io__TextIOBase_errors__doc__}, + +#define _IO_TEXTIOWRAPPER_NAME_GETSETDEF {"name", (getter)_io_TextIOWrapper_name_get, (setter)NULL, NULL}, + +#define _IO_TEXTIOWRAPPER_CLOSED_GETSETDEF {"closed", (getter)_io_TextIOWrapper_closed_get, (setter)NULL, NULL}, + +#define _IO_TEXTIOWRAPPER_NEWLINES_GETSETDEF {"newlines", (getter)_io_TextIOWrapper_newlines_get, (setter)NULL, NULL}, + +#define _IO_TEXTIOWRAPPER_ERRORS_GETSETDEF {"errors", (getter)_io_TextIOWrapper_errors_get, (setter)NULL, NULL}, + +#define _IO_TEXTIOWRAPPER__CHUNK_SIZE_GETSETDEF {"_CHUNK_SIZE", (getter)_io_TextIOWrapper__CHUNK_SIZE_get, (setter)_io_TextIOWrapper__CHUNK_SIZE_set, NULL}, + +#define _IO_TEXTIOWRAPPER_BUFFER_GETSETDEF {"buffer", (getter)_io_TextIOWrapper_buffer_get, (setter)NULL, NULL}, + +/*[clinic end generated code: output=72ad4f1b23cc606f input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index 689466b1c2b85a..fcefc6535393b2 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -330,16 +330,6 @@ pysqlite_cursor_close(PyObject *self, PyObject *Py_UNUSED(ignored)) return pysqlite_cursor_close_impl((pysqlite_Cursor *)self); } -#if !defined(_sqlite3_Cursor_arraysize_DOCSTR) -# define _sqlite3_Cursor_arraysize_DOCSTR NULL -#endif -#if defined(_SQLITE3_CURSOR_ARRAYSIZE_GETSETDEF) -# undef _SQLITE3_CURSOR_ARRAYSIZE_GETSETDEF -# define _SQLITE3_CURSOR_ARRAYSIZE_GETSETDEF {"arraysize", (getter)_sqlite3_Cursor_arraysize_get, (setter)_sqlite3_Cursor_arraysize_set, _sqlite3_Cursor_arraysize_DOCSTR}, -#else -# define _SQLITE3_CURSOR_ARRAYSIZE_GETSETDEF {"arraysize", (getter)_sqlite3_Cursor_arraysize_get, NULL, _sqlite3_Cursor_arraysize_DOCSTR}, -#endif - static PyObject * _sqlite3_Cursor_arraysize_get_impl(pysqlite_Cursor *self); @@ -349,32 +339,29 @@ _sqlite3_Cursor_arraysize_get(PyObject *self, void *Py_UNUSED(context)) return _sqlite3_Cursor_arraysize_get_impl((pysqlite_Cursor *)self); } -#if !defined(_sqlite3_Cursor_arraysize_DOCSTR) -# define _sqlite3_Cursor_arraysize_DOCSTR NULL -#endif -#if defined(_SQLITE3_CURSOR_ARRAYSIZE_GETSETDEF) -# undef _SQLITE3_CURSOR_ARRAYSIZE_GETSETDEF -# define _SQLITE3_CURSOR_ARRAYSIZE_GETSETDEF {"arraysize", (getter)_sqlite3_Cursor_arraysize_get, (setter)_sqlite3_Cursor_arraysize_set, _sqlite3_Cursor_arraysize_DOCSTR}, -#else -# define _SQLITE3_CURSOR_ARRAYSIZE_GETSETDEF {"arraysize", NULL, (setter)_sqlite3_Cursor_arraysize_set, NULL}, -#endif - static int -_sqlite3_Cursor_arraysize_set_impl(pysqlite_Cursor *self, PyObject *value); +_sqlite3_Cursor_arraysize_set_impl(pysqlite_Cursor *self, uint32_t value); static int -_sqlite3_Cursor_arraysize_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_sqlite3_Cursor_arraysize_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + uint32_t value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'arraysize' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + if (!_PyLong_UInt32_Converter(arg, &value)) { + goto exit; + } return_value = _sqlite3_Cursor_arraysize_set_impl((pysqlite_Cursor *)self, value); +exit: return return_value; } -/*[clinic end generated code: output=e7b20358f8213fd7 input=a9049054013a1b77]*/ +#define _SQLITE3_CURSOR_ARRAYSIZE_GETSETDEF {"arraysize", (getter)_sqlite3_Cursor_arraysize_get, (setter)_sqlite3_Cursor_arraysize_set, NULL}, + +/*[clinic end generated code: output=e920343d84bd4976 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index dd4204ff267d0a..5c0ed26a3aabbe 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -1374,17 +1374,14 @@ _sqlite3_Cursor_arraysize_get_impl(pysqlite_Cursor *self) /*[clinic input] @setter _sqlite3.Cursor.arraysize + value: uint32 [clinic start generated code]*/ static int -_sqlite3_Cursor_arraysize_set_impl(pysqlite_Cursor *self, PyObject *value) -/*[clinic end generated code: output=af59a6b09f8cce6e input=ace48cb114e26060]*/ +_sqlite3_Cursor_arraysize_set_impl(pysqlite_Cursor *self, uint32_t value) +/*[clinic end generated code: output=465c2db6df904802 input=80234ca4ec5cfb7c]*/ { - uint32_t arraysize; - if (PyLong_AsUInt32(value, &arraysize) < 0) { - return -1; - } - self->arraysize = arraysize; + self->arraysize = value; return 0; } diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 7a780dce967c79..4fd8bf0ac3b957 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3946,12 +3946,12 @@ _ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self, /*[clinic input] @critical_section @getter -_ssl._SSLContext.verify_mode +_ssl._SSLContext.verify_mode -> int [clinic start generated code]*/ -static PyObject * +static int _ssl__SSLContext_verify_mode_get_impl(PySSLContext *self) -/*[clinic end generated code: output=3e788736cc7229bc input=7e3c7f4454121d0a]*/ +/*[clinic end generated code: output=f588c0dc5c0bc414 input=9f74370037133ac3]*/ { /* ignore SSL_VERIFY_CLIENT_ONCE and SSL_VERIFY_POST_HANDSHAKE */ int mask = (SSL_VERIFY_NONE | SSL_VERIFY_PEER | @@ -3959,72 +3959,69 @@ _ssl__SSLContext_verify_mode_get_impl(PySSLContext *self) int verify_mode = SSL_CTX_get_verify_mode(self->ctx); switch (verify_mode & mask) { case SSL_VERIFY_NONE: - return PyLong_FromLong(PY_SSL_CERT_NONE); + return PY_SSL_CERT_NONE; case SSL_VERIFY_PEER: - return PyLong_FromLong(PY_SSL_CERT_OPTIONAL); + return PY_SSL_CERT_OPTIONAL; case SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT: - return PyLong_FromLong(PY_SSL_CERT_REQUIRED); + return PY_SSL_CERT_REQUIRED; } PyErr_SetString(get_state_ctx(self)->PySSLErrorObject, "invalid return value from SSL_CTX_get_verify_mode"); - return NULL; + return -1; } /*[clinic input] @critical_section @setter _ssl._SSLContext.verify_mode + value: int [clinic start generated code]*/ static int -_ssl__SSLContext_verify_mode_set_impl(PySSLContext *self, PyObject *value) -/*[clinic end generated code: output=d698e16c58db3118 input=3ee60057c3a22378]*/ +_ssl__SSLContext_verify_mode_set_impl(PySSLContext *self, int value) +/*[clinic end generated code: output=5ca6ec88aa4faed0 input=cb53415e79047735]*/ { - int n; - if (!PyArg_Parse(value, "i", &n)) - return -1; - if (n == PY_SSL_CERT_NONE && self->check_hostname) { + if (value == PY_SSL_CERT_NONE && self->check_hostname) { PyErr_SetString(PyExc_ValueError, "Cannot set verify_mode to CERT_NONE when " "check_hostname is enabled."); return -1; } - return _set_verify_mode(self, n); + return _set_verify_mode(self, value); } /*[clinic input] @critical_section @getter -_ssl._SSLContext.verify_flags +_ssl._SSLContext.verify_flags -> unsigned_long [clinic start generated code]*/ -static PyObject * +static unsigned long _ssl__SSLContext_verify_flags_get_impl(PySSLContext *self) -/*[clinic end generated code: output=fbbf8ba28ad6e56e input=c1ec36d610b3f391]*/ +/*[clinic end generated code: output=65df79ad8808f85d input=8a60274c619c3d29]*/ { X509_VERIFY_PARAM *ssl_verification_params; - unsigned long flags; ssl_verification_params = SSL_CTX_get0_param(self->ctx); - flags = X509_VERIFY_PARAM_get_flags(ssl_verification_params); - return PyLong_FromUnsignedLong(flags); + return X509_VERIFY_PARAM_get_flags(ssl_verification_params); } /*[clinic input] @critical_section @setter _ssl._SSLContext.verify_flags + value: unsigned_long(bitwise=True) [clinic start generated code]*/ static int -_ssl__SSLContext_verify_flags_set_impl(PySSLContext *self, PyObject *value) -/*[clinic end generated code: output=a3e3b2a0ce6c2e99 input=b2a0c42583d4f34e]*/ +_ssl__SSLContext_verify_flags_set_impl(PySSLContext *self, + unsigned long value) +/*[clinic end generated code: output=3a0dc3da11d16fc0 input=45ca63f1bfe14386]*/ { X509_VERIFY_PARAM *ssl_verification_params; - unsigned long new_flags, flags, set, clear; + unsigned long new_flags = value; + unsigned long flags, set, clear; - if (!PyArg_Parse(value, "k", &new_flags)) - return -1; ssl_verification_params = SSL_CTX_get0_param(self->ctx); flags = X509_VERIFY_PARAM_get_flags(ssl_verification_params); clear = flags & ~new_flags; @@ -4214,15 +4211,14 @@ _ssl__SSLContext_num_tickets_get_impl(PySSLContext *self) @critical_section @setter _ssl._SSLContext.num_tickets + value: long [clinic start generated code]*/ static int -_ssl__SSLContext_num_tickets_set_impl(PySSLContext *self, PyObject *value) -/*[clinic end generated code: output=ced81b46f3beab09 input=6ef8067ac55607e7]*/ +_ssl__SSLContext_num_tickets_set_impl(PySSLContext *self, long value) +/*[clinic end generated code: output=c2c97071a729b0ff input=6f7531a9d9cd4570]*/ { - long num; - if (!PyArg_Parse(value, "l", &num)) - return -1; + long num = value; if (num < 0) { PyErr_SetString(PyExc_ValueError, "value must be non-negative"); return -1; @@ -4274,11 +4270,13 @@ _ssl__SSLContext_options_get_impl(PySSLContext *self) @critical_section @setter _ssl._SSLContext.options + value: unsigned_long_long [clinic start generated code]*/ static int -_ssl__SSLContext_options_set_impl(PySSLContext *self, PyObject *value) -/*[clinic end generated code: output=92ca34731ece5dbb input=2b94bf789e9ae5dd]*/ +_ssl__SSLContext_options_set_impl(PySSLContext *self, + unsigned long long value) +/*[clinic end generated code: output=9bf1e7bf9ab9c49b input=143105581d4dfc86]*/ { unsigned long long new_opts_arg; uint64_t new_opts, opts, clear, set; @@ -4287,9 +4285,7 @@ _ssl__SSLContext_options_set_impl(PySSLContext *self, PyObject *value) SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3 ); - if (!PyArg_Parse(value, "O&", _PyLong_UnsignedLongLong_Converter, &new_opts_arg)) { - return -1; - } + new_opts_arg = value; Py_BUILD_ASSERT(sizeof(new_opts) >= sizeof(new_opts_arg)); new_opts = (uint64_t)new_opts_arg; @@ -4315,36 +4311,32 @@ _ssl__SSLContext_options_set_impl(PySSLContext *self, PyObject *value) /*[clinic input] @critical_section @getter -_ssl._SSLContext._host_flags +_ssl._SSLContext._host_flags -> unsigned_int [clinic start generated code]*/ -static PyObject * +static unsigned int _ssl__SSLContext__host_flags_get_impl(PySSLContext *self) -/*[clinic end generated code: output=0f9db6654ce32582 input=8e3c49499eefd0e5]*/ +/*[clinic end generated code: output=86ddaf5eeea5f355 input=1ccf5ae9b37de139]*/ { X509_VERIFY_PARAM *ssl_verification_params; - unsigned int host_flags; ssl_verification_params = SSL_CTX_get0_param(self->ctx); - host_flags = X509_VERIFY_PARAM_get_hostflags(ssl_verification_params); - return PyLong_FromUnsignedLong(host_flags); + return X509_VERIFY_PARAM_get_hostflags(ssl_verification_params); } /*[clinic input] @critical_section @setter _ssl._SSLContext._host_flags + value: unsigned_int(bitwise=True) [clinic start generated code]*/ static int -_ssl__SSLContext__host_flags_set_impl(PySSLContext *self, PyObject *value) -/*[clinic end generated code: output=1ed6f4027aaf2e3e input=28caf1fb9c32f6cb]*/ +_ssl__SSLContext__host_flags_set_impl(PySSLContext *self, unsigned int value) +/*[clinic end generated code: output=9986c48e63e6ba3e input=36d1b89df2884d81]*/ { X509_VERIFY_PARAM *ssl_verification_params; - unsigned int new_flags = 0; - - if (!PyArg_Parse(value, "I", &new_flags)) - return -1; + unsigned int new_flags = value; ssl_verification_params = SSL_CTX_get0_param(self->ctx); X509_VERIFY_PARAM_set_hostflags(ssl_verification_params, new_flags); @@ -4354,29 +4346,28 @@ _ssl__SSLContext__host_flags_set_impl(PySSLContext *self, PyObject *value) /*[clinic input] @critical_section @getter -_ssl._SSLContext.check_hostname +_ssl._SSLContext.check_hostname -> bool [clinic start generated code]*/ -static PyObject * +static int _ssl__SSLContext_check_hostname_get_impl(PySSLContext *self) -/*[clinic end generated code: output=e046d6eeefc76063 input=1b8341e705f9ecf5]*/ +/*[clinic end generated code: output=a5772c7e90e32c1d input=d5ae97abc5e0fb0b]*/ { - return PyBool_FromLong(self->check_hostname); + return self->check_hostname; } /*[clinic input] @critical_section @setter _ssl._SSLContext.check_hostname + value: bool [clinic start generated code]*/ static int -_ssl__SSLContext_check_hostname_set_impl(PySSLContext *self, PyObject *value) -/*[clinic end generated code: output=0e767b4784e7dc3f input=e6a771cb5919f74d]*/ +_ssl__SSLContext_check_hostname_set_impl(PySSLContext *self, int value) +/*[clinic end generated code: output=323bb94d7b54d471 input=9134aa868194a6c3]*/ { - int check_hostname; - if (!PyArg_Parse(value, "p", &check_hostname)) - return -1; + int check_hostname = value; int verify_mode = check_hostname ? SSL_CTX_get_verify_mode(self->ctx) : 0; if (check_hostname && verify_mode == SSL_VERIFY_NONE) { diff --git a/Modules/_zstd/clinic/decompressor.c.h b/Modules/_zstd/clinic/decompressor.c.h index fe3b76b8bb369d..83431363621ad6 100644 --- a/Modules/_zstd/clinic/decompressor.c.h +++ b/Modules/_zstd/clinic/decompressor.c.h @@ -93,20 +93,6 @@ PyDoc_STRVAR(_zstd_ZstdDecompressor_unused_data__doc__, "When ZstdDecompressor object stops after a frame is\n" "decompressed, unused input data after the frame. Otherwise this\n" "will be b\'\'."); -#if defined(_zstd_ZstdDecompressor_unused_data_DOCSTR) -# undef _zstd_ZstdDecompressor_unused_data_DOCSTR -#endif -#define _zstd_ZstdDecompressor_unused_data_DOCSTR _zstd_ZstdDecompressor_unused_data__doc__ - -#if !defined(_zstd_ZstdDecompressor_unused_data_DOCSTR) -# define _zstd_ZstdDecompressor_unused_data_DOCSTR NULL -#endif -#if defined(_ZSTD_ZSTDDECOMPRESSOR_UNUSED_DATA_GETSETDEF) -# undef _ZSTD_ZSTDDECOMPRESSOR_UNUSED_DATA_GETSETDEF -# define _ZSTD_ZSTDDECOMPRESSOR_UNUSED_DATA_GETSETDEF {"unused_data", (getter)_zstd_ZstdDecompressor_unused_data_get, (setter)_zstd_ZstdDecompressor_unused_data_set, _zstd_ZstdDecompressor_unused_data_DOCSTR}, -#else -# define _ZSTD_ZSTDDECOMPRESSOR_UNUSED_DATA_GETSETDEF {"unused_data", (getter)_zstd_ZstdDecompressor_unused_data_get, NULL, _zstd_ZstdDecompressor_unused_data_DOCSTR}, -#endif static PyObject * _zstd_ZstdDecompressor_unused_data_get_impl(ZstdDecompressor *self); @@ -222,4 +208,6 @@ _zstd_ZstdDecompressor_decompress(PyObject *self, PyObject *const *args, Py_ssiz return return_value; } -/*[clinic end generated code: output=70bc308e86463751 input=a9049054013a1b77]*/ +#define _ZSTD_ZSTDDECOMPRESSOR_UNUSED_DATA_GETSETDEF {"unused_data", (getter)_zstd_ZstdDecompressor_unused_data_get, (setter)NULL, _zstd_ZstdDecompressor_unused_data__doc__}, + +/*[clinic end generated code: output=91b84afb07b1188c input=a9049054013a1b77]*/ diff --git a/Modules/_zstd/clinic/zstddict.c.h b/Modules/_zstd/clinic/zstddict.c.h index 18b049e3cbe37e..30a1ed8ea9bfa8 100644 --- a/Modules/_zstd/clinic/zstddict.c.h +++ b/Modules/_zstd/clinic/zstddict.c.h @@ -95,20 +95,6 @@ _zstd_ZstdDict_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyDoc_STRVAR(_zstd_ZstdDict_dict_content__doc__, "The content of a Zstandard dictionary, as a bytes object."); -#if defined(_zstd_ZstdDict_dict_content_DOCSTR) -# undef _zstd_ZstdDict_dict_content_DOCSTR -#endif -#define _zstd_ZstdDict_dict_content_DOCSTR _zstd_ZstdDict_dict_content__doc__ - -#if !defined(_zstd_ZstdDict_dict_content_DOCSTR) -# define _zstd_ZstdDict_dict_content_DOCSTR NULL -#endif -#if defined(_ZSTD_ZSTDDICT_DICT_CONTENT_GETSETDEF) -# undef _ZSTD_ZSTDDICT_DICT_CONTENT_GETSETDEF -# define _ZSTD_ZSTDDICT_DICT_CONTENT_GETSETDEF {"dict_content", (getter)_zstd_ZstdDict_dict_content_get, (setter)_zstd_ZstdDict_dict_content_set, _zstd_ZstdDict_dict_content_DOCSTR}, -#else -# define _ZSTD_ZSTDDICT_DICT_CONTENT_GETSETDEF {"dict_content", (getter)_zstd_ZstdDict_dict_content_get, NULL, _zstd_ZstdDict_dict_content_DOCSTR}, -#endif static PyObject * _zstd_ZstdDict_dict_content_get_impl(ZstdDict *self); @@ -131,20 +117,6 @@ PyDoc_STRVAR(_zstd_ZstdDict_as_digested_dict__doc__, " level. It\'s faster when loading again a digested dictionary with\n" " the same compression level.\n" "3. No need to use this for decompression."); -#if defined(_zstd_ZstdDict_as_digested_dict_DOCSTR) -# undef _zstd_ZstdDict_as_digested_dict_DOCSTR -#endif -#define _zstd_ZstdDict_as_digested_dict_DOCSTR _zstd_ZstdDict_as_digested_dict__doc__ - -#if !defined(_zstd_ZstdDict_as_digested_dict_DOCSTR) -# define _zstd_ZstdDict_as_digested_dict_DOCSTR NULL -#endif -#if defined(_ZSTD_ZSTDDICT_AS_DIGESTED_DICT_GETSETDEF) -# undef _ZSTD_ZSTDDICT_AS_DIGESTED_DICT_GETSETDEF -# define _ZSTD_ZSTDDICT_AS_DIGESTED_DICT_GETSETDEF {"as_digested_dict", (getter)_zstd_ZstdDict_as_digested_dict_get, (setter)_zstd_ZstdDict_as_digested_dict_set, _zstd_ZstdDict_as_digested_dict_DOCSTR}, -#else -# define _ZSTD_ZSTDDICT_AS_DIGESTED_DICT_GETSETDEF {"as_digested_dict", (getter)_zstd_ZstdDict_as_digested_dict_get, NULL, _zstd_ZstdDict_as_digested_dict_DOCSTR}, -#endif static PyObject * _zstd_ZstdDict_as_digested_dict_get_impl(ZstdDict *self); @@ -166,20 +138,6 @@ PyDoc_STRVAR(_zstd_ZstdDict_as_undigested_dict__doc__, "2. Loading an undigested dictionary is costly. If load an undigested\n" " dictionary multiple times, consider reusing a compressor object.\n" "3. No need to use this for decompression."); -#if defined(_zstd_ZstdDict_as_undigested_dict_DOCSTR) -# undef _zstd_ZstdDict_as_undigested_dict_DOCSTR -#endif -#define _zstd_ZstdDict_as_undigested_dict_DOCSTR _zstd_ZstdDict_as_undigested_dict__doc__ - -#if !defined(_zstd_ZstdDict_as_undigested_dict_DOCSTR) -# define _zstd_ZstdDict_as_undigested_dict_DOCSTR NULL -#endif -#if defined(_ZSTD_ZSTDDICT_AS_UNDIGESTED_DICT_GETSETDEF) -# undef _ZSTD_ZSTDDICT_AS_UNDIGESTED_DICT_GETSETDEF -# define _ZSTD_ZSTDDICT_AS_UNDIGESTED_DICT_GETSETDEF {"as_undigested_dict", (getter)_zstd_ZstdDict_as_undigested_dict_get, (setter)_zstd_ZstdDict_as_undigested_dict_set, _zstd_ZstdDict_as_undigested_dict_DOCSTR}, -#else -# define _ZSTD_ZSTDDICT_AS_UNDIGESTED_DICT_GETSETDEF {"as_undigested_dict", (getter)_zstd_ZstdDict_as_undigested_dict_get, NULL, _zstd_ZstdDict_as_undigested_dict_DOCSTR}, -#endif static PyObject * _zstd_ZstdDict_as_undigested_dict_get_impl(ZstdDict *self); @@ -201,20 +159,6 @@ PyDoc_STRVAR(_zstd_ZstdDict_as_prefix__doc__, "2. It only works for the first frame, then the\n" " compressor/decompressor will return to no prefix state.\n" "3. When decompressing, must use the same prefix as when compressing."); -#if defined(_zstd_ZstdDict_as_prefix_DOCSTR) -# undef _zstd_ZstdDict_as_prefix_DOCSTR -#endif -#define _zstd_ZstdDict_as_prefix_DOCSTR _zstd_ZstdDict_as_prefix__doc__ - -#if !defined(_zstd_ZstdDict_as_prefix_DOCSTR) -# define _zstd_ZstdDict_as_prefix_DOCSTR NULL -#endif -#if defined(_ZSTD_ZSTDDICT_AS_PREFIX_GETSETDEF) -# undef _ZSTD_ZSTDDICT_AS_PREFIX_GETSETDEF -# define _ZSTD_ZSTDDICT_AS_PREFIX_GETSETDEF {"as_prefix", (getter)_zstd_ZstdDict_as_prefix_get, (setter)_zstd_ZstdDict_as_prefix_set, _zstd_ZstdDict_as_prefix_DOCSTR}, -#else -# define _ZSTD_ZSTDDICT_AS_PREFIX_GETSETDEF {"as_prefix", (getter)_zstd_ZstdDict_as_prefix_get, NULL, _zstd_ZstdDict_as_prefix_DOCSTR}, -#endif static PyObject * _zstd_ZstdDict_as_prefix_get_impl(ZstdDict *self); @@ -224,4 +168,12 @@ _zstd_ZstdDict_as_prefix_get(PyObject *self, void *Py_UNUSED(context)) { return _zstd_ZstdDict_as_prefix_get_impl((ZstdDict *)self); } -/*[clinic end generated code: output=49b66061b4fcdb5f input=a9049054013a1b77]*/ +#define _ZSTD_ZSTDDICT_DICT_CONTENT_GETSETDEF {"dict_content", (getter)_zstd_ZstdDict_dict_content_get, (setter)NULL, _zstd_ZstdDict_dict_content__doc__}, + +#define _ZSTD_ZSTDDICT_AS_DIGESTED_DICT_GETSETDEF {"as_digested_dict", (getter)_zstd_ZstdDict_as_digested_dict_get, (setter)NULL, _zstd_ZstdDict_as_digested_dict__doc__}, + +#define _ZSTD_ZSTDDICT_AS_UNDIGESTED_DICT_GETSETDEF {"as_undigested_dict", (getter)_zstd_ZstdDict_as_undigested_dict_get, (setter)NULL, _zstd_ZstdDict_as_undigested_dict__doc__}, + +#define _ZSTD_ZSTDDICT_AS_PREFIX_GETSETDEF {"as_prefix", (getter)_zstd_ZstdDict_as_prefix_get, (setter)NULL, _zstd_ZstdDict_as_prefix__doc__}, + +/*[clinic end generated code: output=aa4d4b8fd985ae08 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index 14cf5eebc5eec7..6932dc3ccf17e0 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -516,16 +516,6 @@ _asyncio_Future_get_loop(PyObject *self, PyTypeObject *cls, PyObject *const *arg return return_value; } -#if !defined(_asyncio_Future__asyncio_awaited_by_DOCSTR) -# define _asyncio_Future__asyncio_awaited_by_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__ASYNCIO_AWAITED_BY_GETSETDEF) -# undef _ASYNCIO_FUTURE__ASYNCIO_AWAITED_BY_GETSETDEF -# define _ASYNCIO_FUTURE__ASYNCIO_AWAITED_BY_GETSETDEF {"_asyncio_awaited_by", (getter)_asyncio_Future__asyncio_awaited_by_get, (setter)_asyncio_Future__asyncio_awaited_by_set, _asyncio_Future__asyncio_awaited_by_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__ASYNCIO_AWAITED_BY_GETSETDEF {"_asyncio_awaited_by", (getter)_asyncio_Future__asyncio_awaited_by_get, NULL, _asyncio_Future__asyncio_awaited_by_DOCSTR}, -#endif - static PyObject * _asyncio_Future__asyncio_awaited_by_get_impl(FutureObj *self); @@ -541,129 +531,102 @@ _asyncio_Future__asyncio_awaited_by_get(PyObject *self, void *Py_UNUSED(context) return return_value; } -#if !defined(_asyncio_Future__asyncio_future_blocking_DOCSTR) -# define _asyncio_Future__asyncio_future_blocking_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__ASYNCIO_FUTURE_BLOCKING_GETSETDEF) -# undef _ASYNCIO_FUTURE__ASYNCIO_FUTURE_BLOCKING_GETSETDEF -# define _ASYNCIO_FUTURE__ASYNCIO_FUTURE_BLOCKING_GETSETDEF {"_asyncio_future_blocking", (getter)_asyncio_Future__asyncio_future_blocking_get, (setter)_asyncio_Future__asyncio_future_blocking_set, _asyncio_Future__asyncio_future_blocking_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__ASYNCIO_FUTURE_BLOCKING_GETSETDEF {"_asyncio_future_blocking", (getter)_asyncio_Future__asyncio_future_blocking_get, NULL, _asyncio_Future__asyncio_future_blocking_DOCSTR}, -#endif - -static PyObject * +static int _asyncio_Future__asyncio_future_blocking_get_impl(FutureObj *self); static PyObject * _asyncio_Future__asyncio_future_blocking_get(PyObject *self, void *Py_UNUSED(context)) { PyObject *return_value = NULL; + int _return_value; Py_BEGIN_CRITICAL_SECTION(self); - return_value = _asyncio_Future__asyncio_future_blocking_get_impl((FutureObj *)self); + _return_value = _asyncio_Future__asyncio_future_blocking_get_impl((FutureObj *)self); Py_END_CRITICAL_SECTION(); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); +exit: return return_value; } -#if !defined(_asyncio_Future__asyncio_future_blocking_DOCSTR) -# define _asyncio_Future__asyncio_future_blocking_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__ASYNCIO_FUTURE_BLOCKING_GETSETDEF) -# undef _ASYNCIO_FUTURE__ASYNCIO_FUTURE_BLOCKING_GETSETDEF -# define _ASYNCIO_FUTURE__ASYNCIO_FUTURE_BLOCKING_GETSETDEF {"_asyncio_future_blocking", (getter)_asyncio_Future__asyncio_future_blocking_get, (setter)_asyncio_Future__asyncio_future_blocking_set, _asyncio_Future__asyncio_future_blocking_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__ASYNCIO_FUTURE_BLOCKING_GETSETDEF {"_asyncio_future_blocking", NULL, (setter)_asyncio_Future__asyncio_future_blocking_set, NULL}, -#endif - static int -_asyncio_Future__asyncio_future_blocking_set_impl(FutureObj *self, - PyObject *value); +_asyncio_Future__asyncio_future_blocking_set_impl(FutureObj *self, int value); static int -_asyncio_Future__asyncio_future_blocking_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_asyncio_Future__asyncio_future_blocking_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + int value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute '_asyncio_future_blocking' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = PyObject_IsTrue(arg); + if (value < 0) { + goto exit; + } Py_BEGIN_CRITICAL_SECTION(self); return_value = _asyncio_Future__asyncio_future_blocking_set_impl((FutureObj *)self, value); Py_END_CRITICAL_SECTION(); +exit: return return_value; } -#if !defined(_asyncio_Future__log_traceback_DOCSTR) -# define _asyncio_Future__log_traceback_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__LOG_TRACEBACK_GETSETDEF) -# undef _ASYNCIO_FUTURE__LOG_TRACEBACK_GETSETDEF -# define _ASYNCIO_FUTURE__LOG_TRACEBACK_GETSETDEF {"_log_traceback", (getter)_asyncio_Future__log_traceback_get, (setter)_asyncio_Future__log_traceback_set, _asyncio_Future__log_traceback_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__LOG_TRACEBACK_GETSETDEF {"_log_traceback", (getter)_asyncio_Future__log_traceback_get, NULL, _asyncio_Future__log_traceback_DOCSTR}, -#endif - -static PyObject * +static int _asyncio_Future__log_traceback_get_impl(FutureObj *self); static PyObject * _asyncio_Future__log_traceback_get(PyObject *self, void *Py_UNUSED(context)) { PyObject *return_value = NULL; + int _return_value; Py_BEGIN_CRITICAL_SECTION(self); - return_value = _asyncio_Future__log_traceback_get_impl((FutureObj *)self); + _return_value = _asyncio_Future__log_traceback_get_impl((FutureObj *)self); Py_END_CRITICAL_SECTION(); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); +exit: return return_value; } -#if !defined(_asyncio_Future__log_traceback_DOCSTR) -# define _asyncio_Future__log_traceback_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__LOG_TRACEBACK_GETSETDEF) -# undef _ASYNCIO_FUTURE__LOG_TRACEBACK_GETSETDEF -# define _ASYNCIO_FUTURE__LOG_TRACEBACK_GETSETDEF {"_log_traceback", (getter)_asyncio_Future__log_traceback_get, (setter)_asyncio_Future__log_traceback_set, _asyncio_Future__log_traceback_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__LOG_TRACEBACK_GETSETDEF {"_log_traceback", NULL, (setter)_asyncio_Future__log_traceback_set, NULL}, -#endif - static int -_asyncio_Future__log_traceback_set_impl(FutureObj *self, PyObject *value); +_asyncio_Future__log_traceback_set_impl(FutureObj *self, int value); static int -_asyncio_Future__log_traceback_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_asyncio_Future__log_traceback_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + int value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute '_log_traceback' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = PyObject_IsTrue(arg); + if (value < 0) { + goto exit; + } Py_BEGIN_CRITICAL_SECTION(self); return_value = _asyncio_Future__log_traceback_set_impl((FutureObj *)self, value); Py_END_CRITICAL_SECTION(); +exit: return return_value; } -#if !defined(_asyncio_Future__loop_DOCSTR) -# define _asyncio_Future__loop_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__LOOP_GETSETDEF) -# undef _ASYNCIO_FUTURE__LOOP_GETSETDEF -# define _ASYNCIO_FUTURE__LOOP_GETSETDEF {"_loop", (getter)_asyncio_Future__loop_get, (setter)_asyncio_Future__loop_set, _asyncio_Future__loop_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__LOOP_GETSETDEF {"_loop", (getter)_asyncio_Future__loop_get, NULL, _asyncio_Future__loop_DOCSTR}, -#endif - static PyObject * _asyncio_Future__loop_get_impl(FutureObj *self); @@ -679,16 +642,6 @@ _asyncio_Future__loop_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_asyncio_Future__callbacks_DOCSTR) -# define _asyncio_Future__callbacks_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__CALLBACKS_GETSETDEF) -# undef _ASYNCIO_FUTURE__CALLBACKS_GETSETDEF -# define _ASYNCIO_FUTURE__CALLBACKS_GETSETDEF {"_callbacks", (getter)_asyncio_Future__callbacks_get, (setter)_asyncio_Future__callbacks_set, _asyncio_Future__callbacks_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__CALLBACKS_GETSETDEF {"_callbacks", (getter)_asyncio_Future__callbacks_get, NULL, _asyncio_Future__callbacks_DOCSTR}, -#endif - static PyObject * _asyncio_Future__callbacks_get_impl(FutureObj *self); @@ -704,16 +657,6 @@ _asyncio_Future__callbacks_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_asyncio_Future__result_DOCSTR) -# define _asyncio_Future__result_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__RESULT_GETSETDEF) -# undef _ASYNCIO_FUTURE__RESULT_GETSETDEF -# define _ASYNCIO_FUTURE__RESULT_GETSETDEF {"_result", (getter)_asyncio_Future__result_get, (setter)_asyncio_Future__result_set, _asyncio_Future__result_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__RESULT_GETSETDEF {"_result", (getter)_asyncio_Future__result_get, NULL, _asyncio_Future__result_DOCSTR}, -#endif - static PyObject * _asyncio_Future__result_get_impl(FutureObj *self); @@ -729,16 +672,6 @@ _asyncio_Future__result_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_asyncio_Future__exception_DOCSTR) -# define _asyncio_Future__exception_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__EXCEPTION_GETSETDEF) -# undef _ASYNCIO_FUTURE__EXCEPTION_GETSETDEF -# define _ASYNCIO_FUTURE__EXCEPTION_GETSETDEF {"_exception", (getter)_asyncio_Future__exception_get, (setter)_asyncio_Future__exception_set, _asyncio_Future__exception_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__EXCEPTION_GETSETDEF {"_exception", (getter)_asyncio_Future__exception_get, NULL, _asyncio_Future__exception_DOCSTR}, -#endif - static PyObject * _asyncio_Future__exception_get_impl(FutureObj *self); @@ -754,16 +687,6 @@ _asyncio_Future__exception_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_asyncio_Future__source_traceback_DOCSTR) -# define _asyncio_Future__source_traceback_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__SOURCE_TRACEBACK_GETSETDEF) -# undef _ASYNCIO_FUTURE__SOURCE_TRACEBACK_GETSETDEF -# define _ASYNCIO_FUTURE__SOURCE_TRACEBACK_GETSETDEF {"_source_traceback", (getter)_asyncio_Future__source_traceback_get, (setter)_asyncio_Future__source_traceback_set, _asyncio_Future__source_traceback_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__SOURCE_TRACEBACK_GETSETDEF {"_source_traceback", (getter)_asyncio_Future__source_traceback_get, NULL, _asyncio_Future__source_traceback_DOCSTR}, -#endif - static PyObject * _asyncio_Future__source_traceback_get_impl(FutureObj *self); @@ -779,16 +702,6 @@ _asyncio_Future__source_traceback_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_asyncio_Future__cancel_message_DOCSTR) -# define _asyncio_Future__cancel_message_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__CANCEL_MESSAGE_GETSETDEF) -# undef _ASYNCIO_FUTURE__CANCEL_MESSAGE_GETSETDEF -# define _ASYNCIO_FUTURE__CANCEL_MESSAGE_GETSETDEF {"_cancel_message", (getter)_asyncio_Future__cancel_message_get, (setter)_asyncio_Future__cancel_message_set, _asyncio_Future__cancel_message_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__CANCEL_MESSAGE_GETSETDEF {"_cancel_message", (getter)_asyncio_Future__cancel_message_get, NULL, _asyncio_Future__cancel_message_DOCSTR}, -#endif - static PyObject * _asyncio_Future__cancel_message_get_impl(FutureObj *self); @@ -804,30 +717,22 @@ _asyncio_Future__cancel_message_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_asyncio_Future__cancel_message_DOCSTR) -# define _asyncio_Future__cancel_message_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__CANCEL_MESSAGE_GETSETDEF) -# undef _ASYNCIO_FUTURE__CANCEL_MESSAGE_GETSETDEF -# define _ASYNCIO_FUTURE__CANCEL_MESSAGE_GETSETDEF {"_cancel_message", (getter)_asyncio_Future__cancel_message_get, (setter)_asyncio_Future__cancel_message_set, _asyncio_Future__cancel_message_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__CANCEL_MESSAGE_GETSETDEF {"_cancel_message", NULL, (setter)_asyncio_Future__cancel_message_set, NULL}, -#endif - static int _asyncio_Future__cancel_message_set_impl(FutureObj *self, PyObject *value); static int -_asyncio_Future__cancel_message_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_asyncio_Future__cancel_message_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute '_cancel_message' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = _asyncio_Future__cancel_message_set_impl((FutureObj *)self, value); Py_END_CRITICAL_SECTION(); @@ -835,16 +740,6 @@ _asyncio_Future__cancel_message_set(PyObject *self, PyObject *value, void *Py_UN return return_value; } -#if !defined(_asyncio_Future__state_DOCSTR) -# define _asyncio_Future__state_DOCSTR NULL -#endif -#if defined(_ASYNCIO_FUTURE__STATE_GETSETDEF) -# undef _ASYNCIO_FUTURE__STATE_GETSETDEF -# define _ASYNCIO_FUTURE__STATE_GETSETDEF {"_state", (getter)_asyncio_Future__state_get, (setter)_asyncio_Future__state_set, _asyncio_Future__state_DOCSTR}, -#else -# define _ASYNCIO_FUTURE__STATE_GETSETDEF {"_state", (getter)_asyncio_Future__state_get, NULL, _asyncio_Future__state_DOCSTR}, -#endif - static PyObject * _asyncio_Future__state_get_impl(FutureObj *self); @@ -977,72 +872,54 @@ _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) return return_value; } -#if !defined(_asyncio_Task__log_destroy_pending_DOCSTR) -# define _asyncio_Task__log_destroy_pending_DOCSTR NULL -#endif -#if defined(_ASYNCIO_TASK__LOG_DESTROY_PENDING_GETSETDEF) -# undef _ASYNCIO_TASK__LOG_DESTROY_PENDING_GETSETDEF -# define _ASYNCIO_TASK__LOG_DESTROY_PENDING_GETSETDEF {"_log_destroy_pending", (getter)_asyncio_Task__log_destroy_pending_get, (setter)_asyncio_Task__log_destroy_pending_set, _asyncio_Task__log_destroy_pending_DOCSTR}, -#else -# define _ASYNCIO_TASK__LOG_DESTROY_PENDING_GETSETDEF {"_log_destroy_pending", (getter)_asyncio_Task__log_destroy_pending_get, NULL, _asyncio_Task__log_destroy_pending_DOCSTR}, -#endif - -static PyObject * +static int _asyncio_Task__log_destroy_pending_get_impl(TaskObj *self); static PyObject * _asyncio_Task__log_destroy_pending_get(PyObject *self, void *Py_UNUSED(context)) { PyObject *return_value = NULL; + int _return_value; Py_BEGIN_CRITICAL_SECTION(self); - return_value = _asyncio_Task__log_destroy_pending_get_impl((TaskObj *)self); + _return_value = _asyncio_Task__log_destroy_pending_get_impl((TaskObj *)self); Py_END_CRITICAL_SECTION(); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); +exit: return return_value; } -#if !defined(_asyncio_Task__log_destroy_pending_DOCSTR) -# define _asyncio_Task__log_destroy_pending_DOCSTR NULL -#endif -#if defined(_ASYNCIO_TASK__LOG_DESTROY_PENDING_GETSETDEF) -# undef _ASYNCIO_TASK__LOG_DESTROY_PENDING_GETSETDEF -# define _ASYNCIO_TASK__LOG_DESTROY_PENDING_GETSETDEF {"_log_destroy_pending", (getter)_asyncio_Task__log_destroy_pending_get, (setter)_asyncio_Task__log_destroy_pending_set, _asyncio_Task__log_destroy_pending_DOCSTR}, -#else -# define _ASYNCIO_TASK__LOG_DESTROY_PENDING_GETSETDEF {"_log_destroy_pending", NULL, (setter)_asyncio_Task__log_destroy_pending_set, NULL}, -#endif - static int -_asyncio_Task__log_destroy_pending_set_impl(TaskObj *self, PyObject *value); +_asyncio_Task__log_destroy_pending_set_impl(TaskObj *self, int value); static int -_asyncio_Task__log_destroy_pending_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_asyncio_Task__log_destroy_pending_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + int value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute '_log_destroy_pending' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = PyObject_IsTrue(arg); + if (value < 0) { + goto exit; + } Py_BEGIN_CRITICAL_SECTION(self); return_value = _asyncio_Task__log_destroy_pending_set_impl((TaskObj *)self, value); Py_END_CRITICAL_SECTION(); +exit: return return_value; } -#if !defined(_asyncio_Task__must_cancel_DOCSTR) -# define _asyncio_Task__must_cancel_DOCSTR NULL -#endif -#if defined(_ASYNCIO_TASK__MUST_CANCEL_GETSETDEF) -# undef _ASYNCIO_TASK__MUST_CANCEL_GETSETDEF -# define _ASYNCIO_TASK__MUST_CANCEL_GETSETDEF {"_must_cancel", (getter)_asyncio_Task__must_cancel_get, (setter)_asyncio_Task__must_cancel_set, _asyncio_Task__must_cancel_DOCSTR}, -#else -# define _ASYNCIO_TASK__MUST_CANCEL_GETSETDEF {"_must_cancel", (getter)_asyncio_Task__must_cancel_get, NULL, _asyncio_Task__must_cancel_DOCSTR}, -#endif - static PyObject * _asyncio_Task__must_cancel_get_impl(TaskObj *self); @@ -1058,16 +935,6 @@ _asyncio_Task__must_cancel_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_asyncio_Task__coro_DOCSTR) -# define _asyncio_Task__coro_DOCSTR NULL -#endif -#if defined(_ASYNCIO_TASK__CORO_GETSETDEF) -# undef _ASYNCIO_TASK__CORO_GETSETDEF -# define _ASYNCIO_TASK__CORO_GETSETDEF {"_coro", (getter)_asyncio_Task__coro_get, (setter)_asyncio_Task__coro_set, _asyncio_Task__coro_DOCSTR}, -#else -# define _ASYNCIO_TASK__CORO_GETSETDEF {"_coro", (getter)_asyncio_Task__coro_get, NULL, _asyncio_Task__coro_DOCSTR}, -#endif - static PyObject * _asyncio_Task__coro_get_impl(TaskObj *self); @@ -1083,16 +950,6 @@ _asyncio_Task__coro_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_asyncio_Task__fut_waiter_DOCSTR) -# define _asyncio_Task__fut_waiter_DOCSTR NULL -#endif -#if defined(_ASYNCIO_TASK__FUT_WAITER_GETSETDEF) -# undef _ASYNCIO_TASK__FUT_WAITER_GETSETDEF -# define _ASYNCIO_TASK__FUT_WAITER_GETSETDEF {"_fut_waiter", (getter)_asyncio_Task__fut_waiter_get, (setter)_asyncio_Task__fut_waiter_set, _asyncio_Task__fut_waiter_DOCSTR}, -#else -# define _ASYNCIO_TASK__FUT_WAITER_GETSETDEF {"_fut_waiter", (getter)_asyncio_Task__fut_waiter_get, NULL, _asyncio_Task__fut_waiter_DOCSTR}, -#endif - static PyObject * _asyncio_Task__fut_waiter_get_impl(TaskObj *self); @@ -2258,4 +2115,32 @@ _asyncio_future_discard_from_awaited_by(PyObject *module, PyObject *const *args, exit: return return_value; } -/*[clinic end generated code: output=46d50c477614b57e input=a9049054013a1b77]*/ +#define _ASYNCIO_FUTURE__ASYNCIO_AWAITED_BY_GETSETDEF {"_asyncio_awaited_by", (getter)_asyncio_Future__asyncio_awaited_by_get, (setter)NULL, NULL}, + +#define _ASYNCIO_FUTURE__ASYNCIO_FUTURE_BLOCKING_GETSETDEF {"_asyncio_future_blocking", (getter)_asyncio_Future__asyncio_future_blocking_get, (setter)_asyncio_Future__asyncio_future_blocking_set, NULL}, + +#define _ASYNCIO_FUTURE__LOG_TRACEBACK_GETSETDEF {"_log_traceback", (getter)_asyncio_Future__log_traceback_get, (setter)_asyncio_Future__log_traceback_set, NULL}, + +#define _ASYNCIO_FUTURE__LOOP_GETSETDEF {"_loop", (getter)_asyncio_Future__loop_get, (setter)NULL, NULL}, + +#define _ASYNCIO_FUTURE__CALLBACKS_GETSETDEF {"_callbacks", (getter)_asyncio_Future__callbacks_get, (setter)NULL, NULL}, + +#define _ASYNCIO_FUTURE__RESULT_GETSETDEF {"_result", (getter)_asyncio_Future__result_get, (setter)NULL, NULL}, + +#define _ASYNCIO_FUTURE__EXCEPTION_GETSETDEF {"_exception", (getter)_asyncio_Future__exception_get, (setter)NULL, NULL}, + +#define _ASYNCIO_FUTURE__SOURCE_TRACEBACK_GETSETDEF {"_source_traceback", (getter)_asyncio_Future__source_traceback_get, (setter)NULL, NULL}, + +#define _ASYNCIO_FUTURE__CANCEL_MESSAGE_GETSETDEF {"_cancel_message", (getter)_asyncio_Future__cancel_message_get, (setter)_asyncio_Future__cancel_message_set, NULL}, + +#define _ASYNCIO_FUTURE__STATE_GETSETDEF {"_state", (getter)_asyncio_Future__state_get, (setter)NULL, NULL}, + +#define _ASYNCIO_TASK__LOG_DESTROY_PENDING_GETSETDEF {"_log_destroy_pending", (getter)_asyncio_Task__log_destroy_pending_get, (setter)_asyncio_Task__log_destroy_pending_set, NULL}, + +#define _ASYNCIO_TASK__MUST_CANCEL_GETSETDEF {"_must_cancel", (getter)_asyncio_Task__must_cancel_get, (setter)NULL, NULL}, + +#define _ASYNCIO_TASK__CORO_GETSETDEF {"_coro", (getter)_asyncio_Task__coro_get, (setter)NULL, NULL}, + +#define _ASYNCIO_TASK__FUT_WAITER_GETSETDEF {"_fut_waiter", (getter)_asyncio_Task__fut_waiter_get, (setter)NULL, NULL}, + +/*[clinic end generated code: output=f56ee5ac44909b27 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index d60e437b56857a..b0dc01adfc999e 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -340,20 +340,6 @@ PyDoc_STRVAR(_ssl__SSLSocket_context__doc__, "sni_callback on the SSLContext to change the certificate information\n" "associated with the SSLSocket before the cryptographic exchange\n" "handshake messages."); -#if defined(_ssl__SSLSocket_context_DOCSTR) -# undef _ssl__SSLSocket_context_DOCSTR -#endif -#define _ssl__SSLSocket_context_DOCSTR _ssl__SSLSocket_context__doc__ - -#if !defined(_ssl__SSLSocket_context_DOCSTR) -# define _ssl__SSLSocket_context_DOCSTR NULL -#endif -#if defined(_SSL__SSLSOCKET_CONTEXT_GETSETDEF) -# undef _SSL__SSLSOCKET_CONTEXT_GETSETDEF -# define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", (getter)_ssl__SSLSocket_context_get, (setter)_ssl__SSLSocket_context_set, _ssl__SSLSocket_context_DOCSTR}, -#else -# define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", (getter)_ssl__SSLSocket_context_get, NULL, _ssl__SSLSocket_context_DOCSTR}, -#endif static PyObject * _ssl__SSLSocket_context_get_impl(PySSLSocket *self); @@ -370,30 +356,22 @@ _ssl__SSLSocket_context_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ssl__SSLSocket_context_DOCSTR) -# define _ssl__SSLSocket_context_DOCSTR NULL -#endif -#if defined(_SSL__SSLSOCKET_CONTEXT_GETSETDEF) -# undef _SSL__SSLSOCKET_CONTEXT_GETSETDEF -# define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", (getter)_ssl__SSLSocket_context_get, (setter)_ssl__SSLSocket_context_set, _ssl__SSLSocket_context_DOCSTR}, -#else -# define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", NULL, (setter)_ssl__SSLSocket_context_set, NULL}, -#endif - static int _ssl__SSLSocket_context_set_impl(PySSLSocket *self, PyObject *value); static int -_ssl__SSLSocket_context_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ssl__SSLSocket_context_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'context' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLSocket_context_set_impl((PySSLSocket *)self, value); Py_END_CRITICAL_SECTION(); @@ -403,20 +381,6 @@ _ssl__SSLSocket_context_set(PyObject *self, PyObject *value, void *Py_UNUSED(con PyDoc_STRVAR(_ssl__SSLSocket_server_side__doc__, "Whether this is a server-side socket."); -#if defined(_ssl__SSLSocket_server_side_DOCSTR) -# undef _ssl__SSLSocket_server_side_DOCSTR -#endif -#define _ssl__SSLSocket_server_side_DOCSTR _ssl__SSLSocket_server_side__doc__ - -#if !defined(_ssl__SSLSocket_server_side_DOCSTR) -# define _ssl__SSLSocket_server_side_DOCSTR NULL -#endif -#if defined(_SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF) -# undef _SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF -# define _SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF {"server_side", (getter)_ssl__SSLSocket_server_side_get, (setter)_ssl__SSLSocket_server_side_set, _ssl__SSLSocket_server_side_DOCSTR}, -#else -# define _SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF {"server_side", (getter)_ssl__SSLSocket_server_side_get, NULL, _ssl__SSLSocket_server_side_DOCSTR}, -#endif static PyObject * _ssl__SSLSocket_server_side_get_impl(PySSLSocket *self); @@ -435,20 +399,6 @@ _ssl__SSLSocket_server_side_get(PyObject *self, void *Py_UNUSED(context)) PyDoc_STRVAR(_ssl__SSLSocket_server_hostname__doc__, "The currently set server hostname (for SNI)."); -#if defined(_ssl__SSLSocket_server_hostname_DOCSTR) -# undef _ssl__SSLSocket_server_hostname_DOCSTR -#endif -#define _ssl__SSLSocket_server_hostname_DOCSTR _ssl__SSLSocket_server_hostname__doc__ - -#if !defined(_ssl__SSLSocket_server_hostname_DOCSTR) -# define _ssl__SSLSocket_server_hostname_DOCSTR NULL -#endif -#if defined(_SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF) -# undef _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF -# define _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF {"server_hostname", (getter)_ssl__SSLSocket_server_hostname_get, (setter)_ssl__SSLSocket_server_hostname_set, _ssl__SSLSocket_server_hostname_DOCSTR}, -#else -# define _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF {"server_hostname", (getter)_ssl__SSLSocket_server_hostname_get, NULL, _ssl__SSLSocket_server_hostname_DOCSTR}, -#endif static PyObject * _ssl__SSLSocket_server_hostname_get_impl(PySSLSocket *self); @@ -469,20 +419,6 @@ PyDoc_STRVAR(_ssl__SSLSocket_owner__doc__, "The Python-level owner of this object.\n" "\n" "Passed as \"self\" in servername callback."); -#if defined(_ssl__SSLSocket_owner_DOCSTR) -# undef _ssl__SSLSocket_owner_DOCSTR -#endif -#define _ssl__SSLSocket_owner_DOCSTR _ssl__SSLSocket_owner__doc__ - -#if !defined(_ssl__SSLSocket_owner_DOCSTR) -# define _ssl__SSLSocket_owner_DOCSTR NULL -#endif -#if defined(_SSL__SSLSOCKET_OWNER_GETSETDEF) -# undef _SSL__SSLSOCKET_OWNER_GETSETDEF -# define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", (getter)_ssl__SSLSocket_owner_get, (setter)_ssl__SSLSocket_owner_set, _ssl__SSLSocket_owner_DOCSTR}, -#else -# define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", (getter)_ssl__SSLSocket_owner_get, NULL, _ssl__SSLSocket_owner_DOCSTR}, -#endif static PyObject * _ssl__SSLSocket_owner_get_impl(PySSLSocket *self); @@ -499,30 +435,22 @@ _ssl__SSLSocket_owner_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ssl__SSLSocket_owner_DOCSTR) -# define _ssl__SSLSocket_owner_DOCSTR NULL -#endif -#if defined(_SSL__SSLSOCKET_OWNER_GETSETDEF) -# undef _SSL__SSLSOCKET_OWNER_GETSETDEF -# define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", (getter)_ssl__SSLSocket_owner_get, (setter)_ssl__SSLSocket_owner_set, _ssl__SSLSocket_owner_DOCSTR}, -#else -# define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", NULL, (setter)_ssl__SSLSocket_owner_set, NULL}, -#endif - static int _ssl__SSLSocket_owner_set_impl(PySSLSocket *self, PyObject *value); static int -_ssl__SSLSocket_owner_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ssl__SSLSocket_owner_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'owner' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLSocket_owner_set_impl((PySSLSocket *)self, value); Py_END_CRITICAL_SECTION(); @@ -887,20 +815,6 @@ _ssl__SSLSocket_verify_client_post_handshake(PyObject *self, PyObject *Py_UNUSED PyDoc_STRVAR(_ssl__SSLSocket_session__doc__, "The underlying SSLSession object."); -#if defined(_ssl__SSLSocket_session_DOCSTR) -# undef _ssl__SSLSocket_session_DOCSTR -#endif -#define _ssl__SSLSocket_session_DOCSTR _ssl__SSLSocket_session__doc__ - -#if !defined(_ssl__SSLSocket_session_DOCSTR) -# define _ssl__SSLSocket_session_DOCSTR NULL -#endif -#if defined(_SSL__SSLSOCKET_SESSION_GETSETDEF) -# undef _SSL__SSLSOCKET_SESSION_GETSETDEF -# define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", (getter)_ssl__SSLSocket_session_get, (setter)_ssl__SSLSocket_session_set, _ssl__SSLSocket_session_DOCSTR}, -#else -# define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", (getter)_ssl__SSLSocket_session_get, NULL, _ssl__SSLSocket_session_DOCSTR}, -#endif static PyObject * _ssl__SSLSocket_session_get_impl(PySSLSocket *self); @@ -917,30 +831,22 @@ _ssl__SSLSocket_session_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ssl__SSLSocket_session_DOCSTR) -# define _ssl__SSLSocket_session_DOCSTR NULL -#endif -#if defined(_SSL__SSLSOCKET_SESSION_GETSETDEF) -# undef _SSL__SSLSOCKET_SESSION_GETSETDEF -# define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", (getter)_ssl__SSLSocket_session_get, (setter)_ssl__SSLSocket_session_set, _ssl__SSLSocket_session_DOCSTR}, -#else -# define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", NULL, (setter)_ssl__SSLSocket_session_set, NULL}, -#endif - static int _ssl__SSLSocket_session_set_impl(PySSLSocket *self, PyObject *value); static int -_ssl__SSLSocket_session_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ssl__SSLSocket_session_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'session' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLSocket_session_set_impl((PySSLSocket *)self, value); Py_END_CRITICAL_SECTION(); @@ -950,20 +856,6 @@ _ssl__SSLSocket_session_set(PyObject *self, PyObject *value, void *Py_UNUSED(con PyDoc_STRVAR(_ssl__SSLSocket_session_reused__doc__, "Was the client session reused during handshake?"); -#if defined(_ssl__SSLSocket_session_reused_DOCSTR) -# undef _ssl__SSLSocket_session_reused_DOCSTR -#endif -#define _ssl__SSLSocket_session_reused_DOCSTR _ssl__SSLSocket_session_reused__doc__ - -#if !defined(_ssl__SSLSocket_session_reused_DOCSTR) -# define _ssl__SSLSocket_session_reused_DOCSTR NULL -#endif -#if defined(_SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF) -# undef _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF -# define _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF {"session_reused", (getter)_ssl__SSLSocket_session_reused_get, (setter)_ssl__SSLSocket_session_reused_set, _ssl__SSLSocket_session_reused_DOCSTR}, -#else -# define _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF {"session_reused", (getter)_ssl__SSLSocket_session_reused_get, NULL, _ssl__SSLSocket_session_reused_DOCSTR}, -#endif static PyObject * _ssl__SSLSocket_session_reused_get_impl(PySSLSocket *self); @@ -1326,128 +1218,119 @@ _ssl__SSLContext__set_alpn_protocols(PyObject *self, PyObject *arg) return return_value; } -#if !defined(_ssl__SSLContext_verify_mode_DOCSTR) -# define _ssl__SSLContext_verify_mode_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF) -# undef _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF -# define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", (getter)_ssl__SSLContext_verify_mode_get, (setter)_ssl__SSLContext_verify_mode_set, _ssl__SSLContext_verify_mode_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", (getter)_ssl__SSLContext_verify_mode_get, NULL, _ssl__SSLContext_verify_mode_DOCSTR}, -#endif - -static PyObject * +static int _ssl__SSLContext_verify_mode_get_impl(PySSLContext *self); static PyObject * _ssl__SSLContext_verify_mode_get(PyObject *self, void *Py_UNUSED(context)) { PyObject *return_value = NULL; + int _return_value; Py_BEGIN_CRITICAL_SECTION(self); - return_value = _ssl__SSLContext_verify_mode_get_impl((PySSLContext *)self); + _return_value = _ssl__SSLContext_verify_mode_get_impl((PySSLContext *)self); Py_END_CRITICAL_SECTION(); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); +exit: return return_value; } -#if !defined(_ssl__SSLContext_verify_mode_DOCSTR) -# define _ssl__SSLContext_verify_mode_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF) -# undef _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF -# define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", (getter)_ssl__SSLContext_verify_mode_get, (setter)_ssl__SSLContext_verify_mode_set, _ssl__SSLContext_verify_mode_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", NULL, (setter)_ssl__SSLContext_verify_mode_set, NULL}, -#endif - static int -_ssl__SSLContext_verify_mode_set_impl(PySSLContext *self, PyObject *value); +_ssl__SSLContext_verify_mode_set_impl(PySSLContext *self, int value); static int -_ssl__SSLContext_verify_mode_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ssl__SSLContext_verify_mode_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + int value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'verify_mode' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = PyLong_AsInt(arg); + if (value == -1 && PyErr_Occurred()) { + goto exit; + } Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_verify_mode_set_impl((PySSLContext *)self, value); Py_END_CRITICAL_SECTION(); +exit: return return_value; } -#if !defined(_ssl__SSLContext_verify_flags_DOCSTR) -# define _ssl__SSLContext_verify_flags_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF) -# undef _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF -# define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", (getter)_ssl__SSLContext_verify_flags_get, (setter)_ssl__SSLContext_verify_flags_set, _ssl__SSLContext_verify_flags_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", (getter)_ssl__SSLContext_verify_flags_get, NULL, _ssl__SSLContext_verify_flags_DOCSTR}, -#endif - -static PyObject * +static unsigned long _ssl__SSLContext_verify_flags_get_impl(PySSLContext *self); static PyObject * _ssl__SSLContext_verify_flags_get(PyObject *self, void *Py_UNUSED(context)) { PyObject *return_value = NULL; + unsigned long _return_value; Py_BEGIN_CRITICAL_SECTION(self); - return_value = _ssl__SSLContext_verify_flags_get_impl((PySSLContext *)self); + _return_value = _ssl__SSLContext_verify_flags_get_impl((PySSLContext *)self); Py_END_CRITICAL_SECTION(); + if ((_return_value == (unsigned long)-1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromUnsignedLong(_return_value); +exit: return return_value; } -#if !defined(_ssl__SSLContext_verify_flags_DOCSTR) -# define _ssl__SSLContext_verify_flags_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF) -# undef _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF -# define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", (getter)_ssl__SSLContext_verify_flags_get, (setter)_ssl__SSLContext_verify_flags_set, _ssl__SSLContext_verify_flags_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", NULL, (setter)_ssl__SSLContext_verify_flags_set, NULL}, -#endif - static int -_ssl__SSLContext_verify_flags_set_impl(PySSLContext *self, PyObject *value); +_ssl__SSLContext_verify_flags_set_impl(PySSLContext *self, + unsigned long value); static int -_ssl__SSLContext_verify_flags_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ssl__SSLContext_verify_flags_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + unsigned long value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'verify_flags' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + if (!PyIndex_Check(arg)) { + PyErr_Format(PyExc_TypeError, "attribute 'verify_flags' must be int, not %T", arg); + goto exit; + } + { + Py_ssize_t _bytes = PyLong_AsNativeBytes(arg, &value, sizeof(unsigned long), + Py_ASNATIVEBYTES_NATIVE_ENDIAN | + Py_ASNATIVEBYTES_ALLOW_INDEX | + Py_ASNATIVEBYTES_UNSIGNED_BUFFER); + if (_bytes < 0) { + goto exit; + } + if ((size_t)_bytes > sizeof(unsigned long)) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "integer value out of range", 1) < 0) + { + goto exit; + } + } + } Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_verify_flags_set_impl((PySSLContext *)self, value); Py_END_CRITICAL_SECTION(); +exit: return return_value; } -#if !defined(_ssl__SSLContext_minimum_version_DOCSTR) -# define _ssl__SSLContext_minimum_version_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF) -# undef _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF -# define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", (getter)_ssl__SSLContext_minimum_version_get, (setter)_ssl__SSLContext_minimum_version_set, _ssl__SSLContext_minimum_version_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", (getter)_ssl__SSLContext_minimum_version_get, NULL, _ssl__SSLContext_minimum_version_DOCSTR}, -#endif - static PyObject * _ssl__SSLContext_minimum_version_get_impl(PySSLContext *self); @@ -1463,31 +1346,23 @@ _ssl__SSLContext_minimum_version_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ssl__SSLContext_minimum_version_DOCSTR) -# define _ssl__SSLContext_minimum_version_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF) -# undef _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF -# define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", (getter)_ssl__SSLContext_minimum_version_get, (setter)_ssl__SSLContext_minimum_version_set, _ssl__SSLContext_minimum_version_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", NULL, (setter)_ssl__SSLContext_minimum_version_set, NULL}, -#endif - static int _ssl__SSLContext_minimum_version_set_impl(PySSLContext *self, PyObject *value); static int -_ssl__SSLContext_minimum_version_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ssl__SSLContext_minimum_version_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'minimum_version' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_minimum_version_set_impl((PySSLContext *)self, value); Py_END_CRITICAL_SECTION(); @@ -1495,16 +1370,6 @@ _ssl__SSLContext_minimum_version_set(PyObject *self, PyObject *value, void *Py_U return return_value; } -#if !defined(_ssl__SSLContext_maximum_version_DOCSTR) -# define _ssl__SSLContext_maximum_version_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF) -# undef _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF -# define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", (getter)_ssl__SSLContext_maximum_version_get, (setter)_ssl__SSLContext_maximum_version_set, _ssl__SSLContext_maximum_version_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", (getter)_ssl__SSLContext_maximum_version_get, NULL, _ssl__SSLContext_maximum_version_DOCSTR}, -#endif - static PyObject * _ssl__SSLContext_maximum_version_get_impl(PySSLContext *self); @@ -1520,31 +1385,23 @@ _ssl__SSLContext_maximum_version_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ssl__SSLContext_maximum_version_DOCSTR) -# define _ssl__SSLContext_maximum_version_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF) -# undef _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF -# define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", (getter)_ssl__SSLContext_maximum_version_get, (setter)_ssl__SSLContext_maximum_version_set, _ssl__SSLContext_maximum_version_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", NULL, (setter)_ssl__SSLContext_maximum_version_set, NULL}, -#endif - static int _ssl__SSLContext_maximum_version_set_impl(PySSLContext *self, PyObject *value); static int -_ssl__SSLContext_maximum_version_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ssl__SSLContext_maximum_version_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'maximum_version' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_maximum_version_set_impl((PySSLContext *)self, value); Py_END_CRITICAL_SECTION(); @@ -1554,20 +1411,6 @@ _ssl__SSLContext_maximum_version_set(PyObject *self, PyObject *value, void *Py_U PyDoc_STRVAR(_ssl__SSLContext_num_tickets__doc__, "Control the number of TLSv1.3 session tickets."); -#if defined(_ssl__SSLContext_num_tickets_DOCSTR) -# undef _ssl__SSLContext_num_tickets_DOCSTR -#endif -#define _ssl__SSLContext_num_tickets_DOCSTR _ssl__SSLContext_num_tickets__doc__ - -#if !defined(_ssl__SSLContext_num_tickets_DOCSTR) -# define _ssl__SSLContext_num_tickets_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF) -# undef _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF -# define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", (getter)_ssl__SSLContext_num_tickets_get, (setter)_ssl__SSLContext_num_tickets_set, _ssl__SSLContext_num_tickets_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", (getter)_ssl__SSLContext_num_tickets_get, NULL, _ssl__SSLContext_num_tickets_DOCSTR}, -#endif static PyObject * _ssl__SSLContext_num_tickets_get_impl(PySSLContext *self); @@ -1584,53 +1427,35 @@ _ssl__SSLContext_num_tickets_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ssl__SSLContext_num_tickets_DOCSTR) -# define _ssl__SSLContext_num_tickets_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF) -# undef _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF -# define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", (getter)_ssl__SSLContext_num_tickets_get, (setter)_ssl__SSLContext_num_tickets_set, _ssl__SSLContext_num_tickets_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", NULL, (setter)_ssl__SSLContext_num_tickets_set, NULL}, -#endif - static int -_ssl__SSLContext_num_tickets_set_impl(PySSLContext *self, PyObject *value); +_ssl__SSLContext_num_tickets_set_impl(PySSLContext *self, long value); static int -_ssl__SSLContext_num_tickets_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ssl__SSLContext_num_tickets_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + long value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'num_tickets' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = PyLong_AsLong(arg); + if (value == -1 && PyErr_Occurred()) { + goto exit; + } Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_num_tickets_set_impl((PySSLContext *)self, value); Py_END_CRITICAL_SECTION(); +exit: return return_value; } PyDoc_STRVAR(_ssl__SSLContext_security_level__doc__, "The current security level."); -#if defined(_ssl__SSLContext_security_level_DOCSTR) -# undef _ssl__SSLContext_security_level_DOCSTR -#endif -#define _ssl__SSLContext_security_level_DOCSTR _ssl__SSLContext_security_level__doc__ - -#if !defined(_ssl__SSLContext_security_level_DOCSTR) -# define _ssl__SSLContext_security_level_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF) -# undef _SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF -# define _SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF {"security_level", (getter)_ssl__SSLContext_security_level_get, (setter)_ssl__SSLContext_security_level_set, _ssl__SSLContext_security_level_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF {"security_level", (getter)_ssl__SSLContext_security_level_get, NULL, _ssl__SSLContext_security_level_DOCSTR}, -#endif static PyObject * _ssl__SSLContext_security_level_get_impl(PySSLContext *self); @@ -1647,16 +1472,6 @@ _ssl__SSLContext_security_level_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ssl__SSLContext_options_DOCSTR) -# define _ssl__SSLContext_options_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_OPTIONS_GETSETDEF) -# undef _SSL__SSLCONTEXT_OPTIONS_GETSETDEF -# define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", (getter)_ssl__SSLContext_options_get, (setter)_ssl__SSLContext_options_set, _ssl__SSLContext_options_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", (getter)_ssl__SSLContext_options_get, NULL, _ssl__SSLContext_options_DOCSTR}, -#endif - static PyObject * _ssl__SSLContext_options_get_impl(PySSLContext *self); @@ -1672,159 +1487,141 @@ _ssl__SSLContext_options_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ssl__SSLContext_options_DOCSTR) -# define _ssl__SSLContext_options_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_OPTIONS_GETSETDEF) -# undef _SSL__SSLCONTEXT_OPTIONS_GETSETDEF -# define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", (getter)_ssl__SSLContext_options_get, (setter)_ssl__SSLContext_options_set, _ssl__SSLContext_options_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", NULL, (setter)_ssl__SSLContext_options_set, NULL}, -#endif - static int -_ssl__SSLContext_options_set_impl(PySSLContext *self, PyObject *value); +_ssl__SSLContext_options_set_impl(PySSLContext *self, + unsigned long long value); static int -_ssl__SSLContext_options_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ssl__SSLContext_options_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + unsigned long long value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'options' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + if (!_PyLong_UnsignedLongLong_Converter(arg, &value)) { + goto exit; + } Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_options_set_impl((PySSLContext *)self, value); Py_END_CRITICAL_SECTION(); +exit: return return_value; } -#if !defined(_ssl__SSLContext__host_flags_DOCSTR) -# define _ssl__SSLContext__host_flags_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF) -# undef _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF -# define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", (getter)_ssl__SSLContext__host_flags_get, (setter)_ssl__SSLContext__host_flags_set, _ssl__SSLContext__host_flags_DOCSTR}, -#else -# define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", (getter)_ssl__SSLContext__host_flags_get, NULL, _ssl__SSLContext__host_flags_DOCSTR}, -#endif - -static PyObject * +static unsigned int _ssl__SSLContext__host_flags_get_impl(PySSLContext *self); static PyObject * _ssl__SSLContext__host_flags_get(PyObject *self, void *Py_UNUSED(context)) { PyObject *return_value = NULL; + unsigned int _return_value; Py_BEGIN_CRITICAL_SECTION(self); - return_value = _ssl__SSLContext__host_flags_get_impl((PySSLContext *)self); + _return_value = _ssl__SSLContext__host_flags_get_impl((PySSLContext *)self); Py_END_CRITICAL_SECTION(); + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); +exit: return return_value; } -#if !defined(_ssl__SSLContext__host_flags_DOCSTR) -# define _ssl__SSLContext__host_flags_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF) -# undef _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF -# define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", (getter)_ssl__SSLContext__host_flags_get, (setter)_ssl__SSLContext__host_flags_set, _ssl__SSLContext__host_flags_DOCSTR}, -#else -# define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", NULL, (setter)_ssl__SSLContext__host_flags_set, NULL}, -#endif - static int -_ssl__SSLContext__host_flags_set_impl(PySSLContext *self, PyObject *value); +_ssl__SSLContext__host_flags_set_impl(PySSLContext *self, unsigned int value); static int -_ssl__SSLContext__host_flags_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ssl__SSLContext__host_flags_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + unsigned int value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute '_host_flags' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + { + Py_ssize_t _bytes = PyLong_AsNativeBytes(arg, &value, sizeof(unsigned int), + Py_ASNATIVEBYTES_NATIVE_ENDIAN | + Py_ASNATIVEBYTES_ALLOW_INDEX | + Py_ASNATIVEBYTES_UNSIGNED_BUFFER); + if (_bytes < 0) { + goto exit; + } + if ((size_t)_bytes > sizeof(unsigned int)) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "integer value out of range", 1) < 0) + { + goto exit; + } + } + } Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext__host_flags_set_impl((PySSLContext *)self, value); Py_END_CRITICAL_SECTION(); +exit: return return_value; } -#if !defined(_ssl__SSLContext_check_hostname_DOCSTR) -# define _ssl__SSLContext_check_hostname_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF) -# undef _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF -# define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", (getter)_ssl__SSLContext_check_hostname_get, (setter)_ssl__SSLContext_check_hostname_set, _ssl__SSLContext_check_hostname_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", (getter)_ssl__SSLContext_check_hostname_get, NULL, _ssl__SSLContext_check_hostname_DOCSTR}, -#endif - -static PyObject * +static int _ssl__SSLContext_check_hostname_get_impl(PySSLContext *self); static PyObject * _ssl__SSLContext_check_hostname_get(PyObject *self, void *Py_UNUSED(context)) { PyObject *return_value = NULL; + int _return_value; Py_BEGIN_CRITICAL_SECTION(self); - return_value = _ssl__SSLContext_check_hostname_get_impl((PySSLContext *)self); + _return_value = _ssl__SSLContext_check_hostname_get_impl((PySSLContext *)self); Py_END_CRITICAL_SECTION(); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); +exit: return return_value; } -#if !defined(_ssl__SSLContext_check_hostname_DOCSTR) -# define _ssl__SSLContext_check_hostname_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF) -# undef _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF -# define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", (getter)_ssl__SSLContext_check_hostname_get, (setter)_ssl__SSLContext_check_hostname_set, _ssl__SSLContext_check_hostname_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", NULL, (setter)_ssl__SSLContext_check_hostname_set, NULL}, -#endif - static int -_ssl__SSLContext_check_hostname_set_impl(PySSLContext *self, PyObject *value); +_ssl__SSLContext_check_hostname_set_impl(PySSLContext *self, int value); static int -_ssl__SSLContext_check_hostname_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ssl__SSLContext_check_hostname_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + int value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'check_hostname' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = PyObject_IsTrue(arg); + if (value < 0) { + goto exit; + } Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_check_hostname_set_impl((PySSLContext *)self, value); Py_END_CRITICAL_SECTION(); +exit: return return_value; } -#if !defined(_ssl__SSLContext_protocol_DOCSTR) -# define _ssl__SSLContext_protocol_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_PROTOCOL_GETSETDEF) -# undef _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF -# define _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF {"protocol", (getter)_ssl__SSLContext_protocol_get, (setter)_ssl__SSLContext_protocol_set, _ssl__SSLContext_protocol_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF {"protocol", (getter)_ssl__SSLContext_protocol_get, NULL, _ssl__SSLContext_protocol_DOCSTR}, -#endif - static PyObject * _ssl__SSLContext_protocol_get_impl(PySSLContext *self); @@ -2292,20 +2089,6 @@ PyDoc_STRVAR(_ssl__SSLContext_sni_callback__doc__, "SSLContext object.\n" "\n" "See RFC 6066 for details of the SNI extension."); -#if defined(_ssl__SSLContext_sni_callback_DOCSTR) -# undef _ssl__SSLContext_sni_callback_DOCSTR -#endif -#define _ssl__SSLContext_sni_callback_DOCSTR _ssl__SSLContext_sni_callback__doc__ - -#if !defined(_ssl__SSLContext_sni_callback_DOCSTR) -# define _ssl__SSLContext_sni_callback_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF) -# undef _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF -# define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", (getter)_ssl__SSLContext_sni_callback_get, (setter)_ssl__SSLContext_sni_callback_set, _ssl__SSLContext_sni_callback_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", (getter)_ssl__SSLContext_sni_callback_get, NULL, _ssl__SSLContext_sni_callback_DOCSTR}, -#endif static PyObject * _ssl__SSLContext_sni_callback_get_impl(PySSLContext *self); @@ -2322,30 +2105,22 @@ _ssl__SSLContext_sni_callback_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(_ssl__SSLContext_sni_callback_DOCSTR) -# define _ssl__SSLContext_sni_callback_DOCSTR NULL -#endif -#if defined(_SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF) -# undef _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF -# define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", (getter)_ssl__SSLContext_sni_callback_get, (setter)_ssl__SSLContext_sni_callback_set, _ssl__SSLContext_sni_callback_DOCSTR}, -#else -# define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", NULL, (setter)_ssl__SSLContext_sni_callback_set, NULL}, -#endif - static int _ssl__SSLContext_sni_callback_set_impl(PySSLContext *self, PyObject *value); static int -_ssl__SSLContext_sni_callback_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +_ssl__SSLContext_sni_callback_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'sni_callback' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = _ssl__SSLContext_sni_callback_set_impl((PySSLContext *)self, value); Py_END_CRITICAL_SECTION(); @@ -2629,20 +2404,6 @@ _ssl_MemoryBIO(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyDoc_STRVAR(_ssl_MemoryBIO_pending__doc__, "The number of bytes pending in the memory BIO."); -#if defined(_ssl_MemoryBIO_pending_DOCSTR) -# undef _ssl_MemoryBIO_pending_DOCSTR -#endif -#define _ssl_MemoryBIO_pending_DOCSTR _ssl_MemoryBIO_pending__doc__ - -#if !defined(_ssl_MemoryBIO_pending_DOCSTR) -# define _ssl_MemoryBIO_pending_DOCSTR NULL -#endif -#if defined(_SSL_MEMORYBIO_PENDING_GETSETDEF) -# undef _SSL_MEMORYBIO_PENDING_GETSETDEF -# define _SSL_MEMORYBIO_PENDING_GETSETDEF {"pending", (getter)_ssl_MemoryBIO_pending_get, (setter)_ssl_MemoryBIO_pending_set, _ssl_MemoryBIO_pending_DOCSTR}, -#else -# define _SSL_MEMORYBIO_PENDING_GETSETDEF {"pending", (getter)_ssl_MemoryBIO_pending_get, NULL, _ssl_MemoryBIO_pending_DOCSTR}, -#endif static PyObject * _ssl_MemoryBIO_pending_get_impl(PySSLMemoryBIO *self); @@ -2661,20 +2422,6 @@ _ssl_MemoryBIO_pending_get(PyObject *self, void *Py_UNUSED(context)) PyDoc_STRVAR(_ssl_MemoryBIO_eof__doc__, "Whether the memory BIO is at EOF."); -#if defined(_ssl_MemoryBIO_eof_DOCSTR) -# undef _ssl_MemoryBIO_eof_DOCSTR -#endif -#define _ssl_MemoryBIO_eof_DOCSTR _ssl_MemoryBIO_eof__doc__ - -#if !defined(_ssl_MemoryBIO_eof_DOCSTR) -# define _ssl_MemoryBIO_eof_DOCSTR NULL -#endif -#if defined(_SSL_MEMORYBIO_EOF_GETSETDEF) -# undef _SSL_MEMORYBIO_EOF_GETSETDEF -# define _SSL_MEMORYBIO_EOF_GETSETDEF {"eof", (getter)_ssl_MemoryBIO_eof_get, (setter)_ssl_MemoryBIO_eof_set, _ssl_MemoryBIO_eof_DOCSTR}, -#else -# define _SSL_MEMORYBIO_EOF_GETSETDEF {"eof", (getter)_ssl_MemoryBIO_eof_get, NULL, _ssl_MemoryBIO_eof_DOCSTR}, -#endif static PyObject * _ssl_MemoryBIO_eof_get_impl(PySSLMemoryBIO *self); @@ -2797,20 +2544,6 @@ _ssl_MemoryBIO_write_eof(PyObject *self, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(_ssl_SSLSession_time__doc__, "Session creation time (seconds since epoch)."); -#if defined(_ssl_SSLSession_time_DOCSTR) -# undef _ssl_SSLSession_time_DOCSTR -#endif -#define _ssl_SSLSession_time_DOCSTR _ssl_SSLSession_time__doc__ - -#if !defined(_ssl_SSLSession_time_DOCSTR) -# define _ssl_SSLSession_time_DOCSTR NULL -#endif -#if defined(_SSL_SSLSESSION_TIME_GETSETDEF) -# undef _SSL_SSLSESSION_TIME_GETSETDEF -# define _SSL_SSLSESSION_TIME_GETSETDEF {"time", (getter)_ssl_SSLSession_time_get, (setter)_ssl_SSLSession_time_set, _ssl_SSLSession_time_DOCSTR}, -#else -# define _SSL_SSLSESSION_TIME_GETSETDEF {"time", (getter)_ssl_SSLSession_time_get, NULL, _ssl_SSLSession_time_DOCSTR}, -#endif static PyObject * _ssl_SSLSession_time_get_impl(PySSLSession *self); @@ -2829,20 +2562,6 @@ _ssl_SSLSession_time_get(PyObject *self, void *Py_UNUSED(context)) PyDoc_STRVAR(_ssl_SSLSession_timeout__doc__, "Session timeout (delta in seconds)."); -#if defined(_ssl_SSLSession_timeout_DOCSTR) -# undef _ssl_SSLSession_timeout_DOCSTR -#endif -#define _ssl_SSLSession_timeout_DOCSTR _ssl_SSLSession_timeout__doc__ - -#if !defined(_ssl_SSLSession_timeout_DOCSTR) -# define _ssl_SSLSession_timeout_DOCSTR NULL -#endif -#if defined(_SSL_SSLSESSION_TIMEOUT_GETSETDEF) -# undef _SSL_SSLSESSION_TIMEOUT_GETSETDEF -# define _SSL_SSLSESSION_TIMEOUT_GETSETDEF {"timeout", (getter)_ssl_SSLSession_timeout_get, (setter)_ssl_SSLSession_timeout_set, _ssl_SSLSession_timeout_DOCSTR}, -#else -# define _SSL_SSLSESSION_TIMEOUT_GETSETDEF {"timeout", (getter)_ssl_SSLSession_timeout_get, NULL, _ssl_SSLSession_timeout_DOCSTR}, -#endif static PyObject * _ssl_SSLSession_timeout_get_impl(PySSLSession *self); @@ -2861,20 +2580,6 @@ _ssl_SSLSession_timeout_get(PyObject *self, void *Py_UNUSED(context)) PyDoc_STRVAR(_ssl_SSLSession_ticket_lifetime_hint__doc__, "Ticket life time hint."); -#if defined(_ssl_SSLSession_ticket_lifetime_hint_DOCSTR) -# undef _ssl_SSLSession_ticket_lifetime_hint_DOCSTR -#endif -#define _ssl_SSLSession_ticket_lifetime_hint_DOCSTR _ssl_SSLSession_ticket_lifetime_hint__doc__ - -#if !defined(_ssl_SSLSession_ticket_lifetime_hint_DOCSTR) -# define _ssl_SSLSession_ticket_lifetime_hint_DOCSTR NULL -#endif -#if defined(_SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF) -# undef _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF -# define _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF {"ticket_lifetime_hint", (getter)_ssl_SSLSession_ticket_lifetime_hint_get, (setter)_ssl_SSLSession_ticket_lifetime_hint_set, _ssl_SSLSession_ticket_lifetime_hint_DOCSTR}, -#else -# define _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF {"ticket_lifetime_hint", (getter)_ssl_SSLSession_ticket_lifetime_hint_get, NULL, _ssl_SSLSession_ticket_lifetime_hint_DOCSTR}, -#endif static PyObject * _ssl_SSLSession_ticket_lifetime_hint_get_impl(PySSLSession *self); @@ -2893,20 +2598,6 @@ _ssl_SSLSession_ticket_lifetime_hint_get(PyObject *self, void *Py_UNUSED(context PyDoc_STRVAR(_ssl_SSLSession_id__doc__, "Session ID."); -#if defined(_ssl_SSLSession_id_DOCSTR) -# undef _ssl_SSLSession_id_DOCSTR -#endif -#define _ssl_SSLSession_id_DOCSTR _ssl_SSLSession_id__doc__ - -#if !defined(_ssl_SSLSession_id_DOCSTR) -# define _ssl_SSLSession_id_DOCSTR NULL -#endif -#if defined(_SSL_SSLSESSION_ID_GETSETDEF) -# undef _SSL_SSLSESSION_ID_GETSETDEF -# define _SSL_SSLSESSION_ID_GETSETDEF {"id", (getter)_ssl_SSLSession_id_get, (setter)_ssl_SSLSession_id_set, _ssl_SSLSession_id_DOCSTR}, -#else -# define _SSL_SSLSESSION_ID_GETSETDEF {"id", (getter)_ssl_SSLSession_id_get, NULL, _ssl_SSLSession_id_DOCSTR}, -#endif static PyObject * _ssl_SSLSession_id_get_impl(PySSLSession *self); @@ -2925,20 +2616,6 @@ _ssl_SSLSession_id_get(PyObject *self, void *Py_UNUSED(context)) PyDoc_STRVAR(_ssl_SSLSession_has_ticket__doc__, "Does the session contain a ticket?"); -#if defined(_ssl_SSLSession_has_ticket_DOCSTR) -# undef _ssl_SSLSession_has_ticket_DOCSTR -#endif -#define _ssl_SSLSession_has_ticket_DOCSTR _ssl_SSLSession_has_ticket__doc__ - -#if !defined(_ssl_SSLSession_has_ticket_DOCSTR) -# define _ssl_SSLSession_has_ticket_DOCSTR NULL -#endif -#if defined(_SSL_SSLSESSION_HAS_TICKET_GETSETDEF) -# undef _SSL_SSLSESSION_HAS_TICKET_GETSETDEF -# define _SSL_SSLSESSION_HAS_TICKET_GETSETDEF {"has_ticket", (getter)_ssl_SSLSession_has_ticket_get, (setter)_ssl_SSLSession_has_ticket_set, _ssl_SSLSession_has_ticket_DOCSTR}, -#else -# define _SSL_SSLSESSION_HAS_TICKET_GETSETDEF {"has_ticket", (getter)_ssl_SSLSession_has_ticket_get, NULL, _ssl_SSLSession_has_ticket_DOCSTR}, -#endif static PyObject * _ssl_SSLSession_has_ticket_get_impl(PySSLSession *self); @@ -3407,4 +3084,52 @@ _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=f3fc13b81bf9bb6a input=a9049054013a1b77]*/ +#define _SSL__SSLSOCKET_CONTEXT_GETSETDEF {"context", (getter)_ssl__SSLSocket_context_get, (setter)_ssl__SSLSocket_context_set, _ssl__SSLSocket_context__doc__}, + +#define _SSL__SSLSOCKET_SERVER_SIDE_GETSETDEF {"server_side", (getter)_ssl__SSLSocket_server_side_get, (setter)NULL, _ssl__SSLSocket_server_side__doc__}, + +#define _SSL__SSLSOCKET_SERVER_HOSTNAME_GETSETDEF {"server_hostname", (getter)_ssl__SSLSocket_server_hostname_get, (setter)NULL, _ssl__SSLSocket_server_hostname__doc__}, + +#define _SSL__SSLSOCKET_OWNER_GETSETDEF {"owner", (getter)_ssl__SSLSocket_owner_get, (setter)_ssl__SSLSocket_owner_set, _ssl__SSLSocket_owner__doc__}, + +#define _SSL__SSLSOCKET_SESSION_GETSETDEF {"session", (getter)_ssl__SSLSocket_session_get, (setter)_ssl__SSLSocket_session_set, _ssl__SSLSocket_session__doc__}, + +#define _SSL__SSLSOCKET_SESSION_REUSED_GETSETDEF {"session_reused", (getter)_ssl__SSLSocket_session_reused_get, (setter)NULL, _ssl__SSLSocket_session_reused__doc__}, + +#define _SSL__SSLCONTEXT_VERIFY_MODE_GETSETDEF {"verify_mode", (getter)_ssl__SSLContext_verify_mode_get, (setter)_ssl__SSLContext_verify_mode_set, NULL}, + +#define _SSL__SSLCONTEXT_VERIFY_FLAGS_GETSETDEF {"verify_flags", (getter)_ssl__SSLContext_verify_flags_get, (setter)_ssl__SSLContext_verify_flags_set, NULL}, + +#define _SSL__SSLCONTEXT_MINIMUM_VERSION_GETSETDEF {"minimum_version", (getter)_ssl__SSLContext_minimum_version_get, (setter)_ssl__SSLContext_minimum_version_set, NULL}, + +#define _SSL__SSLCONTEXT_MAXIMUM_VERSION_GETSETDEF {"maximum_version", (getter)_ssl__SSLContext_maximum_version_get, (setter)_ssl__SSLContext_maximum_version_set, NULL}, + +#define _SSL__SSLCONTEXT_NUM_TICKETS_GETSETDEF {"num_tickets", (getter)_ssl__SSLContext_num_tickets_get, (setter)_ssl__SSLContext_num_tickets_set, _ssl__SSLContext_num_tickets__doc__}, + +#define _SSL__SSLCONTEXT_SECURITY_LEVEL_GETSETDEF {"security_level", (getter)_ssl__SSLContext_security_level_get, (setter)NULL, _ssl__SSLContext_security_level__doc__}, + +#define _SSL__SSLCONTEXT_OPTIONS_GETSETDEF {"options", (getter)_ssl__SSLContext_options_get, (setter)_ssl__SSLContext_options_set, NULL}, + +#define _SSL__SSLCONTEXT__HOST_FLAGS_GETSETDEF {"_host_flags", (getter)_ssl__SSLContext__host_flags_get, (setter)_ssl__SSLContext__host_flags_set, NULL}, + +#define _SSL__SSLCONTEXT_CHECK_HOSTNAME_GETSETDEF {"check_hostname", (getter)_ssl__SSLContext_check_hostname_get, (setter)_ssl__SSLContext_check_hostname_set, NULL}, + +#define _SSL__SSLCONTEXT_PROTOCOL_GETSETDEF {"protocol", (getter)_ssl__SSLContext_protocol_get, (setter)NULL, NULL}, + +#define _SSL__SSLCONTEXT_SNI_CALLBACK_GETSETDEF {"sni_callback", (getter)_ssl__SSLContext_sni_callback_get, (setter)_ssl__SSLContext_sni_callback_set, _ssl__SSLContext_sni_callback__doc__}, + +#define _SSL_MEMORYBIO_PENDING_GETSETDEF {"pending", (getter)_ssl_MemoryBIO_pending_get, (setter)NULL, _ssl_MemoryBIO_pending__doc__}, + +#define _SSL_MEMORYBIO_EOF_GETSETDEF {"eof", (getter)_ssl_MemoryBIO_eof_get, (setter)NULL, _ssl_MemoryBIO_eof__doc__}, + +#define _SSL_SSLSESSION_TIME_GETSETDEF {"time", (getter)_ssl_SSLSession_time_get, (setter)NULL, _ssl_SSLSession_time__doc__}, + +#define _SSL_SSLSESSION_TIMEOUT_GETSETDEF {"timeout", (getter)_ssl_SSLSession_timeout_get, (setter)NULL, _ssl_SSLSession_timeout__doc__}, + +#define _SSL_SSLSESSION_TICKET_LIFETIME_HINT_GETSETDEF {"ticket_lifetime_hint", (getter)_ssl_SSLSession_ticket_lifetime_hint_get, (setter)NULL, _ssl_SSLSession_ticket_lifetime_hint__doc__}, + +#define _SSL_SSLSESSION_ID_GETSETDEF {"id", (getter)_ssl_SSLSession_id_get, (setter)NULL, _ssl_SSLSession_id__doc__}, + +#define _SSL_SSLSESSION_HAS_TICKET_GETSETDEF {"has_ticket", (getter)_ssl_SSLSession_has_ticket_get, (setter)NULL, _ssl_SSLSession_has_ticket__doc__}, + +/*[clinic end generated code: output=42b28429643df3e3 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/hmacmodule.c.h b/Modules/clinic/hmacmodule.c.h index a31d2ab7f04463..bdff9c4bf8c1df 100644 --- a/Modules/clinic/hmacmodule.c.h +++ b/Modules/clinic/hmacmodule.c.h @@ -204,16 +204,6 @@ _hmac_HMAC_hexdigest(PyObject *self, PyObject *Py_UNUSED(ignored)) return _hmac_HMAC_hexdigest_impl((HMACObject *)self); } -#if !defined(_hmac_HMAC_name_DOCSTR) -# define _hmac_HMAC_name_DOCSTR NULL -#endif -#if defined(_HMAC_HMAC_NAME_GETSETDEF) -# undef _HMAC_HMAC_NAME_GETSETDEF -# define _HMAC_HMAC_NAME_GETSETDEF {"name", (getter)_hmac_HMAC_name_get, (setter)_hmac_HMAC_name_set, _hmac_HMAC_name_DOCSTR}, -#else -# define _HMAC_HMAC_NAME_GETSETDEF {"name", (getter)_hmac_HMAC_name_get, NULL, _hmac_HMAC_name_DOCSTR}, -#endif - static PyObject * _hmac_HMAC_name_get_impl(HMACObject *self); @@ -223,16 +213,6 @@ _hmac_HMAC_name_get(PyObject *self, void *Py_UNUSED(context)) return _hmac_HMAC_name_get_impl((HMACObject *)self); } -#if !defined(_hmac_HMAC_block_size_DOCSTR) -# define _hmac_HMAC_block_size_DOCSTR NULL -#endif -#if defined(_HMAC_HMAC_BLOCK_SIZE_GETSETDEF) -# undef _HMAC_HMAC_BLOCK_SIZE_GETSETDEF -# define _HMAC_HMAC_BLOCK_SIZE_GETSETDEF {"block_size", (getter)_hmac_HMAC_block_size_get, (setter)_hmac_HMAC_block_size_set, _hmac_HMAC_block_size_DOCSTR}, -#else -# define _HMAC_HMAC_BLOCK_SIZE_GETSETDEF {"block_size", (getter)_hmac_HMAC_block_size_get, NULL, _hmac_HMAC_block_size_DOCSTR}, -#endif - static PyObject * _hmac_HMAC_block_size_get_impl(HMACObject *self); @@ -242,16 +222,6 @@ _hmac_HMAC_block_size_get(PyObject *self, void *Py_UNUSED(context)) return _hmac_HMAC_block_size_get_impl((HMACObject *)self); } -#if !defined(_hmac_HMAC_digest_size_DOCSTR) -# define _hmac_HMAC_digest_size_DOCSTR NULL -#endif -#if defined(_HMAC_HMAC_DIGEST_SIZE_GETSETDEF) -# undef _HMAC_HMAC_DIGEST_SIZE_GETSETDEF -# define _HMAC_HMAC_DIGEST_SIZE_GETSETDEF {"digest_size", (getter)_hmac_HMAC_digest_size_get, (setter)_hmac_HMAC_digest_size_set, _hmac_HMAC_digest_size_DOCSTR}, -#else -# define _HMAC_HMAC_DIGEST_SIZE_GETSETDEF {"digest_size", (getter)_hmac_HMAC_digest_size_get, NULL, _hmac_HMAC_digest_size_DOCSTR}, -#endif - static PyObject * _hmac_HMAC_digest_size_get_impl(HMACObject *self); @@ -670,4 +640,10 @@ _hmac_compute_blake2b_32(PyObject *module, PyObject *const *args, Py_ssize_t nar exit: return return_value; } -/*[clinic end generated code: output=6ec5948df1c5569a input=a9049054013a1b77]*/ +#define _HMAC_HMAC_NAME_GETSETDEF {"name", (getter)_hmac_HMAC_name_get, (setter)NULL, NULL}, + +#define _HMAC_HMAC_BLOCK_SIZE_GETSETDEF {"block_size", (getter)_hmac_HMAC_block_size_get, (setter)NULL, NULL}, + +#define _HMAC_HMAC_DIGEST_SIZE_GETSETDEF {"digest_size", (getter)_hmac_HMAC_digest_size_get, (setter)NULL, NULL}, + +/*[clinic end generated code: output=f63101faf6ff6bac input=a9049054013a1b77]*/ diff --git a/Objects/clinic/exceptions.c.h b/Objects/clinic/exceptions.c.h index 5047a673e579c6..31be6c3a2bb2d7 100644 --- a/Objects/clinic/exceptions.c.h +++ b/Objects/clinic/exceptions.c.h @@ -106,16 +106,6 @@ BaseException_add_note(PyObject *self, PyObject *arg) return return_value; } -#if !defined(BaseException_args_DOCSTR) -# define BaseException_args_DOCSTR NULL -#endif -#if defined(BASEEXCEPTION_ARGS_GETSETDEF) -# undef BASEEXCEPTION_ARGS_GETSETDEF -# define BASEEXCEPTION_ARGS_GETSETDEF {"args", (getter)BaseException_args_get, (setter)BaseException_args_set, BaseException_args_DOCSTR}, -#else -# define BASEEXCEPTION_ARGS_GETSETDEF {"args", (getter)BaseException_args_get, NULL, BaseException_args_DOCSTR}, -#endif - static PyObject * BaseException_args_get_impl(PyBaseExceptionObject *self); @@ -131,24 +121,22 @@ BaseException_args_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(BaseException_args_DOCSTR) -# define BaseException_args_DOCSTR NULL -#endif -#if defined(BASEEXCEPTION_ARGS_GETSETDEF) -# undef BASEEXCEPTION_ARGS_GETSETDEF -# define BASEEXCEPTION_ARGS_GETSETDEF {"args", (getter)BaseException_args_get, (setter)BaseException_args_set, BaseException_args_DOCSTR}, -#else -# define BASEEXCEPTION_ARGS_GETSETDEF {"args", NULL, (setter)BaseException_args_set, NULL}, -#endif - static int BaseException_args_set_impl(PyBaseExceptionObject *self, PyObject *value); static int -BaseException_args_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +BaseException_args_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; - + int return_value = -1; + PyObject *value; + + if (arg == NULL) { + PyErr_Format(PyExc_AttributeError, + "attribute 'args' of '%.100s' objects cannot be deleted", + Py_TYPE(self)->tp_name); + return -1; + } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = BaseException_args_set_impl((PyBaseExceptionObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -156,16 +144,6 @@ BaseException_args_set(PyObject *self, PyObject *value, void *Py_UNUSED(context) return return_value; } -#if !defined(BaseException___traceback___DOCSTR) -# define BaseException___traceback___DOCSTR NULL -#endif -#if defined(BASEEXCEPTION___TRACEBACK___GETSETDEF) -# undef BASEEXCEPTION___TRACEBACK___GETSETDEF -# define BASEEXCEPTION___TRACEBACK___GETSETDEF {"__traceback__", (getter)BaseException___traceback___get, (setter)BaseException___traceback___set, BaseException___traceback___DOCSTR}, -#else -# define BASEEXCEPTION___TRACEBACK___GETSETDEF {"__traceback__", (getter)BaseException___traceback___get, NULL, BaseException___traceback___DOCSTR}, -#endif - static PyObject * BaseException___traceback___get_impl(PyBaseExceptionObject *self); @@ -181,25 +159,23 @@ BaseException___traceback___get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(BaseException___traceback___DOCSTR) -# define BaseException___traceback___DOCSTR NULL -#endif -#if defined(BASEEXCEPTION___TRACEBACK___GETSETDEF) -# undef BASEEXCEPTION___TRACEBACK___GETSETDEF -# define BASEEXCEPTION___TRACEBACK___GETSETDEF {"__traceback__", (getter)BaseException___traceback___get, (setter)BaseException___traceback___set, BaseException___traceback___DOCSTR}, -#else -# define BASEEXCEPTION___TRACEBACK___GETSETDEF {"__traceback__", NULL, (setter)BaseException___traceback___set, NULL}, -#endif - static int BaseException___traceback___set_impl(PyBaseExceptionObject *self, PyObject *value); static int -BaseException___traceback___set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +BaseException___traceback___set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; - + int return_value = -1; + PyObject *value; + + if (arg == NULL) { + PyErr_Format(PyExc_AttributeError, + "attribute '__traceback__' of '%.100s' objects cannot be deleted", + Py_TYPE(self)->tp_name); + return -1; + } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = BaseException___traceback___set_impl((PyBaseExceptionObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -207,16 +183,6 @@ BaseException___traceback___set(PyObject *self, PyObject *value, void *Py_UNUSED return return_value; } -#if !defined(BaseException___context___DOCSTR) -# define BaseException___context___DOCSTR NULL -#endif -#if defined(BASEEXCEPTION___CONTEXT___GETSETDEF) -# undef BASEEXCEPTION___CONTEXT___GETSETDEF -# define BASEEXCEPTION___CONTEXT___GETSETDEF {"__context__", (getter)BaseException___context___get, (setter)BaseException___context___set, BaseException___context___DOCSTR}, -#else -# define BASEEXCEPTION___CONTEXT___GETSETDEF {"__context__", (getter)BaseException___context___get, NULL, BaseException___context___DOCSTR}, -#endif - static PyObject * BaseException___context___get_impl(PyBaseExceptionObject *self); @@ -232,25 +198,23 @@ BaseException___context___get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(BaseException___context___DOCSTR) -# define BaseException___context___DOCSTR NULL -#endif -#if defined(BASEEXCEPTION___CONTEXT___GETSETDEF) -# undef BASEEXCEPTION___CONTEXT___GETSETDEF -# define BASEEXCEPTION___CONTEXT___GETSETDEF {"__context__", (getter)BaseException___context___get, (setter)BaseException___context___set, BaseException___context___DOCSTR}, -#else -# define BASEEXCEPTION___CONTEXT___GETSETDEF {"__context__", NULL, (setter)BaseException___context___set, NULL}, -#endif - static int BaseException___context___set_impl(PyBaseExceptionObject *self, PyObject *value); static int -BaseException___context___set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +BaseException___context___set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; - + int return_value = -1; + PyObject *value; + + if (arg == NULL) { + PyErr_Format(PyExc_AttributeError, + "attribute '__context__' of '%.100s' objects cannot be deleted", + Py_TYPE(self)->tp_name); + return -1; + } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = BaseException___context___set_impl((PyBaseExceptionObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -258,16 +222,6 @@ BaseException___context___set(PyObject *self, PyObject *value, void *Py_UNUSED(c return return_value; } -#if !defined(BaseException___cause___DOCSTR) -# define BaseException___cause___DOCSTR NULL -#endif -#if defined(BASEEXCEPTION___CAUSE___GETSETDEF) -# undef BASEEXCEPTION___CAUSE___GETSETDEF -# define BASEEXCEPTION___CAUSE___GETSETDEF {"__cause__", (getter)BaseException___cause___get, (setter)BaseException___cause___set, BaseException___cause___DOCSTR}, -#else -# define BASEEXCEPTION___CAUSE___GETSETDEF {"__cause__", (getter)BaseException___cause___get, NULL, BaseException___cause___DOCSTR}, -#endif - static PyObject * BaseException___cause___get_impl(PyBaseExceptionObject *self); @@ -283,25 +237,23 @@ BaseException___cause___get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(BaseException___cause___DOCSTR) -# define BaseException___cause___DOCSTR NULL -#endif -#if defined(BASEEXCEPTION___CAUSE___GETSETDEF) -# undef BASEEXCEPTION___CAUSE___GETSETDEF -# define BASEEXCEPTION___CAUSE___GETSETDEF {"__cause__", (getter)BaseException___cause___get, (setter)BaseException___cause___set, BaseException___cause___DOCSTR}, -#else -# define BASEEXCEPTION___CAUSE___GETSETDEF {"__cause__", NULL, (setter)BaseException___cause___set, NULL}, -#endif - static int BaseException___cause___set_impl(PyBaseExceptionObject *self, PyObject *value); static int -BaseException___cause___set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +BaseException___cause___set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; - + int return_value = -1; + PyObject *value; + + if (arg == NULL) { + PyErr_Format(PyExc_AttributeError, + "attribute '__cause__' of '%.100s' objects cannot be deleted", + Py_TYPE(self)->tp_name); + return -1; + } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = BaseException___cause___set_impl((PyBaseExceptionObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -380,4 +332,12 @@ BaseExceptionGroup_subgroup(PyObject *self, PyObject *matcher_value) return return_value; } -/*[clinic end generated code: output=e63b88d0443b4f92 input=a9049054013a1b77]*/ +#define BASEEXCEPTION_ARGS_GETSETDEF {"args", (getter)BaseException_args_get, (setter)BaseException_args_set, NULL}, + +#define BASEEXCEPTION___TRACEBACK___GETSETDEF {"__traceback__", (getter)BaseException___traceback___get, (setter)BaseException___traceback___set, NULL}, + +#define BASEEXCEPTION___CONTEXT___GETSETDEF {"__context__", (getter)BaseException___context___get, (setter)BaseException___context___set, NULL}, + +#define BASEEXCEPTION___CAUSE___GETSETDEF {"__cause__", (getter)BaseException___cause___get, (setter)BaseException___cause___set, NULL}, + +/*[clinic end generated code: output=b14d57bb5ad3be0d input=a9049054013a1b77]*/ diff --git a/Objects/clinic/frameobject.c.h b/Objects/clinic/frameobject.c.h index 7b8dab1e015a6b..5d4901833d1ba4 100644 --- a/Objects/clinic/frameobject.c.h +++ b/Objects/clinic/frameobject.c.h @@ -6,20 +6,6 @@ preserve PyDoc_STRVAR(frame_locals__doc__, "Return the mapping used by the frame to look up local variables."); -#if defined(frame_locals_DOCSTR) -# undef frame_locals_DOCSTR -#endif -#define frame_locals_DOCSTR frame_locals__doc__ - -#if !defined(frame_locals_DOCSTR) -# define frame_locals_DOCSTR NULL -#endif -#if defined(FRAME_LOCALS_GETSETDEF) -# undef FRAME_LOCALS_GETSETDEF -# define FRAME_LOCALS_GETSETDEF {"f_locals", (getter)frame_locals_get, (setter)frame_locals_set, frame_locals_DOCSTR}, -#else -# define FRAME_LOCALS_GETSETDEF {"f_locals", (getter)frame_locals_get, NULL, frame_locals_DOCSTR}, -#endif static PyObject * frame_locals_get_impl(PyFrameObject *self); @@ -38,20 +24,6 @@ frame_locals_get(PyObject *self, void *Py_UNUSED(context)) PyDoc_STRVAR(frame_lineno__doc__, "Return the current line number in the frame."); -#if defined(frame_lineno_DOCSTR) -# undef frame_lineno_DOCSTR -#endif -#define frame_lineno_DOCSTR frame_lineno__doc__ - -#if !defined(frame_lineno_DOCSTR) -# define frame_lineno_DOCSTR NULL -#endif -#if defined(FRAME_LINENO_GETSETDEF) -# undef FRAME_LINENO_GETSETDEF -# define FRAME_LINENO_GETSETDEF {"f_lineno", (getter)frame_lineno_get, (setter)frame_lineno_set, frame_lineno_DOCSTR}, -#else -# define FRAME_LINENO_GETSETDEF {"f_lineno", (getter)frame_lineno_get, NULL, frame_lineno_DOCSTR}, -#endif static PyObject * frame_lineno_get_impl(PyFrameObject *self); @@ -70,20 +42,6 @@ frame_lineno_get(PyObject *self, void *Py_UNUSED(context)) PyDoc_STRVAR(frame_lasti__doc__, "Return the index of the last attempted instruction in the frame."); -#if defined(frame_lasti_DOCSTR) -# undef frame_lasti_DOCSTR -#endif -#define frame_lasti_DOCSTR frame_lasti__doc__ - -#if !defined(frame_lasti_DOCSTR) -# define frame_lasti_DOCSTR NULL -#endif -#if defined(FRAME_LASTI_GETSETDEF) -# undef FRAME_LASTI_GETSETDEF -# define FRAME_LASTI_GETSETDEF {"f_lasti", (getter)frame_lasti_get, (setter)frame_lasti_set, frame_lasti_DOCSTR}, -#else -# define FRAME_LASTI_GETSETDEF {"f_lasti", (getter)frame_lasti_get, NULL, frame_lasti_DOCSTR}, -#endif static PyObject * frame_lasti_get_impl(PyFrameObject *self); @@ -102,20 +60,6 @@ frame_lasti_get(PyObject *self, void *Py_UNUSED(context)) PyDoc_STRVAR(frame_globals__doc__, "Return the global variables in the frame."); -#if defined(frame_globals_DOCSTR) -# undef frame_globals_DOCSTR -#endif -#define frame_globals_DOCSTR frame_globals__doc__ - -#if !defined(frame_globals_DOCSTR) -# define frame_globals_DOCSTR NULL -#endif -#if defined(FRAME_GLOBALS_GETSETDEF) -# undef FRAME_GLOBALS_GETSETDEF -# define FRAME_GLOBALS_GETSETDEF {"f_globals", (getter)frame_globals_get, (setter)frame_globals_set, frame_globals_DOCSTR}, -#else -# define FRAME_GLOBALS_GETSETDEF {"f_globals", (getter)frame_globals_get, NULL, frame_globals_DOCSTR}, -#endif static PyObject * frame_globals_get_impl(PyFrameObject *self); @@ -134,20 +78,6 @@ frame_globals_get(PyObject *self, void *Py_UNUSED(context)) PyDoc_STRVAR(frame_builtins__doc__, "Return the built-in variables in the frame."); -#if defined(frame_builtins_DOCSTR) -# undef frame_builtins_DOCSTR -#endif -#define frame_builtins_DOCSTR frame_builtins__doc__ - -#if !defined(frame_builtins_DOCSTR) -# define frame_builtins_DOCSTR NULL -#endif -#if defined(FRAME_BUILTINS_GETSETDEF) -# undef FRAME_BUILTINS_GETSETDEF -# define FRAME_BUILTINS_GETSETDEF {"f_builtins", (getter)frame_builtins_get, (setter)frame_builtins_set, frame_builtins_DOCSTR}, -#else -# define FRAME_BUILTINS_GETSETDEF {"f_builtins", (getter)frame_builtins_get, NULL, frame_builtins_DOCSTR}, -#endif static PyObject * frame_builtins_get_impl(PyFrameObject *self); @@ -166,20 +96,6 @@ frame_builtins_get(PyObject *self, void *Py_UNUSED(context)) PyDoc_STRVAR(frame_code__doc__, "Return the code object being executed in this frame."); -#if defined(frame_code_DOCSTR) -# undef frame_code_DOCSTR -#endif -#define frame_code_DOCSTR frame_code__doc__ - -#if !defined(frame_code_DOCSTR) -# define frame_code_DOCSTR NULL -#endif -#if defined(FRAME_CODE_GETSETDEF) -# undef FRAME_CODE_GETSETDEF -# define FRAME_CODE_GETSETDEF {"f_code", (getter)frame_code_get, (setter)frame_code_set, frame_code_DOCSTR}, -#else -# define FRAME_CODE_GETSETDEF {"f_code", (getter)frame_code_get, NULL, frame_code_DOCSTR}, -#endif static PyObject * frame_code_get_impl(PyFrameObject *self); @@ -190,16 +106,6 @@ frame_code_get(PyObject *self, void *Py_UNUSED(context)) return frame_code_get_impl((PyFrameObject *)self); } -#if !defined(frame_back_DOCSTR) -# define frame_back_DOCSTR NULL -#endif -#if defined(FRAME_BACK_GETSETDEF) -# undef FRAME_BACK_GETSETDEF -# define FRAME_BACK_GETSETDEF {"f_back", (getter)frame_back_get, (setter)frame_back_set, frame_back_DOCSTR}, -#else -# define FRAME_BACK_GETSETDEF {"f_back", (getter)frame_back_get, NULL, frame_back_DOCSTR}, -#endif - static PyObject * frame_back_get_impl(PyFrameObject *self); @@ -217,20 +123,6 @@ frame_back_get(PyObject *self, void *Py_UNUSED(context)) PyDoc_STRVAR(frame_trace_opcodes__doc__, "Return True if opcode tracing is enabled, False otherwise."); -#if defined(frame_trace_opcodes_DOCSTR) -# undef frame_trace_opcodes_DOCSTR -#endif -#define frame_trace_opcodes_DOCSTR frame_trace_opcodes__doc__ - -#if !defined(frame_trace_opcodes_DOCSTR) -# define frame_trace_opcodes_DOCSTR NULL -#endif -#if defined(FRAME_TRACE_OPCODES_GETSETDEF) -# undef FRAME_TRACE_OPCODES_GETSETDEF -# define FRAME_TRACE_OPCODES_GETSETDEF {"f_trace_opcodes", (getter)frame_trace_opcodes_get, (setter)frame_trace_opcodes_set, frame_trace_opcodes_DOCSTR}, -#else -# define FRAME_TRACE_OPCODES_GETSETDEF {"f_trace_opcodes", (getter)frame_trace_opcodes_get, NULL, frame_trace_opcodes_DOCSTR}, -#endif static PyObject * frame_trace_opcodes_get_impl(PyFrameObject *self); @@ -247,30 +139,22 @@ frame_trace_opcodes_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(frame_trace_opcodes_DOCSTR) -# define frame_trace_opcodes_DOCSTR NULL -#endif -#if defined(FRAME_TRACE_OPCODES_GETSETDEF) -# undef FRAME_TRACE_OPCODES_GETSETDEF -# define FRAME_TRACE_OPCODES_GETSETDEF {"f_trace_opcodes", (getter)frame_trace_opcodes_get, (setter)frame_trace_opcodes_set, frame_trace_opcodes_DOCSTR}, -#else -# define FRAME_TRACE_OPCODES_GETSETDEF {"f_trace_opcodes", NULL, (setter)frame_trace_opcodes_set, NULL}, -#endif - static int frame_trace_opcodes_set_impl(PyFrameObject *self, PyObject *value); static int -frame_trace_opcodes_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +frame_trace_opcodes_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'f_trace_opcodes' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = frame_trace_opcodes_set_impl((PyFrameObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -278,30 +162,22 @@ frame_trace_opcodes_set(PyObject *self, PyObject *value, void *Py_UNUSED(context return return_value; } -#if !defined(frame_lineno_DOCSTR) -# define frame_lineno_DOCSTR NULL -#endif -#if defined(FRAME_LINENO_GETSETDEF) -# undef FRAME_LINENO_GETSETDEF -# define FRAME_LINENO_GETSETDEF {"f_lineno", (getter)frame_lineno_get, (setter)frame_lineno_set, frame_lineno_DOCSTR}, -#else -# define FRAME_LINENO_GETSETDEF {"f_lineno", NULL, (setter)frame_lineno_set, NULL}, -#endif - static int frame_lineno_set_impl(PyFrameObject *self, PyObject *value); static int -frame_lineno_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +frame_lineno_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value; - if (value == NULL) { + if (arg == NULL) { PyErr_Format(PyExc_AttributeError, "attribute 'f_lineno' of '%.100s' objects cannot be deleted", Py_TYPE(self)->tp_name); return -1; } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = frame_lineno_set_impl((PyFrameObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -311,20 +187,6 @@ frame_lineno_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) PyDoc_STRVAR(frame_trace__doc__, "Return the trace function for this frame, or None if no trace function is set."); -#if defined(frame_trace_DOCSTR) -# undef frame_trace_DOCSTR -#endif -#define frame_trace_DOCSTR frame_trace__doc__ - -#if !defined(frame_trace_DOCSTR) -# define frame_trace_DOCSTR NULL -#endif -#if defined(FRAME_TRACE_GETSETDEF) -# undef FRAME_TRACE_GETSETDEF -# define FRAME_TRACE_GETSETDEF {"f_trace", (getter)frame_trace_get, (setter)frame_trace_set, frame_trace_DOCSTR}, -#else -# define FRAME_TRACE_GETSETDEF {"f_trace", (getter)frame_trace_get, NULL, frame_trace_DOCSTR}, -#endif static PyObject * frame_trace_get_impl(PyFrameObject *self); @@ -341,24 +203,18 @@ frame_trace_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(frame_trace_DOCSTR) -# define frame_trace_DOCSTR NULL -#endif -#if defined(FRAME_TRACE_GETSETDEF) -# undef FRAME_TRACE_GETSETDEF -# define FRAME_TRACE_GETSETDEF {"f_trace", (getter)frame_trace_get, (setter)frame_trace_set, frame_trace_DOCSTR}, -#else -# define FRAME_TRACE_GETSETDEF {"f_trace", NULL, (setter)frame_trace_set, NULL}, -#endif - static int frame_trace_set_impl(PyFrameObject *self, PyObject *value); static int -frame_trace_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +frame_trace_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value = NULL; + if (arg != NULL) { + value = arg; + } Py_BEGIN_CRITICAL_SECTION(self); return_value = frame_trace_set_impl((PyFrameObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -368,20 +224,6 @@ frame_trace_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) PyDoc_STRVAR(frame_generator__doc__, "Return the generator or coroutine associated with this frame, or None."); -#if defined(frame_generator_DOCSTR) -# undef frame_generator_DOCSTR -#endif -#define frame_generator_DOCSTR frame_generator__doc__ - -#if !defined(frame_generator_DOCSTR) -# define frame_generator_DOCSTR NULL -#endif -#if defined(FRAME_GENERATOR_GETSETDEF) -# undef FRAME_GENERATOR_GETSETDEF -# define FRAME_GENERATOR_GETSETDEF {"f_generator", (getter)frame_generator_get, (setter)frame_generator_set, frame_generator_DOCSTR}, -#else -# define FRAME_GENERATOR_GETSETDEF {"f_generator", (getter)frame_generator_get, NULL, frame_generator_DOCSTR}, -#endif static PyObject * frame_generator_get_impl(PyFrameObject *self); @@ -445,4 +287,24 @@ frame___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored)) return return_value; } -/*[clinic end generated code: output=a42421e56faa7a80 input=a9049054013a1b77]*/ +#define FRAME_F_LOCALS_GETSETDEF {"f_locals", (getter)frame_locals_get, (setter)NULL, frame_locals__doc__}, + +#define FRAME_F_LINENO_GETSETDEF {"f_lineno", (getter)frame_lineno_get, (setter)frame_lineno_set, frame_lineno__doc__}, + +#define FRAME_F_LASTI_GETSETDEF {"f_lasti", (getter)frame_lasti_get, (setter)NULL, frame_lasti__doc__}, + +#define FRAME_F_GLOBALS_GETSETDEF {"f_globals", (getter)frame_globals_get, (setter)NULL, frame_globals__doc__}, + +#define FRAME_F_BUILTINS_GETSETDEF {"f_builtins", (getter)frame_builtins_get, (setter)NULL, frame_builtins__doc__}, + +#define FRAME_F_CODE_GETSETDEF {"f_code", (getter)frame_code_get, (setter)NULL, frame_code__doc__}, + +#define FRAME_F_BACK_GETSETDEF {"f_back", (getter)frame_back_get, (setter)NULL, NULL}, + +#define FRAME_F_TRACE_OPCODES_GETSETDEF {"f_trace_opcodes", (getter)frame_trace_opcodes_get, (setter)frame_trace_opcodes_set, frame_trace_opcodes__doc__}, + +#define FRAME_F_TRACE_GETSETDEF {"f_trace", (getter)frame_trace_get, (setter)frame_trace_set, frame_trace__doc__}, + +#define FRAME_F_GENERATOR_GETSETDEF {"f_generator", (getter)frame_generator_get, (setter)NULL, frame_generator__doc__}, + +/*[clinic end generated code: output=dfa59114b6dbce08 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/funcobject.c.h b/Objects/clinic/funcobject.c.h index fec743146466a4..fa581e553aca8a 100644 --- a/Objects/clinic/funcobject.c.h +++ b/Objects/clinic/funcobject.c.h @@ -11,20 +11,6 @@ preserve PyDoc_STRVAR(function___annotate____doc__, "Get the code object for a function."); -#if defined(function___annotate___DOCSTR) -# undef function___annotate___DOCSTR -#endif -#define function___annotate___DOCSTR function___annotate____doc__ - -#if !defined(function___annotate___DOCSTR) -# define function___annotate___DOCSTR NULL -#endif -#if defined(FUNCTION___ANNOTATE___GETSETDEF) -# undef FUNCTION___ANNOTATE___GETSETDEF -# define FUNCTION___ANNOTATE___GETSETDEF {"__annotate__", (getter)function___annotate___get, (setter)function___annotate___set, function___annotate___DOCSTR}, -#else -# define FUNCTION___ANNOTATE___GETSETDEF {"__annotate__", (getter)function___annotate___get, NULL, function___annotate___DOCSTR}, -#endif static PyObject * function___annotate___get_impl(PyFunctionObject *self); @@ -41,24 +27,22 @@ function___annotate___get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(function___annotate___DOCSTR) -# define function___annotate___DOCSTR NULL -#endif -#if defined(FUNCTION___ANNOTATE___GETSETDEF) -# undef FUNCTION___ANNOTATE___GETSETDEF -# define FUNCTION___ANNOTATE___GETSETDEF {"__annotate__", (getter)function___annotate___get, (setter)function___annotate___set, function___annotate___DOCSTR}, -#else -# define FUNCTION___ANNOTATE___GETSETDEF {"__annotate__", NULL, (setter)function___annotate___set, NULL}, -#endif - static int function___annotate___set_impl(PyFunctionObject *self, PyObject *value); static int -function___annotate___set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +function___annotate___set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; - + int return_value = -1; + PyObject *value; + + if (arg == NULL) { + PyErr_Format(PyExc_AttributeError, + "attribute '__annotate__' of '%.100s' objects cannot be deleted", + Py_TYPE(self)->tp_name); + return -1; + } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = function___annotate___set_impl((PyFunctionObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -68,20 +52,6 @@ function___annotate___set(PyObject *self, PyObject *value, void *Py_UNUSED(conte PyDoc_STRVAR(function___annotations____doc__, "Dict of annotations in a function object."); -#if defined(function___annotations___DOCSTR) -# undef function___annotations___DOCSTR -#endif -#define function___annotations___DOCSTR function___annotations____doc__ - -#if !defined(function___annotations___DOCSTR) -# define function___annotations___DOCSTR NULL -#endif -#if defined(FUNCTION___ANNOTATIONS___GETSETDEF) -# undef FUNCTION___ANNOTATIONS___GETSETDEF -# define FUNCTION___ANNOTATIONS___GETSETDEF {"__annotations__", (getter)function___annotations___get, (setter)function___annotations___set, function___annotations___DOCSTR}, -#else -# define FUNCTION___ANNOTATIONS___GETSETDEF {"__annotations__", (getter)function___annotations___get, NULL, function___annotations___DOCSTR}, -#endif static PyObject * function___annotations___get_impl(PyFunctionObject *self); @@ -98,24 +68,18 @@ function___annotations___get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(function___annotations___DOCSTR) -# define function___annotations___DOCSTR NULL -#endif -#if defined(FUNCTION___ANNOTATIONS___GETSETDEF) -# undef FUNCTION___ANNOTATIONS___GETSETDEF -# define FUNCTION___ANNOTATIONS___GETSETDEF {"__annotations__", (getter)function___annotations___get, (setter)function___annotations___set, function___annotations___DOCSTR}, -#else -# define FUNCTION___ANNOTATIONS___GETSETDEF {"__annotations__", NULL, (setter)function___annotations___set, NULL}, -#endif - static int function___annotations___set_impl(PyFunctionObject *self, PyObject *value); static int -function___annotations___set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +function___annotations___set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; + int return_value = -1; + PyObject *value = NULL; + if (arg != NULL) { + value = arg; + } Py_BEGIN_CRITICAL_SECTION(self); return_value = function___annotations___set_impl((PyFunctionObject *)self, value); Py_END_CRITICAL_SECTION(); @@ -125,20 +89,6 @@ function___annotations___set(PyObject *self, PyObject *value, void *Py_UNUSED(co PyDoc_STRVAR(function___type_params____doc__, "Get the declared type parameters for a function."); -#if defined(function___type_params___DOCSTR) -# undef function___type_params___DOCSTR -#endif -#define function___type_params___DOCSTR function___type_params____doc__ - -#if !defined(function___type_params___DOCSTR) -# define function___type_params___DOCSTR NULL -#endif -#if defined(FUNCTION___TYPE_PARAMS___GETSETDEF) -# undef FUNCTION___TYPE_PARAMS___GETSETDEF -# define FUNCTION___TYPE_PARAMS___GETSETDEF {"__type_params__", (getter)function___type_params___get, (setter)function___type_params___set, function___type_params___DOCSTR}, -#else -# define FUNCTION___TYPE_PARAMS___GETSETDEF {"__type_params__", (getter)function___type_params___get, NULL, function___type_params___DOCSTR}, -#endif static PyObject * function___type_params___get_impl(PyFunctionObject *self); @@ -155,28 +105,31 @@ function___type_params___get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(function___type_params___DOCSTR) -# define function___type_params___DOCSTR NULL -#endif -#if defined(FUNCTION___TYPE_PARAMS___GETSETDEF) -# undef FUNCTION___TYPE_PARAMS___GETSETDEF -# define FUNCTION___TYPE_PARAMS___GETSETDEF {"__type_params__", (getter)function___type_params___get, (setter)function___type_params___set, function___type_params___DOCSTR}, -#else -# define FUNCTION___TYPE_PARAMS___GETSETDEF {"__type_params__", NULL, (setter)function___type_params___set, NULL}, -#endif - static int function___type_params___set_impl(PyFunctionObject *self, PyObject *value); static int -function___type_params___set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +function___type_params___set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; - + int return_value = -1; + PyObject *value; + + if (arg == NULL) { + PyErr_Format(PyExc_AttributeError, + "attribute '__type_params__' of '%.100s' objects cannot be deleted", + Py_TYPE(self)->tp_name); + return -1; + } + if (!PyTuple_Check(arg)) { + PyErr_Format(PyExc_TypeError, "attribute '__type_params__' must be tuple, not %T", arg); + goto exit; + } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = function___type_params___set_impl((PyFunctionObject *)self, value); Py_END_CRITICAL_SECTION(); +exit: return return_value; } @@ -290,4 +243,10 @@ func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=12cb900088d41bdb input=a9049054013a1b77]*/ +#define FUNCTION___ANNOTATE___GETSETDEF {"__annotate__", (getter)function___annotate___get, (setter)function___annotate___set, function___annotate____doc__}, + +#define FUNCTION___ANNOTATIONS___GETSETDEF {"__annotations__", (getter)function___annotations___get, (setter)function___annotations___set, function___annotations____doc__}, + +#define FUNCTION___TYPE_PARAMS___GETSETDEF {"__type_params__", (getter)function___type_params___get, (setter)function___type_params___set, function___type_params____doc__}, + +/*[clinic end generated code: output=b722bea4e9d8b8be input=a9049054013a1b77]*/ diff --git a/Objects/exceptions.c b/Objects/exceptions.c index cc3e03baa4c7df..781b5142ec326e 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -346,19 +346,14 @@ BaseException_args_get_impl(PyBaseExceptionObject *self) /*[clinic input] @critical_section @setter -@deleter BaseException.args [clinic start generated code]*/ static int BaseException_args_set_impl(PyBaseExceptionObject *self, PyObject *value) -/*[clinic end generated code: output=331137e11d8f9e80 input=177ad350c8b45219]*/ +/*[clinic end generated code: output=331137e11d8f9e80 input=2400047ea5970a84]*/ { PyObject *seq; - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, "args may not be deleted"); - return -1; - } seq = PySequence_Tuple(value); if (!seq) return -1; @@ -386,19 +381,14 @@ BaseException___traceback___get_impl(PyBaseExceptionObject *self) /*[clinic input] @critical_section @setter -@deleter BaseException.__traceback__ [clinic start generated code]*/ static int BaseException___traceback___set_impl(PyBaseExceptionObject *self, PyObject *value) -/*[clinic end generated code: output=a82c86d9f29f48f0 input=53a1df586023d786]*/ +/*[clinic end generated code: output=a82c86d9f29f48f0 input=12676035676badad]*/ { - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted"); - return -1; - } if (PyTraceBack_Check(value)) { Py_XSETREF(self->traceback, Py_NewRef(value)); } @@ -432,19 +422,15 @@ BaseException___context___get_impl(PyBaseExceptionObject *self) /*[clinic input] @critical_section @setter -@deleter BaseException.__context__ [clinic start generated code]*/ static int BaseException___context___set_impl(PyBaseExceptionObject *self, PyObject *value) -/*[clinic end generated code: output=b4cb52dcca1da3bd input=fe79e7c0a0854004]*/ +/*[clinic end generated code: output=b4cb52dcca1da3bd input=c0971adf47fa1858]*/ { - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, "__context__ may not be deleted"); - return -1; - } else if (value == Py_None) { + if (value == Py_None) { value = NULL; } else if (!PyExceptionInstance_Check(value)) { PyErr_SetString(PyExc_TypeError, "exception context must be None " @@ -476,19 +462,15 @@ BaseException___cause___get_impl(PyBaseExceptionObject *self) /*[clinic input] @critical_section @setter -@deleter BaseException.__cause__ [clinic start generated code]*/ static int BaseException___cause___set_impl(PyBaseExceptionObject *self, PyObject *value) -/*[clinic end generated code: output=6161315398aaf541 input=3fdd9a0d1674abc9]*/ +/*[clinic end generated code: output=6161315398aaf541 input=e1b403c0bde3f62a]*/ { - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, "__cause__ may not be deleted"); - return -1; - } else if (value == Py_None) { + if (value == Py_None) { value = NULL; } else if (!PyExceptionInstance_Check(value)) { PyErr_SetString(PyExc_TypeError, "exception cause must be None " diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 5889cdaf2aa165..c920e6cfc89c3b 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -1906,16 +1906,16 @@ frame_generator_get_impl(PyFrameObject *self) static PyGetSetDef frame_getsetlist[] = { - FRAME_BACK_GETSETDEF - FRAME_LOCALS_GETSETDEF - FRAME_LINENO_GETSETDEF - FRAME_TRACE_GETSETDEF - FRAME_LASTI_GETSETDEF - FRAME_GLOBALS_GETSETDEF - FRAME_BUILTINS_GETSETDEF - FRAME_CODE_GETSETDEF - FRAME_TRACE_OPCODES_GETSETDEF - FRAME_GENERATOR_GETSETDEF + FRAME_F_BACK_GETSETDEF + FRAME_F_LOCALS_GETSETDEF + FRAME_F_LINENO_GETSETDEF + FRAME_F_TRACE_GETSETDEF + FRAME_F_LASTI_GETSETDEF + FRAME_F_GLOBALS_GETSETDEF + FRAME_F_BUILTINS_GETSETDEF + FRAME_F_CODE_GETSETDEF + FRAME_F_TRACE_OPCODES_GETSETDEF + FRAME_F_GENERATOR_GETSETDEF {0} }; diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 0481adadf668f8..4d3da234f87e49 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -926,19 +926,13 @@ function___annotate___get_impl(PyFunctionObject *self) /*[clinic input] @critical_section @setter -@deleter function.__annotate__ [clinic start generated code]*/ static int function___annotate___set_impl(PyFunctionObject *self, PyObject *value) -/*[clinic end generated code: output=05b7dfc07ada66cd input=4bcfad0bdcfec768]*/ +/*[clinic end generated code: output=05b7dfc07ada66cd input=eb6225e358d97448]*/ { - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "__annotate__ cannot be deleted"); - return -1; - } if (Py_IsNone(value)) { Py_XSETREF(self->func_annotate, Py_NewRef(value)); return 0; @@ -1027,21 +1021,14 @@ function___type_params___get_impl(PyFunctionObject *self) /*[clinic input] @critical_section @setter -@deleter function.__type_params__ + value: object(subclass_of='&PyTuple_Type') [clinic start generated code]*/ static int function___type_params___set_impl(PyFunctionObject *self, PyObject *value) -/*[clinic end generated code: output=038b4cda220e56fb input=c0e33abc5901a2f5]*/ +/*[clinic end generated code: output=038b4cda220e56fb input=e848b79ec6fec497]*/ { - /* Not legal to del f.__type_params__ or to set it to anything - * other than a tuple object. */ - if (value == NULL || !PyTuple_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "__type_params__ must be set to a tuple"); - return -1; - } Py_XSETREF(self->func_typeparams, Py_NewRef(value)); return 0; } diff --git a/Python/clinic/traceback.c.h b/Python/clinic/traceback.c.h index deae2efa3eb28d..8df082c5df831a 100644 --- a/Python/clinic/traceback.c.h +++ b/Python/clinic/traceback.c.h @@ -83,16 +83,6 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) return return_value; } -#if !defined(traceback_tb_next_DOCSTR) -# define traceback_tb_next_DOCSTR NULL -#endif -#if defined(TRACEBACK_TB_NEXT_GETSETDEF) -# undef TRACEBACK_TB_NEXT_GETSETDEF -# define TRACEBACK_TB_NEXT_GETSETDEF {"tb_next", (getter)traceback_tb_next_get, (setter)traceback_tb_next_set, traceback_tb_next_DOCSTR}, -#else -# define TRACEBACK_TB_NEXT_GETSETDEF {"tb_next", (getter)traceback_tb_next_get, NULL, traceback_tb_next_DOCSTR}, -#endif - static PyObject * traceback_tb_next_get_impl(PyTracebackObject *self); @@ -108,28 +98,28 @@ traceback_tb_next_get(PyObject *self, void *Py_UNUSED(context)) return return_value; } -#if !defined(traceback_tb_next_DOCSTR) -# define traceback_tb_next_DOCSTR NULL -#endif -#if defined(TRACEBACK_TB_NEXT_GETSETDEF) -# undef TRACEBACK_TB_NEXT_GETSETDEF -# define TRACEBACK_TB_NEXT_GETSETDEF {"tb_next", (getter)traceback_tb_next_get, (setter)traceback_tb_next_set, traceback_tb_next_DOCSTR}, -#else -# define TRACEBACK_TB_NEXT_GETSETDEF {"tb_next", NULL, (setter)traceback_tb_next_set, NULL}, -#endif - static int traceback_tb_next_set_impl(PyTracebackObject *self, PyObject *value); static int -traceback_tb_next_set(PyObject *self, PyObject *value, void *Py_UNUSED(context)) +traceback_tb_next_set(PyObject *self, PyObject *arg, void *Py_UNUSED(context)) { - int return_value; - + int return_value = -1; + PyObject *value; + + if (arg == NULL) { + PyErr_Format(PyExc_AttributeError, + "attribute 'tb_next' of '%.100s' objects cannot be deleted", + Py_TYPE(self)->tp_name); + return -1; + } + value = arg; Py_BEGIN_CRITICAL_SECTION(self); return_value = traceback_tb_next_set_impl((PyTracebackObject *)self, value); Py_END_CRITICAL_SECTION(); return return_value; } -/*[clinic end generated code: output=5361141395da963e input=a9049054013a1b77]*/ +#define TRACEBACK_TB_NEXT_GETSETDEF {"tb_next", (getter)traceback_tb_next_get, (setter)traceback_tb_next_set, NULL}, + +/*[clinic end generated code: output=0f7bb7a58d9f8d65 input=a9049054013a1b77]*/ diff --git a/Python/traceback.c b/Python/traceback.c index c8b3dbaeb45237..ca94a735db5b8f 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -174,19 +174,13 @@ tb_lineno_get(PyObject *op, void *Py_UNUSED(_)) /*[clinic input] @critical_section @setter -@deleter traceback.tb_next [clinic start generated code]*/ static int traceback_tb_next_set_impl(PyTracebackObject *self, PyObject *value) -/*[clinic end generated code: output=d4868cbc48f2adac input=936201ff689c5700]*/ +/*[clinic end generated code: output=d4868cbc48f2adac input=ce66367f85e3c443]*/ { - if (!value) { - PyErr_Format(PyExc_TypeError, "can't delete tb_next attribute"); - return -1; - } - /* We accept None or a traceback object, and map None -> NULL (inverse of tb_next_get) */ if (value == Py_None) { diff --git a/Tools/clinic/libclinic/app.py b/Tools/clinic/libclinic/app.py index 6768029be2a7db..8cb9d38ebe4a2b 100644 --- a/Tools/clinic/libclinic/app.py +++ b/Tools/clinic/libclinic/app.py @@ -15,7 +15,7 @@ if TYPE_CHECKING: from libclinic.clanguage import CLanguage from libclinic.function import ( - Module, Function, ClassDict, ModuleDict) + Module, Function, Property, ClassDict, ModuleDict) from libclinic.codegen import DestinationDict @@ -103,6 +103,8 @@ def __init__( self.modules: ModuleDict = {} self.classes: ClassDict = {} self.functions: list[Function] = [] + # The attributes implemented by accessors, in the order of definition. + self.properties: list[Property] = [] self.codegen = CodeGen(self.limited_capi) self.line_prefix = self.line_suffix = '' @@ -197,6 +199,10 @@ def parse(self, input: str) -> str: parser.parse(block) printer.print_block(block) + # The entry of an attribute is composed of all its accessors, so it + # is rendered when the whole file is parsed. + self.language.render_properties(self) + # these are destinations not buffers for name, destination in self.destinations.items(): if destination.type == 'suppress': diff --git a/Tools/clinic/libclinic/clanguage.py b/Tools/clinic/libclinic/clanguage.py index ff6749ad1fe173..1f71c6cda81b81 100644 --- a/Tools/clinic/libclinic/clanguage.py +++ b/Tools/clinic/libclinic/clanguage.py @@ -10,12 +10,14 @@ from libclinic.codegen import CRenderData, CodeGen from libclinic.language import Language from libclinic.function import ( - Module, Class, Function, Parameter, + Module, Class, Property, Function, Parameter, group_to_variable_name, - GETTER, METHOD_INIT, METHOD_NEW, + METHOD_INIT, METHOD_NEW, ACCESSORS, SETTERS) from libclinic.converters import self_converter -from libclinic.parse_args import ParseArgsCodeGen +from libclinic.parse_args import ( + ParseArgsCodeGen, + GETSETDEF_PROTOTYPE_COMBINE, GETSETDEF_PROTOTYPE_DEFINE) if TYPE_CHECKING: from libclinic.app import Clinic @@ -84,6 +86,61 @@ def render( function = o return self.render_function(clinic, function) + def render_properties(self, clinic: Clinic) -> None: + """Compose the PyGetSetDef entry of every attribute not composed yet. + + All accessors of an attribute are only known when all blocks of the + file are rendered or the destination is dumped. + """ + destination = clinic.destination_buffers['methoddef_ifndef'] + for prop in clinic.properties: + if prop.rendered: + continue + prop.rendered = True + s = self.render_property(prop) + '\n' + if clinic.line_prefix: + s = libclinic.indent_all_lines(s, clinic.line_prefix) + if clinic.line_suffix: + s = libclinic.suffix_all_lines(s, clinic.line_suffix) + destination.append(s) + + def render_property(self, prop: Property) -> str: + getset_name = prop.getset_name + template_dict = { + 'name': prop.name, + 'getset_name': getset_name, + } + parts: list[str] = [] + if prop.is_plain: + getter = prop.getter[0] if prop.getter else None + setter = prop.setter[0] if prop.setter else None + template_dict['getter'] = (getter.accessor_basename if getter + else 'NULL') + template_dict['setter'] = (setter.accessor_basename if setter + else 'NULL') + template_dict['docstr'] = (f'{getter.c_basename}__doc__' + if getter and getter.docstring + else 'NULL') + parts.append(GETSETDEF_PROTOTYPE_DEFINE.format_map(template_dict) + + '\n') + else: + # Which of the conditionally compiled accessors are compiled is + # only known to the preprocessor. They announce themselves, so + # only the unconditional ones are announced here. + for suffix, funcs in (('GETTER', prop.getter), + ('SETTER', prop.setter)): + for func in funcs: + if func.condition: + continue + parts.append(f"#define {getset_name}_{suffix} " + f"{func.accessor_basename}\n") + if suffix == 'GETTER' and func.docstring: + parts.append(f"#define {getset_name}_DOCSTR " + f"{func.c_basename}__doc__\n") + parts.append(GETSETDEF_PROTOTYPE_COMBINE.format_map(template_dict) + + '\n') + return ''.join(parts) + def compiler_deprecated_warning( self, func: Function, @@ -331,15 +388,12 @@ def render_function( template_dict = {'full_name': full_name} template_dict['name'] = f.displayname if f.kind in ACCESSORS: - template_dict['getset_name'] = f.c_basename.upper() + # The accessors of the same attribute are rendered into a single + # PyGetSetDef entry, which is identified by the Python name. + assert f.property is not None + template_dict['getset_name'] = f.property.getset_name template_dict['getset_basename'] = f.c_basename - if f.kind is GETTER: - template_dict['c_basename'] = f.c_basename + "_get" - else: - template_dict['c_basename'] = f.c_basename + "_set" - # Implicitly add the setter value parameter. - data.impl_parameters.append("PyObject *value") - data.impl_arguments.append("value") + template_dict['c_basename'] = f.accessor_basename else: template_dict['methoddef_name'] = f.c_basename.upper() + "_METHODDEF" template_dict['c_basename'] = f.c_basename diff --git a/Tools/clinic/libclinic/converter.py b/Tools/clinic/libclinic/converter.py index a21478678a478c..0caa8a8956f999 100644 --- a/Tools/clinic/libclinic/converter.py +++ b/Tools/clinic/libclinic/converter.py @@ -8,7 +8,7 @@ from libclinic import fail from libclinic import Sentinels, unspecified, unknown, NULL from libclinic.codegen import CRenderData, Include, TemplateDict -from libclinic.function import Function, Parameter +from libclinic.function import Function, Parameter, SETTERS CConverterClassT = TypeVar("CConverterClassT", bound=type["CConverter"]) @@ -485,6 +485,16 @@ def pre_render(self) -> None: def bad_argument(self, displayname: str, expected: str, *, limited_capi: bool, expected_literal: bool = True) -> str: assert '"' not in expected + if self.function.kind in SETTERS: + # The value of an attribute, not an argument of a function. + if expected_literal: + return (f'PyErr_Format(PyExc_TypeError, ' + f'"attribute \'{{{{name}}}}\' must be {expected}, not %T", ' + f'{{argname}});') + else: + return (f'PyErr_Format(PyExc_TypeError, ' + f'"attribute \'{{{{name}}}}\' must be %s, not %T", ' + f'"{expected}", {{argname}});') if limited_capi: if expected_literal: return (f'PyErr_Format(PyExc_TypeError, ' diff --git a/Tools/clinic/libclinic/dsl_parser.py b/Tools/clinic/libclinic/dsl_parser.py index bbb7939c2e1575..a798fac4f3fd09 100644 --- a/Tools/clinic/libclinic/dsl_parser.py +++ b/Tools/clinic/libclinic/dsl_parser.py @@ -15,14 +15,15 @@ ClinicError, VersionTuple, fail, warn, unspecified, unknown, NULL) from libclinic.function import ( - Module, Class, Function, Parameter, + Module, Class, Property, Function, Parameter, FunctionKind, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW, + GETTER, SETTER, SETTER_AND_DELETER, ACCESSORS, SETTERS) from libclinic.converter import ( converters, legacy_converters) from libclinic.converters import ( - self_converter, defining_class_converter, + self_converter, defining_class_converter, object_converter, correct_name_for_self) from libclinic.return_converters import ( CReturnConverter, return_converters, @@ -418,6 +419,8 @@ def directive_output( fd[command_or_name] = d def directive_dump(self, name: str) -> None: + # The entries of attributes are composed before they are dumped. + self.clinic.language.render_properties(self.clinic) self.block.output.append(self.clinic.get_destination(name).dump()) def directive_printout(self, *args: str) -> None: @@ -646,8 +649,8 @@ def resolve_return_converter( self, full_name: str, forced_converter: str ) -> CReturnConverter: if forced_converter: - if self.kind in ACCESSORS: - fail("@getter and @setter methods cannot define a return type") + if self.kind in SETTERS: + fail("@setter methods cannot define a return type") if self.kind is METHOD_INIT: fail("__init__ methods cannot define a return type") ast_input = f"def x() -> {forced_converter}: pass" @@ -711,6 +714,9 @@ def parse_cloned_function(self, names: FunctionNames, existing: str) -> None: fail("'kind' of function and cloned function don't match! " "(@classmethod/@staticmethod/@coexist)") function = existing_function.copy(**overrides) + function.condition = self.clinic.language.cpp.condition() + if function.kind in ACCESSORS: + self.add_accessor(function) self.function = function self.block.signatures.append(function) (cls or module).functions.append(function) @@ -777,21 +783,9 @@ def state_modulename_name(self, line: str) -> None: self.next(self.state_parameters_start) def add_function(self, func: Function) -> None: + func.condition = self.clinic.language.cpp.condition() if func.kind in ACCESSORS: - # The accessors of the same attribute are rendered into a single - # PyGetSetDef entry, which is identified by the C basename, so - # they must share it. - for other in (func.cls or func.module).functions: - if (other.kind in ACCESSORS - and other.full_name == func.full_name): - if (other.kind is func.kind - or {other.kind, func.kind} <= SETTERS): - kind = 'setter' if func.kind in SETTERS else 'getter' - fail(f"Cannot apply @{kind} to " - f"{func.full_name!r} twice") - if other.c_basename != func.c_basename: - fail(f"The accessors of {func.full_name!r} " - f"must have the same C basename") + self.add_accessor(func) # Insert a self converter automatically. tp, name = correct_name_for_self(func) @@ -811,6 +805,28 @@ def add_function(self, func: Function) -> None: self.function = func (func.cls or func.module).functions.append(func) + def add_accessor(self, func: Function) -> None: + """Add an accessor to the attribute which it implements.""" + assert func.cls is not None + prop = func.cls.properties.get(func.name) + if prop is not None and prop.rendered: + fail(f"All accessors of {func.full_name!r} must be defined " + f"before its PyGetSetDef entry is dumped") + if prop is None: + prop = Property(func.name, func.full_name, func.cls) + func.cls.properties[func.name] = prop + self.clinic.properties.append(prop) + func.property = prop + slot = prop.getter if func.kind is GETTER else prop.setter + # Several implementations of the same accessor can share the slot if + # each of them is compiled under its own preprocessor condition. + if slot and (not func.condition + or any(not other.condition for other in slot)): + if func.kind is GETTER: + fail(f"Cannot apply @getter to {func.full_name!r} twice") + fail(f"The setter of {func.full_name!r} is already defined") + slot.append(func) + # Now entering the parameters section. The rules, formally stated: # # * All lines must be indented with spaces only. @@ -875,8 +891,8 @@ def state_parameters_start(self, line: str) -> None: return self.next(self.state_function_docstring, line) assert self.function is not None - if self.function.kind in ACCESSORS: - fail("@getter and @setter methods cannot define parameters") + if self.function.kind is GETTER: + fail("@getter methods cannot define parameters") self.parameter_continuation = '' return self.next(self.state_parameter, line) @@ -899,6 +915,10 @@ def state_parameter(self, line: str) -> None: if not self.valid_line(line): return + if self.function.kind in SETTERS and len(self.function.parameters) > 1: + # The only parameter of a setter is the new value. + fail("@setter methods must define exactly one parameter") + if self.parameter_continuation: line = self.parameter_continuation + ' ' + line.lstrip() self.parameter_continuation = '' @@ -1617,6 +1637,34 @@ def do_post_block_processing_cleanup(self, lineno: int) -> None: if not self.function: return + func = self.function + if func.kind in (SETTER, SETTER_AND_DELETER): + # The new value is the only parameter of a setter. The setter + # of a deletable attribute is also called with NULL to delete it, + # hence the default value. + optional = func.kind is SETTER_AND_DELETER + if len(func.parameters) == 1: + # It is optional to declare the value, which is usually + # a plain object. + default = NULL if optional else unspecified + converter = object_converter('value', 'value', func, default) + func.parameters['value'] = Parameter( + 'value', inspect.Parameter.POSITIONAL_ONLY, + function=func, converter=converter, default=default) + else: + p = list(func.parameters.values())[1] + if p.is_keyword_only() or p.is_variable_length(): + fail("the value of @setter must be a positional parameter") + if p.is_optional() != optional: + if optional: + fail("the value of @setter with @deleter must have " + "a default value, used to delete the attribute") + else: + fail("the value of @setter cannot have a default value") + if optional and p.default is not NULL: + fail("the value of @setter with @deleter can only have " + "NULL as a default value") + self.check_remaining_star(lineno) self.check_vectorcall_parameters(lineno) try: @@ -1645,7 +1693,7 @@ def render_text_signature( if f.forced_text_signature: lines.append(f.forced_text_signature) elif f.kind in ACCESSORS: - # @getter and @setter do not need signatures like a method or a function. + # Accessors do not need signatures like a method or a function. return '' else: lines.append('(') diff --git a/Tools/clinic/libclinic/function.py b/Tools/clinic/libclinic/function.py index 83d929fcc9207a..e5d7469bb732aa 100644 --- a/Tools/clinic/libclinic/function.py +++ b/Tools/clinic/libclinic/function.py @@ -18,6 +18,7 @@ ClassDict = dict[str, "Class"] ModuleDict = dict[str, "Module"] ParamDict = dict[str, "Parameter"] +PropertyDict = dict[str, "Property"] @dc.dataclass(repr=False) @@ -47,11 +48,43 @@ def __post_init__(self) -> None: self.parent = self.cls or self.module self.classes: ClassDict = {} self.functions: list[Function] = [] + self.properties: PropertyDict = {} def __repr__(self) -> str: return "" +@dc.dataclass(repr=False) +class Property: + """An attribute implemented by accessors, rendered into a PyGetSetDef entry. + + A slot can contain several implementations if they are guarded by + preprocessor conditions. + """ + name: str + full_name: str + cls: Class + + def __post_init__(self) -> None: + self.getter: list[Function] = [] + self.setter: list[Function] = [] + self.rendered = False + + def __repr__(self) -> str: + return "" + + @property + def is_plain(self) -> bool: + """Can the entry be composed without the help of the preprocessor?""" + return all(len(funcs) <= 1 and not (funcs and funcs[0].condition) + for funcs in (self.getter, self.setter)) + + @property + def getset_name(self) -> str: + """The prefix of the names of the macros of the entry.""" + return self.full_name.replace('.', '_').upper() + + class FunctionKind(enum.Enum): CALLABLE = enum.auto() STATIC_METHOD = enum.auto() @@ -127,8 +160,20 @@ class Function: def __post_init__(self) -> None: self.parent = self.cls or self.module self.self_converter: self_converter | None = None + # The attribute implemented by an accessor, and the preprocessor + # condition under which it is compiled. + self.property: Property | None = None + self.condition: str = '' self.__render_parameters__: list[Parameter] | None = None + @functools.cached_property + def accessor_basename(self) -> str: + """The name of the C function which implements this accessor.""" + assert self.kind in ACCESSORS + if self.kind is GETTER: + return self.c_basename + "_get" + return self.c_basename + "_set" + @functools.cached_property def displayname(self) -> str: """Pretty-printable name.""" diff --git a/Tools/clinic/libclinic/language.py b/Tools/clinic/libclinic/language.py index 15975430c16022..c8da0c724f45ba 100644 --- a/Tools/clinic/libclinic/language.py +++ b/Tools/clinic/libclinic/language.py @@ -35,6 +35,9 @@ def render( def parse_line(self, line: str) -> None: ... + def render_properties(self, clinic: Clinic) -> None: + ... + def validate(self) -> None: def assert_only_one( attr: str, diff --git a/Tools/clinic/libclinic/parse_args.py b/Tools/clinic/libclinic/parse_args.py index 4b6b54bc4febf3..4caab253fe32cc 100644 --- a/Tools/clinic/libclinic/parse_args.py +++ b/Tools/clinic/libclinic/parse_args.py @@ -6,7 +6,7 @@ from libclinic.function import ( Function, Parameter, ParamTuple, count_required, group_to_variable_name, permute_optional_groups, - GETTER, SETTER, METHOD_INIT, + GETTER, SETTER, SETTER_AND_DELETER, METHOD_INIT, ACCESSORS, SETTERS) from libclinic.converter import CConverter from libclinic.converters import ( @@ -140,7 +140,7 @@ def declare_parser( """) PARSER_PROTOTYPE_SETTER: Final[str] = libclinic.normalize_snippet(""" static int - {c_basename}({self_type}{self_name}, PyObject *value, void *Py_UNUSED(context)) + {c_basename}({self_type}{self_name}, PyObject *arg, void *Py_UNUSED(context)) """) METH_O_PROTOTYPE: Final[str] = libclinic.normalize_snippet(""" static PyObject * @@ -153,13 +153,20 @@ def declare_parser( PyDoc_STRVAR({c_basename}__doc__, {docstring}); """) +# The docstring of an attribute is defined by its getter. GETSET_DOCSTRING_PROTOTYPE_STRVAR: Final[str] = libclinic.normalize_snippet(""" PyDoc_STRVAR({getset_basename}__doc__, {docstring}); - #if defined({getset_basename}_DOCSTR) - # undef {getset_basename}_DOCSTR +""") +# If the getter is compiled conditionally, the entry refers to the docstring +# by a macro, because only the preprocessor knows which one is defined. +GETSET_DOCSTRING_PROTOTYPE_DEFINE: Final[str] = libclinic.normalize_snippet(""" + PyDoc_STRVAR({getset_basename}__doc__, + {docstring}); + #if defined({getset_name}_DOCSTR) + # undef {getset_name}_DOCSTR #endif - #define {getset_basename}_DOCSTR {getset_basename}__doc__ + #define {getset_name}_DOCSTR {getset_basename}__doc__ """) IMPL_DEFINITION_PROTOTYPE: Final[str] = libclinic.normalize_snippet(""" static {impl_return_type} @@ -169,48 +176,52 @@ def declare_parser( #define {methoddef_name} \ {{"{name}", {methoddef_cast}{c_basename}{methoddef_cast_end}, {methoddef_flags}, {c_basename}__doc__}}, """) -GETTERDEF_PROTOTYPE_DEFINE: Final[str] = libclinic.normalize_snippet(r""" - #if !defined({getset_basename}_DOCSTR) - # define {getset_basename}_DOCSTR NULL - #endif - #if defined({getset_name}_GETSETDEF) - # undef {getset_name}_GETSETDEF - # define {getset_name}_GETSETDEF {{"{name}", (getter){getset_basename}_get, (setter){getset_basename}_set, {getset_basename}_DOCSTR}}, - #else - # define {getset_name}_GETSETDEF {{"{name}", (getter){getset_basename}_get, NULL, {getset_basename}_DOCSTR}}, - #endif -""") -SETTERDEF_PROTOTYPE_DEFINE: Final[str] = libclinic.normalize_snippet(r""" - #if !defined({getset_basename}_DOCSTR) - # define {getset_basename}_DOCSTR NULL - #endif - #if defined({getset_name}_GETSETDEF) - # undef {getset_name}_GETSETDEF - # define {getset_name}_GETSETDEF {{"{name}", (getter){getset_basename}_get, (setter){getset_basename}_set, {getset_basename}_DOCSTR}}, - #else - # define {getset_name}_GETSETDEF {{"{name}", NULL, (setter){getset_basename}_set, NULL}}, - #endif -""") -METHODDEF_PROTOTYPE_IFNDEF: Final[str] = libclinic.normalize_snippet(""" - #ifndef {methoddef_name} - #define {methoddef_name} - #endif /* !defined({methoddef_name}) */ -""") -GETSETDEF_PROTOTYPE_IFNDEF: Final[str] = libclinic.normalize_snippet(""" - #ifndef {getset_name}_GETSETDEF - #define {getset_name}_GETSETDEF - #endif /* !defined({getset_name}_GETSETDEF) */ +# An accessor which is compiled conditionally announces the function which +# implements it. Only the preprocessor knows which of them are compiled, so +# the entry is composed of these announcements +# (see GETSETDEF_PROTOTYPE_COMBINE). +GETTERDEF_PROTOTYPE_DEFINE: Final[str] = libclinic.normalize_snippet(""" + #define {getset_name}_GETTER {c_basename} """) -# The setter is called with NULL to delete the attribute. Unless @deleter is -# applied to it, deletion is rejected before the implementation is called. SETTER_PREAMBLE: Final[str] = libclinic.normalize_snippet(""" - if (value == NULL) {{ + if (arg == NULL) {{ PyErr_Format(PyExc_AttributeError, "attribute '{name}' of '%.100s' objects cannot be deleted", Py_TYPE({self_name})->tp_name); return -1; }} """, indent=4) +SETTERDEF_PROTOTYPE_DEFINE: Final[str] = libclinic.normalize_snippet(""" + #define {getset_name}_SETTER {c_basename} +""") +METHODDEF_PROTOTYPE_IFNDEF: Final[str] = libclinic.normalize_snippet(""" + #ifndef {methoddef_name} + #define {methoddef_name} + #endif /* !defined({methoddef_name}) */ +""") +# The entry of an attribute whose accessors are all compiled unconditionally. +GETSETDEF_PROTOTYPE_DEFINE: Final[str] = libclinic.normalize_snippet(""" + #define {getset_name}_GETSETDEF {{"{name}", (getter){getter}, (setter){setter}, {docstr}}}, +""") +# Composes the PyGetSetDef entry of an attribute. It must be rendered after +# all accessors of that attribute, so it is written to the same destination as +# the "ifndef" of a method, which is emptied at the end of the file. +GETSETDEF_PROTOTYPE_COMBINE: Final[str] = libclinic.normalize_snippet(""" + #if defined({getset_name}_GETTER) || defined({getset_name}_SETTER) + # if !defined({getset_name}_GETTER) + # define {getset_name}_GETTER NULL + # endif + # if !defined({getset_name}_SETTER) + # define {getset_name}_SETTER NULL + # endif + # if !defined({getset_name}_DOCSTR) + # define {getset_name}_DOCSTR NULL + # endif + # define {getset_name}_GETSETDEF {{"{name}", (getter){getset_name}_GETTER, (setter){getset_name}_SETTER, {getset_name}_DOCSTR}}, + #else + # define {getset_name}_GETSETDEF + #endif +""") # Every parser body ends with this shape; parser_body() and # _assemble_vectorcall() fill the assembly-time markers. PARSER_FINALE_SKELETON: Final[str] = libclinic.normalize_snippet(""" @@ -397,15 +408,21 @@ def select_prototypes(self) -> None: if self.is_new_or_init() and not self.func.docstring: pass elif self.func.kind is GETTER: - self.methoddef_define = GETTERDEF_PROTOTYPE_DEFINE + # Only an accessor compiled conditionally announces itself. + self.methoddef_define = (GETTERDEF_PROTOTYPE_DEFINE + if self.func.condition else '') if self.func.docstring: - self.docstring_definition = GETSET_DOCSTRING_PROTOTYPE_STRVAR + self.docstring_definition = ( + GETSET_DOCSTRING_PROTOTYPE_DEFINE if self.func.condition + else GETSET_DOCSTRING_PROTOTYPE_STRVAR) elif self.func.kind in SETTERS: if self.func.docstring: - fail("docstrings are only supported for @getter, not @setter", + fail("docstrings are only supported for @getter", line_number=self.func.line_number) - self.return_value_declaration = "int {parser_retval};" - self.methoddef_define = SETTERDEF_PROTOTYPE_DEFINE + # The conversion of the value can fail before it is set. + self.return_value_declaration = "int {parser_retval} = -1;" + self.methoddef_define = (SETTERDEF_PROTOTYPE_DEFINE + if self.func.condition else '') else: self.docstring_prototype = DOCSTRING_PROTOTYPE_VAR self.docstring_definition = DOCSTRING_PROTOTYPE_STRVAR @@ -442,19 +459,48 @@ def parser_body(self, *fields: str) -> None: init_result_check="") self.parser_definition = code - def parse_no_args(self) -> None: - parser_code: list[str] | None - simple_return = self.use_simple_return() + def render_setter_value(self) -> str: + """Return the code which converts the new value of the attribute.""" + # The parser guarantees that the value is the only parameter. + assert len(self.parameters) == 1 + p = self.parameters[0] + parsearg = p.converter.parse_arg('arg', p.get_displayname(0), + limited_capi=self.limited_capi) + if parsearg is None: + p.converter.use_converter() + parsearg = """ + if (!PyArg_Parse(arg, "{format_units}:{name}", {parse_arguments})) {{ + goto exit; + }} + """ + if self.func.kind is not SETTER_AND_DELETER: + return libclinic.normalize_snippet(parsearg, indent=4) + # The value is only converted if the attribute is not deleted. + return "\n".join([ + libclinic.normalize_snippet("if (arg != NULL) {{", indent=4), + libclinic.normalize_snippet(parsearg, indent=8), + libclinic.normalize_snippet("}}", indent=4), + ]) + + def parse_accessor(self) -> None: + """Generate the code of a getter or a setter.""" + parser_code: list[str] = [] if self.func.kind is GETTER: self.parser_prototype = PARSER_PROTOTYPE_GETTER - parser_code = [] - elif self.func.kind in SETTERS: + else: self.parser_prototype = PARSER_PROTOTYPE_SETTER + # The setter is called with NULL to delete the attribute, which + # is checked before parsing, because NULL is not a value. if self.func.kind is SETTER: - parser_code = [SETTER_PREAMBLE] - else: - parser_code = [] - elif not self.requires_defining_class: + # The setter which is not the deleter rejects the deletion. + parser_code.append(SETTER_PREAMBLE) + parser_code.append(self.render_setter_value()) + self.finish_parser_body(parser_code) + + def parse_no_args(self) -> None: + parser_code: list[str] | None + simple_return = self.use_simple_return() + if not self.requires_defining_class: # no self.parameters, METH_NOARGS self.flags = "METH_NOARGS" self.parser_prototype = PARSER_PROTOTYPE_NOARGS @@ -473,7 +519,12 @@ def parse_no_args(self) -> None: }} """ % return_error, indent=4)] - if simple_return: + self.finish_parser_body(parser_code) + + def finish_parser_body(self, parser_code: list[str]) -> None: + """Generate the parsing function from the code which parses + the arguments.""" + if self.use_simple_return(): self.parser_definition = '\n'.join([ self.parser_prototype, '{{', @@ -1422,19 +1473,20 @@ def process_methoddef(self, clang: CLanguage) -> None: self.methoddef_define = self.methoddef_define.replace('{methoddef_cast}', methoddef_cast) self.methoddef_define = self.methoddef_define.replace('{methoddef_cast_end}', methoddef_cast_end) + # The entry of an attribute is composed when all its accessors are + # known (see render_properties). self.methoddef_ifndef = '' - conditional = clang.cpp.condition() + conditional = self.func.condition if not conditional: self.cpp_if = self.cpp_endif = '' else: self.cpp_if = "#if " + conditional self.cpp_endif = "#endif /* " + conditional + " */" - if self.methoddef_define and self.codegen.add_ifndef_symbol(self.func.full_name): - if self.func.kind in ACCESSORS: - self.methoddef_ifndef = GETSETDEF_PROTOTYPE_IFNDEF - else: - self.methoddef_ifndef = METHODDEF_PROTOTYPE_IFNDEF + if (self.func.kind not in ACCESSORS + and self.methoddef_define + and self.codegen.add_ifndef_symbol(self.func.full_name)): + self.methoddef_ifndef = METHODDEF_PROTOTYPE_IFNDEF def finalize(self, clang: CLanguage) -> None: # add ';' to the end of self.parser_prototype and self.impl_prototype @@ -1675,7 +1727,9 @@ def parse_args(self, clang: CLanguage) -> dict[str, str]: # previous call to parser_body. this is used for an awful hack. self.parser_body_fields: tuple[str, ...] = () - if not self.parameters and not self.varpos and not self.var_keyword: + if self.func.kind in ACCESSORS: + self.parse_accessor() + elif not self.parameters and not self.varpos and not self.var_keyword: self.parse_no_args() elif self.use_meth_o(): self.parse_one_arg() From c2e740ae5f7328eb55d6dab0b4fd6f7fc15cca23 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Sun, 20 Sep 2026 00:59:06 +0900 Subject: [PATCH 09/11] gh-126547: pre-allocate version number for unicode type (#157781) --- Objects/unicodeobject.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d2faa28722b0e0..5d0b818981fc98 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -14475,6 +14475,7 @@ PyTypeObject PyUnicode_Type = { 0, /* tp_alloc */ unicode_new, /* tp_new */ PyObject_Free, /* tp_free */ + .tp_version_tag = _Py_TYPE_VERSION_STR, .tp_vectorcall = unicode_vectorcall, ._tp_iteritem = unicode_iteritem, }; From e8f644868b3ba350897c05c0d44b5b7081b263eb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 19 Sep 2026 18:08:58 +0200 Subject: [PATCH 10/11] gh-156939: Add tests on the PyUnicode C API (#157798) Add tests on functions: * PyUnicode_CHECK_INTERNED() * PyUnicode_Check() * PyUnicode_CheckExact() * PyUnicode_Equal() * PyUnicode_GET_LENGTH() * PyUnicode_IS_ASCII() * PyUnicode_IS_COMPACT() * PyUnicode_IS_COMPACT_ASCII() * PyUnicode_KIND() * PyUnicode_MAX_CHAR_VALUE() * PyUnicode_READ() * PyUnicode_READ_CHAR() * PyUnicode_WRITE() Changes: * Add test on PyUnicode_FromOrdinal(0). * Require _testcapi module in test_capi.test_unicode. Since _testcapi is specific to CPython, remove @support.cpython_only. --- Lib/test/test_capi/test_unicode.py | 546 ++++++++++++++++++----------- Modules/_testcapi/unicode.c | 155 ++++++++ Modules/_testcapi/util.h | 10 + Modules/_testlimitedcapi/unicode.c | 19 + 4 files changed, 527 insertions(+), 203 deletions(-) diff --git a/Lib/test/test_capi/test_unicode.py b/Lib/test/test_capi/test_unicode.py index f2b77e3fdb5fc4..50e807e3e7db08 100644 --- a/Lib/test/test_capi/test_unicode.py +++ b/Lib/test/test_capi/test_unicode.py @@ -2,41 +2,72 @@ import textwrap import unittest from test import support +from test.support import import_helper from test.support import threading_helper from test.support.script_helper import assert_python_failure +from threading import Thread -try: - import _testcapi - from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX -except ImportError: - _testcapi = None -try: - import _testlimitedcapi -except ImportError: - _testlimitedcapi = None -try: - import _testinternalcapi -except ImportError: - _testinternalcapi = None try: import ctypes except ImportError: ctypes = None +# Skip the test if one these modules is not available +_testcapi = import_helper.import_module('_testcapi') +_testlimitedcapi = import_helper.import_module('_testlimitedcapi') +_testinternalcapi = import_helper.import_module('_testinternalcapi') +from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, SIZEOF_WCHAR_T + NULL = None class Str(str): pass +class StrLike: + def __init__(self, value): + self.value = value + def __str__(self): + return self.value + + +PyUnicode_1BYTE_KIND = 1 +PyUnicode_2BYTE_KIND = 2 +PyUnicode_4BYTE_KIND = 4 + +SSTATE_NOT_INTERNED = 0 +SSTATE_INTERNED_MORTAL = 1 +SSTATE_INTERNED_IMMORTAL = 2 +SSTATE_INTERNED_IMMORTAL_STATIC = 3 + class CAPITest(unittest.TestCase): - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def _test_check(self, check, *, exact): + # Test PyUnicode_Check() + self.assertTrue(check('')) + self.assertTrue(check('abc')) + self.assertEqual(check(Str('abc')), 0 if exact else 1) + self.assertFalse(check(StrLike('abc'))) + + self.assertFalse(check(b'abc')) + self.assertFalse(check(3)) + self.assertFalse(check([])) + self.assertFalse(check(object())) + + # CRASHES check(NULL) + + def test_check(self): + # Test PyUnicode_Check() + self._test_check(_testlimitedcapi.unicode_check, exact=False) + + def test_checkexact(self): + # Test PyUnicode_CheckExact() + self._test_check(_testlimitedcapi.unicode_checkexact, exact=True) + def test_new(self): """Test PyUnicode_New()""" - from _testcapi import unicode_new as new + new = _testcapi.unicode_new for maxchar in 0, 0x61, 0xa1, 0x4f60, 0x1f600, 0x10ffff: self.assertEqual(new(0, maxchar), '') @@ -53,11 +84,9 @@ def test_new(self): self.assertRaises(SystemError, new, -1, 0) self.assertRaises(SystemError, new, PY_SSIZE_T_MIN, 0) - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_fill(self): """Test PyUnicode_Fill()""" - from _testcapi import unicode_fill as fill + fill = _testcapi.unicode_fill strings = [ # all strings have exactly 5 characters @@ -93,12 +122,7 @@ def test_fill(self): # CRASHES fill(NULL, 0, 0, 0x78) # TODO: Test PyUnicode_Fill() with non-modifiable unicode. - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') - def test_writechar(self): - """Test PyUnicode_WriteChar()""" - from _testlimitedcapi import unicode_writechar as writechar - + def _test_writechar(self, writechar, *, check): strings = [ # one string for every kind 'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16', @@ -111,24 +135,31 @@ def test_writechar(self): if j <= i: self.assertEqual(writechar(s, 1, c), (s[:1] + chr(c) + s[2:], 0)) - else: + elif check: self.assertRaises(ValueError, writechar, s, 1, c) - self.assertRaises(IndexError, writechar, 'abc', 3, 0x78) - self.assertRaises(IndexError, writechar, 'abc', -1, 0x78) - self.assertRaises(IndexError, writechar, 'abc', PY_SSIZE_T_MAX, 0x78) - self.assertRaises(IndexError, writechar, 'abc', PY_SSIZE_T_MIN, 0x78) - self.assertRaises(TypeError, writechar, b'abc', 0, 0x78) - self.assertRaises(TypeError, writechar, [], 0, 0x78) - # CRASHES writechar(NULL, 0, 0x78) - # TODO: Test PyUnicode_WriteChar() with non-modifiable and legacy - # unicode. - - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') + if check: + self.assertRaises(IndexError, writechar, 'abc', 3, 0x78) + self.assertRaises(IndexError, writechar, 'abc', -1, 0x78) + self.assertRaises(IndexError, writechar, 'abc', PY_SSIZE_T_MAX, 0x78) + self.assertRaises(IndexError, writechar, 'abc', PY_SSIZE_T_MIN, 0x78) + self.assertRaises(TypeError, writechar, b'abc', 0, 0x78) + self.assertRaises(TypeError, writechar, [], 0, 0x78) + # CRASHES writechar(NULL, 0, 0x78) + # TODO: Test PyUnicode_WriteChar() with non-modifiable and legacy + # unicode. + + def test_writechar(self): + """Test PyUnicode_WriteChar()""" + self._test_writechar(_testlimitedcapi.unicode_writechar, check=True) + + def test_write_macro(self): + """Test PyUnicode_WRITE()""" + self._test_writechar(_testcapi.unicode_write, check=False) + def test_resize(self): """Test PyUnicode_Resize()""" - from _testlimitedcapi import unicode_resize as resize + resize = _testlimitedcapi.unicode_resize strings = [ # all strings have exactly 3 characters @@ -150,11 +181,9 @@ def test_resize(self): # TODO: Test PyUnicode_Resize() with non-modifiable and legacy unicode # and with NULL as the address. - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_append(self): """Test PyUnicode_Append()""" - from _testlimitedcapi import unicode_append as append + append = _testlimitedcapi.unicode_append strings = [ 'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16', @@ -178,11 +207,9 @@ def test_append(self): # and with NULL as the address. # TODO: Check reference counts. - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_appendanddel(self): """Test PyUnicode_AppendAndDel()""" - from _testlimitedcapi import unicode_appendanddel as appendanddel + appendanddel = _testlimitedcapi.unicode_appendanddel strings = [ 'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16', @@ -205,11 +232,9 @@ def test_appendanddel(self): # and with NULL as the address. # TODO: Check reference counts. - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_fromstringandsize(self): """Test PyUnicode_FromStringAndSize()""" - from _testlimitedcapi import unicode_fromstringandsize as fromstringandsize + fromstringandsize = _testlimitedcapi.unicode_fromstringandsize self.assertEqual(fromstringandsize(b'abc'), 'abc') self.assertEqual(fromstringandsize(b'abc', 2), 'ab') @@ -230,11 +255,9 @@ def test_fromstringandsize(self): self.assertRaises(SystemError, fromstringandsize, NULL, 3) self.assertRaises(SystemError, fromstringandsize, NULL, PY_SSIZE_T_MAX) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_fromstring(self): """Test PyUnicode_FromString()""" - from _testlimitedcapi import unicode_fromstring as fromstring + fromstring = _testlimitedcapi.unicode_fromstring self.assertEqual(fromstring(b'abc'), 'abc') self.assertEqual(fromstring(b'\xc2\xa1\xc2\xa2'), '\xa1\xa2') @@ -246,11 +269,9 @@ def test_fromstring(self): # CRASHES fromstring(NULL) - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_fromkindanddata(self): """Test PyUnicode_FromKindAndData()""" - from _testcapi import unicode_fromkindanddata as fromkindanddata + fromkindanddata = _testcapi.unicode_fromkindanddata strings = [ 'abcde', '\xa1\xa2\xa3\xa4\xa5', @@ -282,11 +303,9 @@ def test_fromkindanddata(self): # CRASHES fromkindanddata(1, NULL, 1) # CRASHES fromkindanddata(4, b'\xff\xff\xff\xff') - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_substring(self): """Test PyUnicode_Substring()""" - from _testlimitedcapi import unicode_substring as substring + substring = _testlimitedcapi.unicode_substring strings = [ 'ab', 'ab\xa1\xa2', @@ -306,44 +325,68 @@ def test_substring(self): # CRASHES substring([], 0, 0) # CRASHES substring(NULL, 0, 0) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') - def test_getlength(self): - """Test PyUnicode_GetLength()""" - from _testlimitedcapi import unicode_getlength as getlength - - for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', + def _test_getlength(self, getlength, *, check): + for s in ['', 'abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', 'a\ud800b\udfffc', '\ud834\udd1e']: self.assertEqual(getlength(s), len(s)) - self.assertRaises(TypeError, getlength, b'abc') - self.assertRaises(TypeError, getlength, []) + if check: + self.assertRaises(TypeError, getlength, b'abc') + self.assertRaises(TypeError, getlength, []) # CRASHES getlength(NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') - def test_readchar(self): - """Test PyUnicode_ReadChar()""" - from _testlimitedcapi import unicode_readchar as readchar + def test_getlength(self): + """Test PyUnicode_GetLength()""" + self._test_getlength(_testlimitedcapi.unicode_getlength, check=True) + def test_getlength_macro(self): + """Test PyUnicode_GET_LENGTH() macro""" + self._test_getlength(_testcapi.unicode_getlength_macro, check=False) + + def _test_read_char(self, readchar, *, check, read_null_char): for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', 'a\ud800b\udfffc', '\ud834\udd1e']: for i, c in enumerate(s): self.assertEqual(readchar(s, i), ord(c)) - self.assertRaises(IndexError, readchar, s, len(s)) - self.assertRaises(IndexError, readchar, s, PY_SSIZE_T_MAX) - self.assertRaises(IndexError, readchar, s, -1) - self.assertRaises(IndexError, readchar, s, PY_SSIZE_T_MIN) + if read_null_char: + self.assertEqual(readchar(s, len(s)), 0) + elif check: + self.assertRaises(IndexError, readchar, s, len(s)) + if check: + self.assertRaises(IndexError, readchar, s, PY_SSIZE_T_MAX) + self.assertRaises(IndexError, readchar, s, -1) + self.assertRaises(IndexError, readchar, s, PY_SSIZE_T_MIN) + else: + # CRASHES on above test + pass + + if check: + # invalid type + self.assertRaises(TypeError, readchar, b'abc', 0) + self.assertRaises(TypeError, readchar, [], 0) + # CRASHES readchar(NULL, 0) + else: + # CRASHES on above test + pass + + def test_readchar(self): + """Test PyUnicode_ReadChar()""" + self._test_read_char(_testlimitedcapi.unicode_readchar, + check=True, read_null_char=False) - self.assertRaises(TypeError, readchar, b'abc', 0) - self.assertRaises(TypeError, readchar, [], 0) - # CRASHES readchar(NULL, 0) + def test_read_char_macro(self): + """Test PyUnicode_READ_CHAR() macro""" + self._test_read_char(_testcapi.unicode_read_char, + check=False, read_null_char=True) + + def test_read_macro(self): + """Test PyUnicode_READ() macro""" + self._test_read_char(_testcapi.unicode_read, + check=False, read_null_char=True) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_fromobject(self): """Test PyUnicode_FromObject()""" - from _testlimitedcapi import unicode_fromobject as fromobject + fromobject = _testlimitedcapi.unicode_fromobject for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', 'a\ud800b\udfffc', '\ud834\udd1e']: @@ -792,11 +835,9 @@ class LocalType: self.assertRaisesRegex(SystemError, 'invalid format string', PyUnicode_FromFormat, b'%+i', c_int(10)) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_interninplace(self): """Test PyUnicode_InternInPlace()""" - from _testlimitedcapi import unicode_interninplace as interninplace + interninplace = _testlimitedcapi.unicode_interninplace s = b'abc'.decode() r = interninplace(s) @@ -805,11 +846,9 @@ def test_interninplace(self): # CRASHES interninplace(b'abc') # CRASHES interninplace(NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_internfromstring(self): """Test PyUnicode_InternFromString()""" - from _testlimitedcapi import unicode_internfromstring as internfromstring + internfromstring = _testlimitedcapi.unicode_internfromstring self.assertEqual(internfromstring(b'abc'), 'abc') self.assertEqual(internfromstring(b'\xf0\x9f\x98\x80'), '\U0001f600') @@ -819,12 +858,9 @@ def test_internfromstring(self): # CRASHES internfromstring(NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_fromwidechar(self): """Test PyUnicode_FromWideChar()""" - from _testlimitedcapi import unicode_fromwidechar as fromwidechar - from _testcapi import SIZEOF_WCHAR_T + fromwidechar = _testlimitedcapi.unicode_fromwidechar if SIZEOF_WCHAR_T == 2: encoding = 'utf-16le' if sys.byteorder == 'little' else 'utf-16be' @@ -856,13 +892,10 @@ def test_fromwidechar(self): #self.assertRaises(MemoryError, fromwidechar, b'', PY_SSIZE_T_MAX) #self.assertRaises(SystemError, fromwidechar, b'\0'*SIZEOF_WCHAR_T, PY_SSIZE_T_MIN) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_aswidechar(self): """Test PyUnicode_AsWideChar()""" - from _testlimitedcapi import unicode_aswidechar - from _testlimitedcapi import unicode_aswidechar_null - from _testcapi import SIZEOF_WCHAR_T + unicode_aswidechar = _testlimitedcapi.unicode_aswidechar + unicode_aswidechar_null = _testlimitedcapi.unicode_aswidechar_null wchar, size = unicode_aswidechar('abcdef', 2) self.assertEqual(size, 2) @@ -904,13 +937,10 @@ def test_aswidechar(self): self.assertRaises(TypeError, unicode_aswidechar_null, [], 10) self.assertRaises(SystemError, unicode_aswidechar_null, NULL, 10) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_aswidecharstring(self): """Test PyUnicode_AsWideCharString()""" - from _testlimitedcapi import unicode_aswidecharstring - from _testlimitedcapi import unicode_aswidecharstring_null - from _testcapi import SIZEOF_WCHAR_T + unicode_aswidecharstring = _testlimitedcapi.unicode_aswidecharstring + unicode_aswidecharstring_null = _testlimitedcapi.unicode_aswidecharstring_null wchar, size = unicode_aswidecharstring('abc') self.assertEqual(size, 3) @@ -939,11 +969,9 @@ def test_aswidecharstring(self): self.assertRaises(TypeError, unicode_aswidecharstring_null, []) self.assertRaises(SystemError, unicode_aswidecharstring_null, NULL) - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_asucs4(self): """Test PyUnicode_AsUCS4()""" - from _testcapi import unicode_asucs4 + unicode_asucs4 = _testcapi.unicode_asucs4 for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', 'a\ud800b\udfffc', '\ud834\udd1e']: @@ -964,11 +992,9 @@ def test_asucs4(self): # CRASHES unicode_asucs4(NULL, 1, 0) # CRASHES unicode_asucs4(NULL, 1, 1) - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_asucs4copy(self): """Test PyUnicode_AsUCS4Copy()""" - from _testcapi import unicode_asucs4copy as asucs4copy + asucs4copy = _testcapi.unicode_asucs4copy for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', 'a\ud800b\udfffc', '\ud834\udd1e']: @@ -980,12 +1006,11 @@ def test_asucs4copy(self): # CRASHES asucs4copy([]) # CRASHES asucs4copy(NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_fromordinal(self): """Test PyUnicode_FromOrdinal()""" - from _testlimitedcapi import unicode_fromordinal as fromordinal + fromordinal = _testlimitedcapi.unicode_fromordinal + self.assertEqual(fromordinal(0), '\x00') self.assertEqual(fromordinal(0x61), 'a') self.assertEqual(fromordinal(0x20ac), '\u20ac') self.assertEqual(fromordinal(0x1f600), '\U0001f600') @@ -993,11 +1018,9 @@ def test_fromordinal(self): self.assertRaises(ValueError, fromordinal, 0x110000) self.assertRaises(ValueError, fromordinal, -1) - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_asutf8(self): """Test PyUnicode_AsUTF8()""" - from _testcapi import unicode_asutf8 + unicode_asutf8 = _testcapi.unicode_asutf8 self.assertEqual(unicode_asutf8('abc', 4), b'abc\0') self.assertEqual(unicode_asutf8('абв', 7), b'\xd0\xb0\xd0\xb1\xd0\xb2\0') @@ -1009,12 +1032,10 @@ def test_asutf8(self): self.assertRaises(TypeError, unicode_asutf8, [], 0) # CRASHES unicode_asutf8(NULL, 0) - @unittest.skipIf(_testcapi is None, 'need _testcapi module') @threading_helper.requires_working_threading() def test_asutf8_race(self): """Test that there's no race condition in PyUnicode_AsUTF8()""" unicode_asutf8 = _testcapi.unicode_asutf8 - from threading import Thread data = "😊" @@ -1027,12 +1048,10 @@ def worker(): pass - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_asutf8andsize(self): """Test PyUnicode_AsUTF8AndSize()""" - from _testlimitedcapi import unicode_asutf8andsize - from _testlimitedcapi import unicode_asutf8andsize_null + unicode_asutf8andsize = _testlimitedcapi.unicode_asutf8andsize + unicode_asutf8andsize_null = _testlimitedcapi.unicode_asutf8andsize_null self.assertEqual(unicode_asutf8andsize('abc', 4), (b'abc\0', 3)) self.assertEqual(unicode_asutf8andsize('абв', 7), (b'\xd0\xb0\xd0\xb1\xd0\xb2\0', 6)) @@ -1050,19 +1069,15 @@ def test_asutf8andsize(self): # CRASHES unicode_asutf8andsize(NULL, 0) # CRASHES unicode_asutf8andsize_null(NULL, 0) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_getdefaultencoding(self): """Test PyUnicode_GetDefaultEncoding()""" - from _testlimitedcapi import unicode_getdefaultencoding as getdefaultencoding + getdefaultencoding = _testlimitedcapi.unicode_getdefaultencoding self.assertEqual(getdefaultencoding(), b'utf-8') - @support.cpython_only - @unittest.skipIf(_testinternalcapi is None, 'need _testinternalcapi module') def test_transform_decimal_and_space(self): """Test _PyUnicode_TransformDecimalAndSpaceToASCII()""" - from _testinternalcapi import _PyUnicode_TransformDecimalAndSpaceToASCII as transform_decimal + transform_decimal = _testinternalcapi._PyUnicode_TransformDecimalAndSpaceToASCII self.assertEqual(transform_decimal('123'), '123') @@ -1078,11 +1093,9 @@ def test_transform_decimal_and_space(self): self.assertRaises(SystemError, transform_decimal, []) # CRASHES transform_decimal(NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_concat(self): """Test PyUnicode_Concat()""" - from _testlimitedcapi import unicode_concat as concat + concat = _testlimitedcapi.unicode_concat self.assertEqual(concat('abc', 'def'), 'abcdef') self.assertEqual(concat('abc', 'где'), 'abcгде') @@ -1099,11 +1112,9 @@ def test_concat(self): # CRASHES concat(NULL, 'def') # CRASHES concat('abc', NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_split(self): """Test PyUnicode_Split()""" - from _testlimitedcapi import unicode_split as split + split = _testlimitedcapi.unicode_split self.assertEqual(split('a|b|c|d', '|'), ['a', 'b', 'c', 'd']) self.assertEqual(split('a|b|c|d', '|', 2), ['a', 'b', 'c|d']) @@ -1127,11 +1138,9 @@ def test_split(self): self.assertRaises(TypeError, split, [], '|') # CRASHES split(NULL, '|') - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_rsplit(self): """Test PyUnicode_RSplit()""" - from _testlimitedcapi import unicode_rsplit as rsplit + rsplit = _testlimitedcapi.unicode_rsplit self.assertEqual(rsplit('a|b|c|d', '|'), ['a', 'b', 'c', 'd']) self.assertEqual(rsplit('a|b|c|d', '|', 2), ['a|b', 'c', 'd']) @@ -1156,11 +1165,9 @@ def test_rsplit(self): self.assertRaises(TypeError, rsplit, [], '|') # CRASHES rsplit(NULL, '|') - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_partition(self): """Test PyUnicode_Partition()""" - from _testlimitedcapi import unicode_partition as partition + partition = _testlimitedcapi.unicode_partition self.assertEqual(partition('a|b|c', '|'), ('a', '|', 'b|c')) self.assertEqual(partition('a||b||c', '||'), ('a', '||', 'b||c')) @@ -1176,11 +1183,9 @@ def test_partition(self): # CRASHES partition(NULL, '|') # CRASHES partition('a|b|c', NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_rpartition(self): """Test PyUnicode_RPartition()""" - from _testlimitedcapi import unicode_rpartition as rpartition + rpartition = _testlimitedcapi.unicode_rpartition self.assertEqual(rpartition('a|b|c', '|'), ('a|b', '|', 'c')) self.assertEqual(rpartition('a||b||c', '||'), ('a||b', '||', 'c')) @@ -1196,11 +1201,9 @@ def test_rpartition(self): # CRASHES rpartition(NULL, '|') # CRASHES rpartition('a|b|c', NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_splitlines(self): """Test PyUnicode_SplitLines()""" - from _testlimitedcapi import unicode_splitlines as splitlines + splitlines = _testlimitedcapi.unicode_splitlines self.assertEqual(splitlines('a\nb\rc\r\nd'), ['a', 'b', 'c', 'd']) self.assertEqual(splitlines('a\nb\rc\r\nd', True), @@ -1214,11 +1217,9 @@ def test_splitlines(self): self.assertRaises(TypeError, splitlines, b'a\nb\rc\r\nd') # CRASHES splitlines(NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_translate(self): """Test PyUnicode_Translate()""" - from _testlimitedcapi import unicode_translate as translate + translate = _testlimitedcapi.unicode_translate self.assertEqual(translate('abcd', {ord('a'): 'A', ord('b'): ord('B'), ord('c'): '<>'}), 'AB<>d') self.assertEqual(translate('абвг', {ord('а'): 'А', ord('б'): ord('Б'), ord('в'): '<>'}), 'АБ<>г') @@ -1239,11 +1240,9 @@ def test_translate(self): self.assertRaises(LookupError, translate, 'abc', {ord('b'): None}, 'foo') # CRASHES translate(NULL, []) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_join(self): """Test PyUnicode_Join()""" - from _testlimitedcapi import unicode_join as join + join = _testlimitedcapi.unicode_join self.assertEqual(join('|', ['a', 'b', 'c']), 'a|b|c') self.assertEqual(join('|', ['a', '', 'c']), 'a||c') self.assertEqual(join('', ['a', 'b', 'c']), 'abc') @@ -1257,11 +1256,9 @@ def test_join(self): self.assertRaises(TypeError, join, '|', 123) self.assertRaises(SystemError, join, '|', NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_count(self): """Test PyUnicode_Count()""" - from _testlimitedcapi import unicode_count + unicode_count = _testlimitedcapi.unicode_count for str in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1": for i, ch in enumerate(str): @@ -1288,11 +1285,9 @@ def test_count(self): # CRASHES unicode_count(NULL, '!', 0, len(str)) # CRASHES unicode_count(str, NULL, 0, len(str)) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_tailmatch(self): """Test PyUnicode_Tailmatch()""" - from _testlimitedcapi import unicode_tailmatch as tailmatch + tailmatch = _testlimitedcapi.unicode_tailmatch str = 'ababahalamaha' self.assertEqual(tailmatch(str, 'aba', 0, len(str), -1), 1) @@ -1323,11 +1318,9 @@ def test_tailmatch(self): # CRASHES tailmatch(NULL, 'aba', 0, len(str), -1) # CRASHES tailmatch(str, NULL, 0, len(str), -1) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_find(self): """Test PyUnicode_Find()""" - from _testlimitedcapi import unicode_find as find + find = _testlimitedcapi.unicode_find for str in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1": for i, ch in enumerate(str): @@ -1364,11 +1357,9 @@ def test_find(self): # CRASHES find(NULL, '!', 0, len(str), 1) # CRASHES find(str, NULL, 0, len(str), 1) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_findchar(self): """Test PyUnicode_FindChar()""" - from _testlimitedcapi import unicode_findchar + unicode_findchar = _testlimitedcapi.unicode_findchar for str in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1": for i, ch in enumerate(str): @@ -1400,11 +1391,9 @@ def test_findchar(self): # CRASHES unicode_findchar([], ord('!'), 0, len(str), 1) # CRASHES unicode_findchar(NULL, ord('!'), 0, len(str), 1), 1) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_replace(self): """Test PyUnicode_Replace()""" - from _testlimitedcapi import unicode_replace as replace + replace = _testlimitedcapi.unicode_replace str = 'abracadabra' self.assertEqual(replace(str, 'a', '='), '=br=c=d=br=') @@ -1431,11 +1420,9 @@ def test_replace(self): # CRASHES replace('a', NULL, '=') # CRASHES replace(NULL, 'a', '=') - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_compare(self): """Test PyUnicode_Compare()""" - from _testlimitedcapi import unicode_compare as compare + compare = _testlimitedcapi.unicode_compare self.assertEqual(compare('abc', 'abc'), 0) self.assertEqual(compare('abc', 'def'), -1) @@ -1453,11 +1440,9 @@ def test_compare(self): # CRASHES compare(NULL, 'abc') # CRASHES compare('abc', NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_comparewithasciistring(self): """Test PyUnicode_CompareWithASCIIString()""" - from _testlimitedcapi import unicode_comparewithasciistring as comparewithasciistring + comparewithasciistring = _testlimitedcapi.unicode_comparewithasciistring self.assertEqual(comparewithasciistring('abc', b'abc'), 0) self.assertEqual(comparewithasciistring('abc', b'def'), -1) @@ -1470,12 +1455,10 @@ def test_comparewithasciistring(self): # CRASHES comparewithasciistring([], b'abc') # CRASHES comparewithasciistring(NULL, b'abc') - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_equaltoutf8(self): # Test PyUnicode_EqualToUTF8() - from _testlimitedcapi import unicode_equaltoutf8 as equaltoutf8 - from _testlimitedcapi import unicode_asutf8andsize as asutf8andsize + equaltoutf8 = _testlimitedcapi.unicode_equaltoutf8 + asutf8andsize = _testlimitedcapi.unicode_asutf8andsize strings = [ 'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16', @@ -1516,12 +1499,10 @@ def test_equaltoutf8(self): self.assertEqual(equaltoutf8('\ud801', '\ud801'.encode("utf8", "surrogatepass")), 0) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_equaltoutf8andsize(self): # Test PyUnicode_EqualToUTF8AndSize() - from _testlimitedcapi import unicode_equaltoutf8andsize as equaltoutf8andsize - from _testlimitedcapi import unicode_asutf8andsize as asutf8andsize + equaltoutf8andsize = _testlimitedcapi.unicode_equaltoutf8andsize + asutf8andsize = _testlimitedcapi.unicode_asutf8andsize strings = [ 'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16', @@ -1585,11 +1566,9 @@ def check_not_equal_encoding(text, encoding): # CRASHES equaltoutf8andsize(NULL, b'abc') # CRASHES equaltoutf8andsize('abc', NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_richcompare(self): """Test PyUnicode_RichCompare()""" - from _testlimitedcapi import unicode_richcompare as richcompare + richcompare = _testlimitedcapi.unicode_richcompare LT, LE, EQ, NE, GT, GE = range(6) strings = ('abc', 'абв', '\U0001f600', 'abc\0') @@ -1613,11 +1592,25 @@ def test_richcompare(self): # CRASHES richcompare(NULL, 'abc', op) # CRASHES richcompare('abc', NULL, op) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') + def test_equal(self): + """Test PyUnicode_Equal()""" + equal = _testlimitedcapi.unicode_equal + + strings = ('abc', 'абв', '\U0001f600', 'abc\0') + for s1 in strings: + for s2 in strings: + self.assertEqual(equal(s1, s2), int(s1 == s2)) + + self.assertRaises(TypeError, equal, 'str', b'bytes') + self.assertRaises(TypeError, equal, b'bytes', 'str') + self.assertRaises(TypeError, equal, 12, 34) + + # CRASHES equal(NULL, 'abc') + # CRASHES equal('abc', NULL) + def test_format(self): """Test PyUnicode_Format()""" - from _testlimitedcapi import unicode_format as format + format = _testlimitedcapi.unicode_format self.assertEqual(format('x=%d!', 42), 'x=42!') self.assertEqual(format('x=%d!', (42,)), 'x=42!') @@ -1626,11 +1619,9 @@ def test_format(self): self.assertRaises(SystemError, format, 'x=%d!', NULL) self.assertRaises(SystemError, format, NULL, 42) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_contains(self): """Test PyUnicode_Contains()""" - from _testlimitedcapi import unicode_contains as contains + contains = _testlimitedcapi.unicode_contains self.assertEqual(contains('abcd', ''), 1) self.assertEqual(contains('abcd', 'b'), 1) @@ -1648,11 +1639,9 @@ def test_contains(self): # CRASHES contains(NULL, 'b') # CRASHES contains('abcd', NULL) - @support.cpython_only - @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module') def test_isidentifier(self): """Test PyUnicode_IsIdentifier()""" - from _testlimitedcapi import unicode_isidentifier as isidentifier + isidentifier = _testlimitedcapi.unicode_isidentifier self.assertEqual(isidentifier("a"), 1) self.assertEqual(isidentifier("b0"), 1) @@ -1670,11 +1659,9 @@ def test_isidentifier(self): # CRASHES isidentifier([]) # CRASHES isidentifier(NULL) - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_copycharacters(self): """Test PyUnicode_CopyCharacters()""" - from _testcapi import unicode_copycharacters + unicode_copycharacters = _testcapi.unicode_copycharacters strings = [ # all strings have exactly 5 characters @@ -1725,11 +1712,9 @@ def test_copycharacters(self): # TODO: Test PyUnicode_CopyCharacters() with non-unicode and # non-modifiable unicode as "to". - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_pep393_utf8_caching_bug(self): # Issue #25709: Problem with string concatenation and utf-8 cache - from _testcapi import getargs_s_hash + getargs_s_hash = _testcapi.getargs_s_hash for k in 0x24, 0xa4, 0x20ac, 0x1f40d: s = '' for i in range(5): @@ -1743,10 +1728,9 @@ def test_pep393_utf8_caching_bug(self): # Check that the second call returns the same result self.assertEqual(getargs_s_hash(s), chr(k).encode() * (i + 1)) - @support.cpython_only - @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_GET_CACHED_HASH(self): - from _testcapi import unicode_GET_CACHED_HASH + """Test PyUnstable_Unicode_GET_CACHED_HASH()""" + unicode_GET_CACHED_HASH = _testcapi.unicode_GET_CACHED_HASH content_bytes = b'some new string' # avoid parser interning & constant folding obj = str(content_bytes, 'ascii') @@ -1757,9 +1741,86 @@ def test_GET_CACHED_HASH(self): # impl detail: ASCII string hashes are equal to bytes ones self.assertEqual(unicode_GET_CACHED_HASH(obj), hash(content_bytes)) + def test_kind(self): + """Test PyUnicode_KIND()""" + unicode_kind = _testcapi.unicode_kind + self.assertEqual(unicode_kind('ascii'), PyUnicode_1BYTE_KIND) + self.assertEqual(unicode_kind('latin1:\xe9'), PyUnicode_1BYTE_KIND) + self.assertEqual(unicode_kind('bmp:\u20ac'), PyUnicode_2BYTE_KIND) + self.assertEqual(unicode_kind('\U0010ffff'), PyUnicode_4BYTE_KIND) + + # CRASHES unicode_kind(NULL) + + def test_max_char_value(self): + """Test PyUnicode_MAX_CHAR_VALUE()""" + max_char_value = _testcapi.unicode_max_char_value + self.assertEqual(max_char_value('ascii'), 0x7f) + self.assertEqual(max_char_value('latin1:\xe9'), 0xff) + self.assertEqual(max_char_value('bmp:\u20ac'), 0xffff) + self.assertEqual(max_char_value('\U0010ffff'), 0x10_ffff) + + # CRASHES max_char_value(NULL) + + def test_check_interned(self): + """Test PyUnicode_CHECK_INTERNED() macro""" + check_interned = _testcapi.unicode_check_interned + + def fresh_string(text): + # Create a new string object by decoding a bytes string. + return text.encode().decode() + + s = fresh_string('hello') + self.assertEqual(check_interned(s), SSTATE_NOT_INTERNED) + + s = fresh_string('long string unlikely to be used by Python') + s = sys.intern(s) + if support.Py_GIL_DISABLED: + self.assertEqual(check_interned(s), SSTATE_INTERNED_IMMORTAL) + else: + self.assertEqual(check_interned(s), SSTATE_INTERNED_MORTAL) + + # 'x' is a singleton: immortal static interned string + self.assertEqual(check_interned('x'), SSTATE_INTERNED_IMMORTAL_STATIC) + + # CRASHES check_interned(NULL) + + def test_is_ascii(self): + """Test PyUnicode_IS_ASCII() macro""" + is_ascii = _testcapi.unicode_is_ascii + self.assertEqual(is_ascii('abc'), 1) + self.assertEqual(is_ascii('\u20ac'), 0) + # CRASHES is_ascii(NULL) + + def test_is_compact(self): + """Test PyUnicode_IS_COMPACT() macro""" + is_compact = _testcapi.unicode_is_compact + self.assertEqual(is_compact('ascii'), 1) + self.assertEqual(is_compact('latin1:\xe9'), 1) + self.assertEqual(is_compact('bmp:\u20ac'), 1) + self.assertEqual(is_compact('\U0010ffff'), 1) + # str subclasses are not compact + self.assertEqual(is_compact(Str('abc')), 0) + self.assertEqual(is_compact(Str('\u20ac')), 0) + + # CRASHES is_compact(NULL) + + def test_is_compact_ascii(self): + """Test PyUnicode_IS_COMPACT_ASCII() macro""" + is_compact_ascii = _testcapi.unicode_is_compact_ascii + self.assertEqual(is_compact_ascii('ascii'), 1) + self.assertEqual(is_compact_ascii('latin1:\xe9'), 0) + self.assertEqual(is_compact_ascii('bmp:\u20ac'), 0) + self.assertEqual(is_compact_ascii('\U0010ffff'), 0) + # str subclasses are not compact + self.assertEqual(is_compact_ascii(Str('abc')), 0) + self.assertEqual(is_compact_ascii(Str('\u20ac')), 0) + + # CRASHES is_compact_ascii(NULL) + class PyUnicodeWriterTest(unittest.TestCase): def create_writer(self, size): + # Test PyUnicodeWriter_Create() return _testcapi.PyUnicodeWriter(size) def test_basic(self): @@ -1782,6 +1843,7 @@ def test_basic(self): # test PyUnicodeWriter_WriteRepr() writer.write_repr("repr") + # test PyUnicodeWriter_Finish() self.assertEqual(writer.finish(), "var=long value 'repr'") @@ -1818,6 +1880,7 @@ def test_utf8(self): "ascii-latin1=\xE9-euro=\u20AC.") def test_ascii(self): + # Test PyUnicodeWriter_WriteASCII() writer = self.create_writer(0) writer.write_ascii(b"Hello ", -1) writer.write_ascii(b"", 0) @@ -1908,8 +1971,7 @@ def test_decode_utf8_consumed(self): self.assertEqual(writer.finish(), "text-\xE9-\u20AC-more-incomplete-default") def test_widechar(self): - from _testcapi import SIZEOF_WCHAR_T - + # Test PyUnicodeWriter_WriteWideChar() if SIZEOF_WCHAR_T == 2: encoding = 'utf-16le' if sys.byteorder == 'little' else 'utf-16be' elif SIZEOF_WCHAR_T == 4: @@ -1940,6 +2002,7 @@ def test_widechar(self): "latin1=\xE9-euro=\u20AC-max=\U0010ffff-zeroes=\0\0\0.") def test_ucs4(self): + # Test PyUnicodeWriter_WriteUCS4() encoding = 'utf-32le' if sys.byteorder == 'little' else 'utf-32be' writer = self.create_writer(0) @@ -1984,8 +2047,10 @@ def test_substring_empty(self): self.assertEqual(writer.finish(), '') def test_singletons(self): - writer = self.create_writer(5) - self.assertIs(writer.finish(), '') + for size in (0, 123): + with self.subTest(size=size): + writer = self.create_writer(size) + self.assertIs(writer.finish(), '') for ch in range(256): with self.subTest(ch=ch): @@ -2011,6 +2076,7 @@ def test_detect_overflow(self): self.assertIn(f'at position '.encode(), proc.err) +# Test PyUnicodeWriter_Format() @unittest.skipIf(ctypes is None, 'need ctypes') class PyUnicodeWriterFormatTest(unittest.TestCase): def create_writer(self, size): @@ -2079,6 +2145,80 @@ def copy(text): # CRASHES unicode_equal("abc", NULL) # CRASHES unicode_equal(NULL, "abc") + # TODO: Add tests to the following codec functions: + # - PyUnicode_AsASCIIString + # - PyUnicode_AsCharmapString + # - PyUnicode_AsEncodedString + # - PyUnicode_AsLatin1String + # - PyUnicode_AsMBCSString + # - PyUnicode_AsRawUnicodeEscapeString + # - PyUnicode_AsUTF16String + # - PyUnicode_AsUTF32String + # - PyUnicode_AsUTF8String + # - PyUnicode_AsUnicodeEscapeString + # - PyUnicode_BuildEncodingMap + # - PyUnicode_Decode + # - PyUnicode_DecodeASCII + # - PyUnicode_DecodeCharmap + # - PyUnicode_DecodeCodePageStateful + # - PyUnicode_DecodeFSDefault + # - PyUnicode_DecodeFSDefaultAndSize + # - PyUnicode_DecodeLatin1 + # - PyUnicode_DecodeLocale + # - PyUnicode_DecodeLocaleAndSize + # - PyUnicode_DecodeMBCS + # - PyUnicode_DecodeMBCSStateful + # - PyUnicode_DecodeRawUnicodeEscape + # - PyUnicode_DecodeUTF16 + # - PyUnicode_DecodeUTF16Stateful + # - PyUnicode_DecodeUTF32 + # - PyUnicode_DecodeUTF32Stateful + # - PyUnicode_DecodeUTF7 + # - PyUnicode_DecodeUTF7Stateful + # - PyUnicode_DecodeUTF8 + # - PyUnicode_DecodeUTF8Stateful + # - PyUnicode_DecodeUnicodeEscape + # - PyUnicode_EncodeCodePage + # - PyUnicode_EncodeFSDefault + # - PyUnicode_EncodeLocale + # - PyUnicode_FSConverter + # - PyUnicode_FSDecoder + # - PyUnicode_FromEncodedObject + # - PyUnicode_Splitlines + + # TODO: Add tests to the following character functions: + # - Py_UNICODE_ISALNUM + # - Py_UNICODE_ISALPHA + # - Py_UNICODE_ISDECIMAL + # - Py_UNICODE_ISDIGIT + # - Py_UNICODE_ISLINEBREAK + # - Py_UNICODE_ISLOWER + # - Py_UNICODE_ISNUMERIC + # - Py_UNICODE_ISPRINTABLE + # - Py_UNICODE_ISSPACE + # - Py_UNICODE_ISTITLE + # - Py_UNICODE_ISUPPER + # - Py_UNICODE_TODECIMAL + # - Py_UNICODE_TODIGIT + # - Py_UNICODE_TOLOWER + # - Py_UNICODE_TONUMERIC + # - Py_UNICODE_TOTITLE + # - Py_UNICODE_TOUPPER + + # TODO: Maybe add tests to the following less important functions: + # - PyUnicode_1BYTE_DATA + # - PyUnicode_2BYTE_DATA + # - PyUnicode_4BYTE_DATA + # - PyUnicode_DATA + # - PyUnicode_IS_READY + # - PyUnicode_READY + # - Py_UNICODE_HIGH_SURROGATE + # - Py_UNICODE_IS_HIGH_SURROGATE + # - Py_UNICODE_IS_LOW_SURROGATE + # - Py_UNICODE_IS_SURROGATE + # - Py_UNICODE_JOIN_SURROGATES + # - Py_UNICODE_LOW_SURROGATE + if __name__ == "__main__": unittest.main() diff --git a/Modules/_testcapi/unicode.c b/Modules/_testcapi/unicode.c index c23aab385b1d7d..8c9e3e9b5321d4 100644 --- a/Modules/_testcapi/unicode.c +++ b/Modules/_testcapi/unicode.c @@ -220,6 +220,8 @@ unicode_copycharacters(PyObject *self, PyObject *args) return Py_BuildValue("(Nn)", to_copy, copied); } + +// Test PyUnstable_Unicode_GET_CACHED_HASH() static PyObject* unicode_GET_CACHED_HASH(PyObject *self, PyObject *arg) { @@ -295,6 +297,148 @@ corrupt_unicode(PyObject *Py_UNUSED(module), PyObject *args) } +/* Test PyUnicode_READ_CHAR() */ +static PyObject * +unicode_read_char(PyObject *self, PyObject *args) +{ + PyObject *unicode; + Py_ssize_t index; + if (!PyArg_ParseTuple(args, "On", &unicode, &index)) { + return NULL; + } + NULLABLE(unicode); + + Py_UCS4 result = PyUnicode_READ_CHAR(unicode, index); + return PyLong_FromUnsignedLong(result); +} + + +/* Test PyUnicode_READ() macro */ +static PyObject * +unicode_read(PyObject *self, PyObject *args) +{ + PyObject *unicode; + Py_ssize_t index; + if (!PyArg_ParseTuple(args, "On", &unicode, &index)) { + return NULL; + } + NULLABLE(unicode); + + int kind = PyUnicode_KIND(unicode); + const void *data = PyUnicode_DATA(unicode); + Py_UCS4 result = PyUnicode_READ(kind, data, index); + return PyLong_FromUnsignedLong(result); +} + + +/* Test PyUnicode_WRITE() macro */ +static PyObject * +unicode_write(PyObject *self, PyObject *args) +{ + PyObject *unicode; + Py_ssize_t index; + unsigned int character; + if (!PyArg_ParseTuple(args, "OnI", &unicode, &index, &character)) { + return NULL; + } + NULLABLE(unicode); + + PyObject *copy = unicode_copy(unicode); + if (copy == NULL) { + return NULL; + } + + int kind = PyUnicode_KIND(copy); + const void *data = PyUnicode_DATA(copy); + PyUnicode_WRITE(kind, data, index, character); + // Same return value than _testlimitedcapi unicode_writechar(): + // always use 0 as the function result + return Py_BuildValue("(Ni)", copy, 0); +} + + +/* Test PyUnicode_KIND() macro */ +static PyObject * +unicode_kind(PyObject *self, PyObject *unicode) +{ + NULLABLE(unicode); + + int kind = PyUnicode_KIND(unicode); + return PyLong_FromLong(kind); +} + + +/* Test PyUnicode_MAX_CHAR_VALUE() macro */ +static PyObject * +unicode_max_char_value(PyObject *self, PyObject *unicode) +{ + NULLABLE(unicode); + + Py_UCS4 maxchar = PyUnicode_MAX_CHAR_VALUE(unicode); + return PyLong_FromUnsignedLong(maxchar); +} + + +/* Test PyUnicode_GET_LENGTH() macro */ +static PyObject * +unicode_getlength_macro(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyLong_FromSsize_t(PyUnicode_GET_LENGTH(arg)); +} + + +/* Test PyUnicode_Equal() macro */ +static PyObject * +unicode_equal(PyObject *self, PyObject *args) +{ + PyObject *str1, *str2; + if (!PyArg_ParseTuple(args, "OnI", &str1, &str2)) { + return NULL; + } + NULLABLE(str1); + NULLABLE(str2); + + RETURN_INT(PyUnicode_Equal(str1, str2)); +} + + +/* Test PyUnicode_CHECK_INTERNED() macro */ +static PyObject * +unicode_check_interned(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + RETURN_UINT(PyUnicode_CHECK_INTERNED(arg)); +} + + +/* Test PyUnicode_IS_ASCII() macro */ +static PyObject * +unicode_is_ascii(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + RETURN_UINT(PyUnicode_IS_ASCII(arg)); +} + + +/* Test PyUnicode_IS_COMPACT() macro */ +static PyObject * +unicode_is_compact(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + RETURN_UINT(PyUnicode_IS_COMPACT(arg)); +} + + +/* Test PyUnicode_IS_COMPACT_ASCII() macro */ +static PyObject * +unicode_is_compact_ascii(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + RETURN_INT(PyUnicode_IS_COMPACT_ASCII(arg)); +} + + // --- PyUnicodeWriter type ------------------------------------------------- typedef struct { @@ -642,6 +786,17 @@ static PyMethodDef TestMethods[] = { {"unicode_GET_CACHED_HASH", unicode_GET_CACHED_HASH, METH_O}, {"test_py_identifier", test_py_identifier, METH_NOARGS}, {"corrupt_unicode", corrupt_unicode, METH_VARARGS}, + {"unicode_read_char", unicode_read_char, METH_VARARGS}, + {"unicode_read", unicode_read, METH_VARARGS}, + {"unicode_write", unicode_write, METH_VARARGS}, + {"unicode_kind", unicode_kind, METH_O}, + {"unicode_max_char_value", unicode_max_char_value, METH_O}, + {"unicode_getlength_macro", unicode_getlength_macro, METH_O}, + {"unicode_equal", unicode_equal, METH_VARARGS}, + {"unicode_check_interned", unicode_check_interned, METH_O}, + {"unicode_is_ascii", unicode_is_ascii, METH_O}, + {"unicode_is_compact", unicode_is_compact, METH_O}, + {"unicode_is_compact_ascii", unicode_is_compact_ascii, METH_O}, {NULL}, }; diff --git a/Modules/_testcapi/util.h b/Modules/_testcapi/util.h index 042e522542eddb..c20472e24f3d46 100644 --- a/Modules/_testcapi/util.h +++ b/Modules/_testcapi/util.h @@ -14,6 +14,16 @@ return PyLong_FromLong(_ret); \ } while (0) +#define RETURN_UINT(value) do { \ + unsigned int _ret = (value); \ + if (_ret == (unsigned int)-1) { \ + assert(PyErr_Occurred()); \ + return NULL; \ + } \ + assert(!PyErr_Occurred()); \ + return PyLong_FromUnsignedLong(_ret); \ + } while (0) + #define RETURN_SIZE(value) do { \ Py_ssize_t _ret = (value); \ if (_ret == -1) { \ diff --git a/Modules/_testlimitedcapi/unicode.c b/Modules/_testlimitedcapi/unicode.c index 980b192fdc3cbb..a8511a8242fe7a 100644 --- a/Modules/_testlimitedcapi/unicode.c +++ b/Modules/_testlimitedcapi/unicode.c @@ -1855,6 +1855,23 @@ unicode_equal(PyObject *module, PyObject *args) } +/* Test PyUnicode_Check() */ +static PyObject * +unicode_check(PyObject *module, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyUnicode_Check(obj)); +} + + +/* Test PyUnicode_CheckExact() */ +static PyObject * +unicode_checkexact(PyObject *module, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyUnicode_CheckExact(obj)); +} + static PyMethodDef TestMethods[] = { {"codec_incrementalencoder", codec_incrementalencoder, METH_VARARGS}, @@ -1944,6 +1961,8 @@ static PyMethodDef TestMethods[] = { {"unicode_contains", unicode_contains, METH_VARARGS}, {"unicode_isidentifier", unicode_isidentifier, METH_O}, {"unicode_equal", unicode_equal, METH_VARARGS}, + {"unicode_check", unicode_check, METH_O}, + {"unicode_checkexact", unicode_checkexact, METH_O}, {NULL}, }; From 9193375382fbfc871a8a1c14f918895081e219a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=8E=E3=82=A6=E3=83=A9=20=7C=20Flare?= Date: Sat, 19 Sep 2026 18:11:49 +0200 Subject: [PATCH 11/11] gh-157549: Use sysconf() for the page size in remote_debug.h (#157800) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getpagesize() is not an ISO C or POSIX function. Darwin hides the prototype under -std=c11, so the _remote_debugging build fails with -Werror=implicit-function-declaration. That is the failure in the reported x86_64-apple-darwin → arm64-apple-darwin cross build. Call sysconf(_SC_PAGESIZE) instead, which is already how resource.getpagesize() works. Fall back to 4096 if sysconf() fails. --without-remote-debug is unchanged. That flag only disables the target-side attach protocol (Py_REMOTE_DEBUG); it does not exclude the _remote_debugging client module. --- .../next/Build/2026-09-19-16-54-58.gh-issue-157549.uk6QNH.rst | 3 +++ Python/remote_debug.h | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Build/2026-09-19-16-54-58.gh-issue-157549.uk6QNH.rst diff --git a/Misc/NEWS.d/next/Build/2026-09-19-16-54-58.gh-issue-157549.uk6QNH.rst b/Misc/NEWS.d/next/Build/2026-09-19-16-54-58.gh-issue-157549.uk6QNH.rst new file mode 100644 index 00000000000000..eab0335aa67114 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-09-19-16-54-58.gh-issue-157549.uk6QNH.rst @@ -0,0 +1,3 @@ +Use ``sysconf(_SC_PAGESIZE)`` instead of ``getpagesize()`` in +``remote_debug.h`` so ``_remote_debugging`` builds on Darwin with +``-Werror=implicit-function-declaration``. diff --git a/Python/remote_debug.h b/Python/remote_debug.h index 12c5963f97c0e6..caea3d5c062e5f 100644 --- a/Python/remote_debug.h +++ b/Python/remote_debug.h @@ -142,7 +142,8 @@ get_page_size(void) { GetSystemInfo(&si); page_size = si.dwPageSize; #else - page_size = (size_t)getpagesize(); + long n = sysconf(_SC_PAGESIZE); + page_size = (n > 0) ? (size_t)n : 4096; #endif } return page_size;