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/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 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, + } 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/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 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" 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/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/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/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/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_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/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_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/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_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/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/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/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. 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/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. 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 3882b9a5ddff3c..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) { @@ -6386,6 +6346,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 +6483,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; } 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/_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}, }; 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/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, }; 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/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; 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()