Python-checkins
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
February 2024
- 1 participants
- 877 discussions
Feb. 29, 2024
https://github.com/python/cpython/commit/556749c3e33f7787da149f75ca1702b803…
commit: 556749c3e33f7787da149f75ca1702b80383bead
branch: main
author: Dino Viehland <dinoviehland(a)meta.com>
committer: DinoV <dinoviehland(a)gmail.com>
date: 2024-02-29T13:38:50-08:00
summary:
gh-112075: Avoid locking shared keys on every assignment (#116087)
files:
M Objects/dictobject.c
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 5016e255f70ef9..9b8fc4a958f7ad 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -1597,19 +1597,11 @@ insertion_resize(PyInterpreterState *interp, PyDictObject *mp, int unicode)
}
static Py_ssize_t
-insert_into_splitdictkeys(PyDictKeysObject *keys, PyObject *name)
+insert_into_splitdictkeys(PyDictKeysObject *keys, PyObject *name, Py_hash_t hash)
{
assert(PyUnicode_CheckExact(name));
ASSERT_KEYS_LOCKED(keys);
- Py_hash_t hash = unicode_get_hash(name);
- if (hash == -1) {
- hash = PyUnicode_Type.tp_hash(name);
- if (hash == -1) {
- PyErr_Clear();
- return DKIX_EMPTY;
- }
- }
Py_ssize_t ix = unicodekeys_lookup_unicode(keys, name, hash);
if (ix == DKIX_EMPTY) {
if (keys->dk_usable <= 0) {
@@ -6692,8 +6684,25 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
Py_ssize_t ix = DKIX_EMPTY;
if (PyUnicode_CheckExact(name)) {
- LOCK_KEYS(keys);
- ix = insert_into_splitdictkeys(keys, name);
+ Py_hash_t hash = unicode_get_hash(name);
+ if (hash == -1) {
+ hash = PyUnicode_Type.tp_hash(name);
+ assert(hash != -1);
+ }
+
+#ifdef Py_GIL_DISABLED
+ // Try a thread-safe lookup to see if the index is already allocated
+ ix = unicodekeys_lookup_unicode_threadsafe(keys, name, hash);
+ if (ix == DKIX_EMPTY) {
+ // Lock keys and do insert
+ LOCK_KEYS(keys);
+ ix = insert_into_splitdictkeys(keys, name, hash);
+ UNLOCK_KEYS(keys);
+ }
+#else
+ ix = insert_into_splitdictkeys(keys, name, hash);
+#endif
+
#ifdef Py_STATS
if (ix == DKIX_EMPTY) {
if (PyUnicode_CheckExact(name)) {
@@ -6709,7 +6718,6 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
}
}
#endif
- UNLOCK_KEYS(keys);
}
if (ix == DKIX_EMPTY) {
PyObject *dict = make_dict_from_instance_attributes(
1
0
gh-71052: Add test exclusions to support running the test suite on Android (#115918)
by erlend-aasland Feb. 29, 2024
by erlend-aasland Feb. 29, 2024
Feb. 29, 2024
https://github.com/python/cpython/commit/41d5391c551e2012f13d56ff4bcc1df15c…
commit: 41d5391c551e2012f13d56ff4bcc1df15c2821d3
branch: main
author: Malcolm Smith <smith(a)chaquo.com>
committer: erlend-aasland <erlend.aasland(a)protonmail.com>
date: 2024-02-29T22:32:50+01:00
summary:
gh-71052: Add test exclusions to support running the test suite on Android (#115918)
files:
A Misc/NEWS.d/next/Tests/2024-02-25-16-28-26.gh-issue-71052.lSb9EC.rst
M Lib/test/support/__init__.py
M Lib/test/support/os_helper.py
M Lib/test/test_asyncio/test_subprocess.py
M Lib/test/test_compileall.py
M Lib/test/test_fcntl.py
M Lib/test/test_interpreters/test_lifecycle.py
M Lib/test/test_os.py
M Lib/test/test_pathlib/test_pathlib.py
M Lib/test/test_posix.py
M Lib/test/test_pty.py
M Lib/test/test_venv.py
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 401b2ce1fe213c..14e3766a34377b 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -532,24 +532,33 @@ def requires_debug_ranges(reason='requires co_positions / debug_ranges'):
is_emscripten = sys.platform == "emscripten"
is_wasi = sys.platform == "wasi"
-# Apple mobile platforms (iOS/tvOS/watchOS) are POSIX-like but do not
-# have subprocess or fork support.
is_apple_mobile = sys.platform in {"ios", "tvos", "watchos"}
is_apple = is_apple_mobile or sys.platform == "darwin"
has_fork_support = hasattr(os, "fork") and not (
+ # WASM and Apple mobile platforms do not support subprocesses.
is_emscripten
or is_wasi
or is_apple_mobile
+
+ # Although Android supports fork, it's unsafe to call it from Python because
+ # all Android apps are multi-threaded.
+ or is_android
)
def requires_fork():
return unittest.skipUnless(has_fork_support, "requires working os.fork()")
has_subprocess_support = not (
+ # WASM and Apple mobile platforms do not support subprocesses.
is_emscripten
or is_wasi
or is_apple_mobile
+
+ # Although Android supports subproceses, they're almost never useful in
+ # practice (see PEP 738). And most of the tests that use them are calling
+ # sys.executable, which won't work when Python is embedded in an Android app.
+ or is_android
)
def requires_subprocess():
diff --git a/Lib/test/support/os_helper.py b/Lib/test/support/os_helper.py
index 22787e32b5f3ab..ffa5fc52e9b2bd 100644
--- a/Lib/test/support/os_helper.py
+++ b/Lib/test/support/os_helper.py
@@ -198,6 +198,23 @@ def skip_unless_symlink(test):
return test if ok else unittest.skip(msg)(test)
+_can_hardlink = None
+
+def can_hardlink():
+ global _can_hardlink
+ if _can_hardlink is None:
+ # Android blocks hard links using SELinux
+ # (https://stackoverflow.com/q/32365690).
+ _can_hardlink = hasattr(os, "link") and not support.is_android
+ return _can_hardlink
+
+
+def skip_unless_hardlink(test):
+ ok = can_hardlink()
+ msg = "requires hardlink support"
+ return test if ok else unittest.skip(msg)(test)
+
+
_can_xattr = None
diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py
index f50a9ebc031ba8..890c0acc1720dc 100644
--- a/Lib/test/test_asyncio/test_subprocess.py
+++ b/Lib/test/test_asyncio/test_subprocess.py
@@ -13,6 +13,8 @@
from test import support
from test.support import os_helper
+if not support.has_subprocess_support:
+ raise unittest.SkipTest("test module requires subprocess")
if support.MS_WINDOWS:
import msvcrt
@@ -47,7 +49,6 @@ def _start(self, *args, **kwargs):
self._proc.pid = -1
-(a)support.requires_subprocess()
class SubprocessTransportTests(test_utils.TestCase):
def setUp(self):
super().setUp()
@@ -111,7 +112,6 @@ def test_subprocess_repr(self):
transport.close()
-(a)support.requires_subprocess()
class SubprocessMixin:
def test_stdin_stdout(self):
diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py
index 0ec6013dc11e3e..14c2af19e3eb28 100644
--- a/Lib/test/test_compileall.py
+++ b/Lib/test/test_compileall.py
@@ -977,7 +977,7 @@ class CommandLineTestsNoSourceEpoch(CommandLineTestsBase,
-(a)unittest.skipUnless(hasattr(os, 'link'), 'requires os.link')
+(a)os_helper.skip_unless_hardlink
class HardlinkDedupTestsBase:
# Test hardlink_dupes parameter of compileall.compile_dir()
diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py
index 6d734d052454d3..8b4ed4a9e3a4fe 100644
--- a/Lib/test/test_fcntl.py
+++ b/Lib/test/test_fcntl.py
@@ -129,7 +129,8 @@ def test_fcntl_bad_file_overflow(self):
fcntl.fcntl(BadFile(INT_MIN - 1), fcntl.F_SETFL, os.O_NONBLOCK)
@unittest.skipIf(
- platform.machine().startswith('arm') and platform.system() == 'Linux',
+ any(platform.machine().startswith(name) for name in {"arm", "aarch"})
+ and platform.system() in {"Linux", "Android"},
"ARM Linux returns EINVAL for F_NOTIFY DN_MULTISHOT")
def test_fcntl_64_bit(self):
# Issue #1309352: fcntl shouldn't fail when the third arg fits in a
diff --git a/Lib/test/test_interpreters/test_lifecycle.py b/Lib/test/test_interpreters/test_lifecycle.py
index 67b6f439c3191f..becf003e2e5f20 100644
--- a/Lib/test/test_interpreters/test_lifecycle.py
+++ b/Lib/test/test_interpreters/test_lifecycle.py
@@ -164,6 +164,7 @@ def test_sys_path_0(self):
class FinalizationTests(TestBase):
+ @support.requires_subprocess()
def test_gh_109793(self):
# Make sure finalization finishes and the correct error code
# is reported, even when subinterpreters get cleaned up at the end.
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 2372ac4c21efd9..3b2d5fccc30f3c 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -1592,6 +1592,9 @@ def test_yields_correct_dir_fd(self):
@unittest.skipIf(
support.is_emscripten, "Cannot dup stdout on Emscripten"
)
+ @unittest.skipIf(
+ support.is_android, "dup return value is unpredictable on Android"
+ )
def test_fd_leak(self):
# Since we're opening a lot of FDs, we must be careful to avoid leaks:
# we both check that calling fwalk() a large number of times doesn't
@@ -2492,8 +2495,10 @@ def test_listdir(self):
# test listdir without arguments
current_directory = os.getcwd()
try:
- os.chdir(os.sep)
- self.assertEqual(set(os.listdir()), set(os.listdir(os.sep)))
+ # The root directory is not readable on Android, so use a directory
+ # we created ourselves.
+ os.chdir(self.dir)
+ self.assertEqual(set(os.listdir()), expected)
finally:
os.chdir(current_directory)
@@ -4838,7 +4843,7 @@ def check_entry(self, entry, name, is_dir, is_file, is_symlink):
os.name == 'nt')
def test_attributes(self):
- link = hasattr(os, 'link')
+ link = os_helper.can_hardlink()
symlink = os_helper.can_symlink()
dirname = os.path.join(self.path, "dir")
diff --git a/Lib/test/test_pathlib/test_pathlib.py b/Lib/test/test_pathlib/test_pathlib.py
index c0dcf314da4bfc..7e44ae61a5eba7 100644
--- a/Lib/test/test_pathlib/test_pathlib.py
+++ b/Lib/test/test_pathlib/test_pathlib.py
@@ -796,7 +796,7 @@ def test_rmdir(self):
self.assertFileNotFound(p.stat)
self.assertFileNotFound(p.unlink)
- @unittest.skipUnless(hasattr(os, "link"), "os.link() is not present")
+ @os_helper.skip_unless_hardlink
def test_hardlink_to(self):
P = self.cls(self.base)
target = P / 'fileA'
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index a45f620e18dc1d..2706d5eb6d9830 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -1270,9 +1270,10 @@ def test_get_and_set_scheduler_and_param(self):
self.assertIn(mine, possible_schedulers)
try:
parent = posix.sched_getscheduler(os.getppid())
- except OSError as e:
- if e.errno != errno.EPERM:
- raise
+ except PermissionError:
+ # POSIX specifies EPERM, but Android returns EACCES. Both errno
+ # values are mapped to PermissionError.
+ pass
else:
self.assertIn(parent, possible_schedulers)
self.assertRaises(OSError, posix.sched_getscheduler, -1)
@@ -1287,9 +1288,8 @@ def test_get_and_set_scheduler_and_param(self):
try:
posix.sched_setscheduler(0, mine, param)
posix.sched_setparam(0, param)
- except OSError as e:
- if e.errno != errno.EPERM:
- raise
+ except PermissionError:
+ pass
self.assertRaises(OSError, posix.sched_setparam, -1, param)
self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param)
diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py
index 3f2bac0155fd9e..dee94533c74549 100644
--- a/Lib/test/test_pty.py
+++ b/Lib/test/test_pty.py
@@ -1,7 +1,6 @@
-import sys
import unittest
from test.support import (
- is_apple_mobile, is_emscripten, is_wasi, reap_children, verbose
+ is_android, is_apple_mobile, is_emscripten, is_wasi, reap_children, verbose
)
from test.support.import_helper import import_module
from test.support.os_helper import TESTFN, unlink
@@ -9,9 +8,8 @@
# Skip these tests if termios is not available
import_module('termios')
-# Skip tests on WASM platforms, plus iOS/tvOS/watchOS
-if is_apple_mobile or is_emscripten or is_wasi:
- raise unittest.SkipTest(f"pty tests not required on {sys.platform}")
+if is_android or is_apple_mobile or is_emscripten or is_wasi:
+ raise unittest.SkipTest("pty is not available on this platform")
import errno
import os
diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py
index ba31beb81e80b0..f60c662d322e38 100644
--- a/Lib/test/test_venv.py
+++ b/Lib/test/test_venv.py
@@ -19,8 +19,9 @@
import tempfile
from test.support import (captured_stdout, captured_stderr,
skip_if_broken_multiprocessing_synchronize, verbose,
- requires_subprocess, is_apple_mobile, is_emscripten,
- is_wasi, requires_venv_with_pip, TEST_HOME_DIR,
+ requires_subprocess, is_android, is_apple_mobile,
+ is_emscripten, is_wasi,
+ requires_venv_with_pip, TEST_HOME_DIR,
requires_resource, copy_python_src_ignore)
from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree)
import unittest
@@ -39,10 +40,8 @@
or sys._base_executable != sys.executable,
'cannot run venv.create from within a venv on this platform')
-# Skip tests on WASM platforms, plus iOS/tvOS/watchOS
-if is_apple_mobile or is_emscripten or is_wasi:
- raise unittest.SkipTest(f"venv tests not required on {sys.platform}")
-
+if is_android or is_apple_mobile or is_emscripten or is_wasi:
+ raise unittest.SkipTest("venv is not available on this platform")
@requires_subprocess()
def check_output(cmd, encoding=None):
diff --git a/Misc/NEWS.d/next/Tests/2024-02-25-16-28-26.gh-issue-71052.lSb9EC.rst b/Misc/NEWS.d/next/Tests/2024-02-25-16-28-26.gh-issue-71052.lSb9EC.rst
new file mode 100644
index 00000000000000..9d3467ca7e7d40
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2024-02-25-16-28-26.gh-issue-71052.lSb9EC.rst
@@ -0,0 +1 @@
+Add test exclusions to support running the test suite on Android.
1
0
Feb. 29, 2024
https://github.com/python/cpython/commit/211b55951d239dbbf5379f61e941b22cee…
commit: 211b55951d239dbbf5379f61e941b22cee3f4edb
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: hugovk <1324225+hugovk(a)users.noreply.github.com>
date: 2024-02-29T21:32:14Z
summary:
[3.12] gh-112844: Add SBOM for external dependencies (GH-115789) (#116128)
Co-authored-by: Seth Michael Larson <seth(a)python.org>
files:
A Misc/externals.spdx.json
M .github/CODEOWNERS
M Tools/build/generate_sbom.py
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 41bb3e73638fab..c77bfb8d0d589a 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -168,5 +168,6 @@ Lib/ast.py @isidentical
**/*zipfile/_path/* @jaraco
# SBOM
+/Misc/externals.spdx.json @sethmlarson
/Misc/sbom.spdx.json @sethmlarson
/Tools/build/generate_sbom.py @sethmlarson
diff --git a/Misc/externals.spdx.json b/Misc/externals.spdx.json
new file mode 100644
index 00000000000000..12cbc54c756a4e
--- /dev/null
+++ b/Misc/externals.spdx.json
@@ -0,0 +1,195 @@
+{
+ "SPDXID": "SPDXRef-DOCUMENT",
+ "packages": [
+ {
+ "SPDXID": "SPDXRef-PACKAGE-bzip2",
+ "checksums": [
+ {
+ "algorithm": "SHA256",
+ "checksumValue": "ab8d1b0cc087c20d4c32c0e4fcf7d0c733a95da12cedc6d63b3f0a9af07427e2"
+ }
+ ],
+ "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/bzip2-1.0.8…",
+ "externalRefs": [
+ {
+ "referenceCategory": "SECURITY",
+ "referenceLocator": "cpe:2.3:a:bzip:bzip2:1.0.8:*:*:*:*:*:*:*",
+ "referenceType": "cpe23Type"
+ }
+ ],
+ "licenseConcluded": "NOASSERTION",
+ "name": "bzip2",
+ "primaryPackagePurpose": "SOURCE",
+ "versionInfo": "1.0.8"
+ },
+ {
+ "SPDXID": "SPDXRef-PACKAGE-libffi",
+ "checksums": [
+ {
+ "algorithm": "SHA256",
+ "checksumValue": "9d802681adfea27d84cae0487a785fb9caa925bdad44c401b364c59ab2b8edda"
+ }
+ ],
+ "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/libffi-3.4.…",
+ "externalRefs": [
+ {
+ "referenceCategory": "SECURITY",
+ "referenceLocator": "cpe:2.3:a:libffi_project:libffi:3.4.4:*:*:*:*:*:*:*",
+ "referenceType": "cpe23Type"
+ }
+ ],
+ "licenseConcluded": "NOASSERTION",
+ "name": "libffi",
+ "primaryPackagePurpose": "SOURCE",
+ "versionInfo": "3.4.4"
+ },
+ {
+ "SPDXID": "SPDXRef-PACKAGE-openssl",
+ "checksums": [
+ {
+ "algorithm": "SHA256",
+ "checksumValue": "e6a77c273ebb284fedd8ea19b081fce74a9455936ffd47215f7c24713e2614b2"
+ }
+ ],
+ "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/openssl-3.0…",
+ "externalRefs": [
+ {
+ "referenceCategory": "SECURITY",
+ "referenceLocator": "cpe:2.3:a:openssl:openssl:3.0.13:*:*:*:*:*:*:*",
+ "referenceType": "cpe23Type"
+ }
+ ],
+ "licenseConcluded": "NOASSERTION",
+ "name": "openssl",
+ "primaryPackagePurpose": "SOURCE",
+ "versionInfo": "3.0.13"
+ },
+ {
+ "SPDXID": "SPDXRef-PACKAGE-sqlite",
+ "checksums": [
+ {
+ "algorithm": "SHA256",
+ "checksumValue": "6f0364a27375435a34137b138ca4fedef8d23eec6493ca1dfff33bfc0c34fda4"
+ }
+ ],
+ "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/sqlite-3.45…",
+ "externalRefs": [
+ {
+ "referenceCategory": "SECURITY",
+ "referenceLocator": "cpe:2.3:a:sqlite:sqlite:3.45.1.0:*:*:*:*:*:*:*",
+ "referenceType": "cpe23Type"
+ }
+ ],
+ "licenseConcluded": "NOASSERTION",
+ "name": "sqlite",
+ "primaryPackagePurpose": "SOURCE",
+ "versionInfo": "3.45.1.0"
+ },
+ {
+ "SPDXID": "SPDXRef-PACKAGE-tcl-core",
+ "checksums": [
+ {
+ "algorithm": "SHA256",
+ "checksumValue": "6e33a88f116822167734cd72b693b5d30ced130a3cae6dc2ff696042f993bb42"
+ }
+ ],
+ "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/tcl-core-8.…",
+ "externalRefs": [
+ {
+ "referenceCategory": "SECURITY",
+ "referenceLocator": "cpe:2.3:a:tcl_tk:tcl_tk:8.6.13.0:*:*:*:*:*:*:*",
+ "referenceType": "cpe23Type"
+ }
+ ],
+ "licenseConcluded": "NOASSERTION",
+ "name": "tcl-core",
+ "primaryPackagePurpose": "SOURCE",
+ "versionInfo": "8.6.13.0"
+ },
+ {
+ "SPDXID": "SPDXRef-PACKAGE-tk",
+ "checksums": [
+ {
+ "algorithm": "SHA256",
+ "checksumValue": "896c1f488bdd0159091bd5cce124b756dfdffa4a5350b7fd4d7d8e48421089a4"
+ }
+ ],
+ "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/tk-8.6.13.0…",
+ "externalRefs": [
+ {
+ "referenceCategory": "SECURITY",
+ "referenceLocator": "cpe:2.3:a:tcl_tk:tcl_tk:8.6.13.0:*:*:*:*:*:*:*",
+ "referenceType": "cpe23Type"
+ }
+ ],
+ "licenseConcluded": "NOASSERTION",
+ "name": "tk",
+ "primaryPackagePurpose": "SOURCE",
+ "versionInfo": "8.6.13.0"
+ },
+ {
+ "SPDXID": "SPDXRef-PACKAGE-tix",
+ "checksums": [
+ {
+ "algorithm": "SHA256",
+ "checksumValue": "f7b21d115867a41ae5fd7c635a4c234d3ca25126c3661eb36028c6e25601f85e"
+ }
+ ],
+ "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/tix-8.4.3.6…",
+ "externalRefs": [
+ {
+ "referenceCategory": "SECURITY",
+ "referenceLocator": "cpe:2.3:a:tcl_tk:tcl_tk:8.4.3.6:*:*:*:*:*:*:*",
+ "referenceType": "cpe23Type"
+ }
+ ],
+ "licenseConcluded": "NOASSERTION",
+ "name": "tix",
+ "primaryPackagePurpose": "SOURCE",
+ "versionInfo": "8.4.3.6"
+ },
+ {
+ "SPDXID": "SPDXRef-PACKAGE-xz",
+ "checksums": [
+ {
+ "algorithm": "SHA256",
+ "checksumValue": "a15c168e39e87d750c3dc766edc7f19bdda57dacf01e509678467eace91ad282"
+ }
+ ],
+ "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/xz-5.2.5.ta…",
+ "externalRefs": [
+ {
+ "referenceCategory": "SECURITY",
+ "referenceLocator": "cpe:2.3:a:xz_project:xz:5.2.5:*:*:*:*:*:*:*",
+ "referenceType": "cpe23Type"
+ }
+ ],
+ "licenseConcluded": "NOASSERTION",
+ "name": "xz",
+ "primaryPackagePurpose": "SOURCE",
+ "versionInfo": "5.2.5"
+ },
+ {
+ "SPDXID": "SPDXRef-PACKAGE-zlib",
+ "checksums": [
+ {
+ "algorithm": "SHA256",
+ "checksumValue": "e3f3fb32564952006eb18b091ca8464740e5eca29d328cfb0b2da22768e0b638"
+ }
+ ],
+ "downloadLocation": "https://github.com/python/cpython-source-deps/archive/refs/tags/zlib-1.3.1.…",
+ "externalRefs": [
+ {
+ "referenceCategory": "SECURITY",
+ "referenceLocator": "cpe:2.3:a:zlib:zlib:1.3.1:*:*:*:*:*:*:*",
+ "referenceType": "cpe23Type"
+ }
+ ],
+ "licenseConcluded": "NOASSERTION",
+ "name": "zlib",
+ "primaryPackagePurpose": "SOURCE",
+ "versionInfo": "1.3.1"
+ }
+ ],
+ "spdxVersion": "SPDX-2.3"
+}
\ No newline at end of file
diff --git a/Tools/build/generate_sbom.py b/Tools/build/generate_sbom.py
index 201c81c4d14d79..6aa4946ee227e7 100644
--- a/Tools/build/generate_sbom.py
+++ b/Tools/build/generate_sbom.py
@@ -7,9 +7,8 @@
import pathlib
import subprocess
import sys
+import urllib.request
import typing
-import zipfile
-from urllib.request import urlopen
CPYTHON_ROOT_DIR = pathlib.Path(__file__).parent.parent.parent
@@ -125,30 +124,41 @@ def filter_gitignored_paths(paths: list[str]) -> list[str]:
return sorted([line.split()[-1] for line in git_check_ignore_lines if line.startswith("::")])
-def main() -> None:
- sbom_path = CPYTHON_ROOT_DIR / "Misc/sbom.spdx.json"
- sbom_data = json.loads(sbom_path.read_bytes())
+def get_externals() -> list[str]:
+ """
+ Parses 'PCbuild/get_externals.bat' for external libraries.
+ Returns a list of (git tag, name, version) tuples.
+ """
+ get_externals_bat_path = CPYTHON_ROOT_DIR / "PCbuild/get_externals.bat"
+ externals = re.findall(
+ r"set\s+libraries\s*=\s*%libraries%\s+([a-zA-Z0-9.-]+)\s",
+ get_externals_bat_path.read_text()
+ )
+ return externals
- # We regenerate all of this information. Package information
- # should be preserved though since that is edited by humans.
- sbom_data["files"] = []
- sbom_data["relationships"] = []
- # Ensure all packages in this tool are represented also in the SBOM file.
- actual_names = {package["name"] for package in sbom_data["packages"]}
- expected_names = set(PACKAGE_TO_FILES)
- error_if(
- actual_names != expected_names,
- f"Packages defined in SBOM tool don't match those defined in SBOM file: {actual_names}, {expected_names}",
- )
+def check_sbom_packages(sbom_data: dict[str, typing.Any]) -> None:
+ """Make a bunch of assertions about the SBOM package data to ensure it's consistent."""
- # Make a bunch of assertions about the SBOM data to ensure it's consistent.
for package in sbom_data["packages"]:
# Properties and ID must be properly formed.
error_if(
"name" not in package,
"Package is missing the 'name' field"
)
+
+ # Verify that the checksum matches the expected value
+ # and that the download URL is valid.
+ if "checksums" not in package or "CI" in os.environ:
+ download_location = package["downloadLocation"]
+ resp = urllib.request.urlopen(download_location)
+ error_if(resp.status != 200, f"Couldn't access URL: {download_location}'")
+
+ package["checksums"] = [{
+ "algorithm": "SHA256",
+ "checksumValue": hashlib.sha256(resp.read()).hexdigest()
+ }]
+
missing_required_keys = REQUIRED_PROPERTIES_PACKAGE - set(package.keys())
error_if(
bool(missing_required_keys),
@@ -180,6 +190,26 @@ def main() -> None:
f"License identifier must be 'NOASSERTION'"
)
+
+def create_source_sbom() -> None:
+ sbom_path = CPYTHON_ROOT_DIR / "Misc/sbom.spdx.json"
+ sbom_data = json.loads(sbom_path.read_bytes())
+
+ # We regenerate all of this information. Package information
+ # should be preserved though since that is edited by humans.
+ sbom_data["files"] = []
+ sbom_data["relationships"] = []
+
+ # Ensure all packages in this tool are represented also in the SBOM file.
+ actual_names = {package["name"] for package in sbom_data["packages"]}
+ expected_names = set(PACKAGE_TO_FILES)
+ error_if(
+ actual_names != expected_names,
+ f"Packages defined in SBOM tool don't match those defined in SBOM file: {actual_names}, {expected_names}",
+ )
+
+ check_sbom_packages(sbom_data)
+
# We call 'sorted()' here a lot to avoid filesystem scan order issues.
for name, files in sorted(PACKAGE_TO_FILES.items()):
package_spdx_id = spdx_id(f"SPDXRef-PACKAGE-{name}")
@@ -224,5 +254,49 @@ def main() -> None:
sbom_path.write_text(json.dumps(sbom_data, indent=2, sort_keys=True))
+def create_externals_sbom() -> None:
+ sbom_path = CPYTHON_ROOT_DIR / "Misc/externals.spdx.json"
+ sbom_data = json.loads(sbom_path.read_bytes())
+
+ externals = get_externals()
+ externals_name_to_version = {}
+ externals_name_to_git_tag = {}
+ for git_tag in externals:
+ name, _, version = git_tag.rpartition("-")
+ externals_name_to_version[name] = version
+ externals_name_to_git_tag[name] = git_tag
+
+ # Ensure all packages in this tool are represented also in the SBOM file.
+ actual_names = {package["name"] for package in sbom_data["packages"]}
+ expected_names = set(externals_name_to_version)
+ error_if(
+ actual_names != expected_names,
+ f"Packages defined in SBOM tool don't match those defined in SBOM file: {actual_names}, {expected_names}",
+ )
+
+ # Set the versionInfo and downloadLocation fields for all packages.
+ for package in sbom_data["packages"]:
+ package["versionInfo"] = externals_name_to_version[package["name"]]
+ download_location = (
+ f"https://github.com/python/cpython-source-deps/archive/refs/tags/{externals_…'name']]}.tar.gz"
+ )
+ download_location_changed = download_location != package["downloadLocation"]
+ package["downloadLocation"] = download_location
+
+ # If the download URL has changed we want one to get recalulated.
+ if download_location_changed:
+ package.pop("checksums", None)
+
+ check_sbom_packages(sbom_data)
+
+ # Update the SBOM on disk
+ sbom_path.write_text(json.dumps(sbom_data, indent=2, sort_keys=True))
+
+
+def main() -> None:
+ create_source_sbom()
+ create_externals_sbom()
+
+
if __name__ == "__main__":
main()
1
0
gh-108051: Update versions found by find_python.bat and clarify readme (GH-116118)
by zooba Feb. 29, 2024
by zooba Feb. 29, 2024
Feb. 29, 2024
https://github.com/python/cpython/commit/83c5ecdeec80fbd1f667f234f626c4154d…
commit: 83c5ecdeec80fbd1f667f234f626c4154d40ebb5
branch: main
author: Steve Dower <steve.dower(a)python.org>
committer: zooba <steve.dower(a)microsoft.com>
date: 2024-02-29T21:24:05Z
summary:
gh-108051: Update versions found by find_python.bat and clarify readme (GH-116118)
files:
M PCbuild/find_python.bat
M PCbuild/readme.txt
diff --git a/PCbuild/find_python.bat b/PCbuild/find_python.bat
index d3f62c93869003..af85f6d362466e 100644
--- a/PCbuild/find_python.bat
+++ b/PCbuild/find_python.bat
@@ -29,6 +29,9 @@
:begin_search
@set PYTHON=
+@rem If PYTHON_FOR_BUILD is set, use that
+@if NOT "%PYTHON_FOR_BUILD%"=="" @(set PYTHON="%PYTHON_FOR_BUILD%") && (set _Py_Python_Source=found as PYTHON_FOR_BUILD) && goto :found
+
@rem If there is an active virtual env, use that one
@if NOT "%VIRTUAL_ENV%"=="" (set PYTHON="%VIRTUAL_ENV%\Scripts\python.exe") & (set _Py_Python_Source=found in virtual env) & goto :found
@@ -42,7 +45,9 @@
@if NOT "%HOST_PYTHON%"=="" @%HOST_PYTHON% -Ec "import sys; assert sys.version_info[:2] >= (3, 9)" >nul 2>nul && (set PYTHON="%HOST_PYTHON%") && (set _Py_Python_Source=found as HOST_PYTHON) && goto :found
@rem If py.exe finds a recent enough version, use that one
-@for %%p in (3.11 3.10 3.9) do @py -%%p -EV >nul 2>&1 && (set PYTHON=py -%%p) && (set _Py_Python_Source=found %%p with py.exe) && goto :found
+@rem It is fine to add new versions to this list when they have released,
+@rem but we do not use prerelease builds here.
+@for %%p in (3.12 3.11 3.10 3.9) do @py -%%p -EV >nul 2>&1 && (set PYTHON=py -%%p) && (set _Py_Python_Source=found %%p with py.exe) && goto :found
@if NOT exist "%_Py_EXTERNALS_DIR%" mkdir "%_Py_EXTERNALS_DIR%"
@set _Py_NUGET=%NUGET%
diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt
index 387565515fa0b0..a7c2a68928ca84 100644
--- a/PCbuild/readme.txt
+++ b/PCbuild/readme.txt
@@ -226,12 +226,18 @@ directory. This script extracts all the external sub-projects from
and
https://github.com/python/cpython-bin-deps
via a Python script called "get_external.py", located in this directory.
-If Python 3.6 or later is not available via the "py.exe" launcher, the
-path or command to use for Python can be provided in the PYTHON_FOR_BUILD
-environment variable, or get_externals.bat will download the latest
-version of NuGet and use it to download the latest "pythonx86" package
-for use with get_external.py. Everything downloaded by these scripts is
-stored in ..\externals (relative to this directory).
+Everything downloaded by these scripts is stored in ..\externals
+(relative to this directory), or the path specified by the EXTERNALS_DIR
+environment variable.
+
+The path or command to use for Python can be provided with the
+PYTHON_FOR_BUILD environment variable. If this is not set, an active
+virtual environment will be used. If none is active, and HOST_PYTHON is
+set to a recent enough version or "py.exe" is able to find a recent
+enough version, those will be used. If all else fails, a copy of Python
+will be downloaded from NuGet and extracted to the externals directory.
+This will then be used for later builds (see PCbuild/find_python.bat
+for the full logic).
It is also possible to download sources from each project's homepage,
though you may have to change folder names or pass the names to MSBuild
1
0
[3.12] gh-73580: Docs for tunnelling TLS through TLS (GH-22539) (GH-116149)
by serhiy-storchaka Feb. 29, 2024
by serhiy-storchaka Feb. 29, 2024
Feb. 29, 2024
https://github.com/python/cpython/commit/811f4bd5a7559581681bfb1cb14c9c6881…
commit: 811f4bd5a7559581681bfb1cb14c9c6881813f63
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: serhiy-storchaka <storchaka(a)gmail.com>
date: 2024-02-29T21:04:02Z
summary:
[3.12] gh-73580: Docs for tunnelling TLS through TLS (GH-22539) (GH-116149)
(cherry picked from commit 91c3c64237f56bde9d1c1b8127fdcb02a112b5a4)
Co-authored-by: Carl Bordum Hansen <carl(a)bordum.dk>
files:
M Doc/library/ssl.rst
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index 9f25016ff164a5..a08bf993fb7c9d 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -1765,6 +1765,9 @@ to speed up repeated connections from the same clients.
*session*, see :attr:`~SSLSocket.session`.
+ To wrap an :class:`SSLSocket` in another :class:`SSLSocket`, use
+ :meth:`SSLContext.wrap_bio`.
+
.. versionchanged:: 3.5
Always allow a server_hostname to be passed, even if OpenSSL does not
have SNI.
1
0
[3.11] gh-73580: Docs for tunnelling TLS through TLS (GH-22539) (GH-116150)
by serhiy-storchaka Feb. 29, 2024
by serhiy-storchaka Feb. 29, 2024
Feb. 29, 2024
https://github.com/python/cpython/commit/8014ffda1dfb4094c52b5a12401abbf22b…
commit: 8014ffda1dfb4094c52b5a12401abbf22b78e4e2
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: serhiy-storchaka <storchaka(a)gmail.com>
date: 2024-02-29T21:03:59Z
summary:
[3.11] gh-73580: Docs for tunnelling TLS through TLS (GH-22539) (GH-116150)
(cherry picked from commit 91c3c64237f56bde9d1c1b8127fdcb02a112b5a4)
Co-authored-by: Carl Bordum Hansen <carl(a)bordum.dk>
files:
M Doc/library/ssl.rst
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index bda3e98d9b0feb..5dbe554d858ad7 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -1860,6 +1860,9 @@ to speed up repeated connections from the same clients.
*session*, see :attr:`~SSLSocket.session`.
+ To wrap an :class:`SSLSocket` in another :class:`SSLSocket`, use
+ :meth:`SSLContext.wrap_bio`.
+
.. versionchanged:: 3.5
Always allow a server_hostname to be passed, even if OpenSSL does not
have SNI.
1
0
Feb. 29, 2024
https://github.com/python/cpython/commit/91c3c64237f56bde9d1c1b8127fdcb02a1…
commit: 91c3c64237f56bde9d1c1b8127fdcb02a112b5a4
branch: main
author: Carl Bordum Hansen <carl(a)bordum.dk>
committer: serhiy-storchaka <storchaka(a)gmail.com>
date: 2024-02-29T22:56:04+02:00
summary:
gh-73580: Docs for tunnelling TLS through TLS (GH-22539)
files:
M Doc/library/ssl.rst
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index fa81c3f208cff7..ce8f3dd2d317c1 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -1790,6 +1790,9 @@ to speed up repeated connections from the same clients.
*session*, see :attr:`~SSLSocket.session`.
+ To wrap an :class:`SSLSocket` in another :class:`SSLSocket`, use
+ :meth:`SSLContext.wrap_bio`.
+
.. versionchanged:: 3.5
Always allow a server_hostname to be passed, even if OpenSSL does not
have SNI.
1
0
[3.11] Docs: mark up NotImplemented using the :data: role throughout the docs (GH-116135) (#116148)
by erlend-aasland Feb. 29, 2024
by erlend-aasland Feb. 29, 2024
Feb. 29, 2024
https://github.com/python/cpython/commit/f4efc135b3549555468c6a813cf2e75738…
commit: f4efc135b3549555468c6a813cf2e75738b6a24e
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: erlend-aasland <erlend.aasland(a)protonmail.com>
date: 2024-02-29T20:53:50Z
summary:
[3.11] Docs: mark up NotImplemented using the :data: role throughout the docs (GH-116135) (#116148)
(cherry picked from commit dbe44f150cd161bd327ed662e527a4c93829fb3e)
Co-authored-by: Erlend E. Aasland <erlend(a)python.org>
files:
M Doc/library/abc.rst
M Doc/library/constants.rst
M Doc/library/exceptions.rst
M Doc/library/importlib.rst
M Doc/library/numbers.rst
M Doc/library/pickle.rst
M Doc/library/stdtypes.rst
M Doc/library/unittest.mock.rst
M Doc/reference/datamodel.rst
M Doc/reference/expressions.rst
M Doc/whatsnew/2.7.rst
M Doc/whatsnew/3.10.rst
M Doc/whatsnew/3.4.rst
M Doc/whatsnew/3.9.rst
M Misc/NEWS.d/3.10.0a6.rst
M Misc/NEWS.d/3.11.0a1.rst
diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst
index c073ea955abaa4..10e2cba50e49b0 100644
--- a/Doc/library/abc.rst
+++ b/Doc/library/abc.rst
@@ -101,11 +101,11 @@ a helper class :class:`ABC` to alternatively define ABCs through inheritance:
subclass of the ABC. (This class method is called from the
:meth:`~class.__subclasscheck__` method of the ABC.)
- This method should return ``True``, ``False`` or ``NotImplemented``. If
+ This method should return ``True``, ``False`` or :data:`NotImplemented`. If
it returns ``True``, the *subclass* is considered a subclass of this ABC.
If it returns ``False``, the *subclass* is not considered a subclass of
this ABC, even if it would normally be one. If it returns
- ``NotImplemented``, the subclass check is continued with the usual
+ :data:`!NotImplemented`, the subclass check is continued with the usual
mechanism.
.. XXX explain the "usual mechanism"
diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst
index 401dc9a320c5e0..93a7244f87de6b 100644
--- a/Doc/library/constants.rst
+++ b/Doc/library/constants.rst
@@ -33,27 +33,27 @@ A small number of constants live in the built-in namespace. They are:
the other type; may be returned by the in-place binary special methods
(e.g. :meth:`~object.__imul__`, :meth:`~object.__iand__`, etc.) for the same purpose.
It should not be evaluated in a boolean context.
- ``NotImplemented`` is the sole instance of the :data:`types.NotImplementedType` type.
+ :data:`!NotImplemented` is the sole instance of the :data:`types.NotImplementedType` type.
.. note::
- When a binary (or in-place) method returns ``NotImplemented`` the
+ When a binary (or in-place) method returns :data:`!NotImplemented` the
interpreter will try the reflected operation on the other type (or some
other fallback, depending on the operator). If all attempts return
- ``NotImplemented``, the interpreter will raise an appropriate exception.
- Incorrectly returning ``NotImplemented`` will result in a misleading
- error message or the ``NotImplemented`` value being returned to Python code.
+ :data:`!NotImplemented`, the interpreter will raise an appropriate exception.
+ Incorrectly returning :data:`!NotImplemented` will result in a misleading
+ error message or the :data:`!NotImplemented` value being returned to Python code.
See :ref:`implementing-the-arithmetic-operations` for examples.
.. note::
- ``NotImplementedError`` and ``NotImplemented`` are not interchangeable,
+ ``NotImplementedError`` and :data:`!NotImplemented` are not interchangeable,
even though they have similar names and purposes.
See :exc:`NotImplementedError` for details on when to use it.
.. versionchanged:: 3.9
- Evaluating ``NotImplemented`` in a boolean context is deprecated. While
+ Evaluating :data:`!NotImplemented` in a boolean context is deprecated. While
it currently evaluates as true, it will emit a :exc:`DeprecationWarning`.
It will raise a :exc:`TypeError` in a future version of Python.
diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst
index eed0ad18b992e4..60600b2436b734 100644
--- a/Doc/library/exceptions.rst
+++ b/Doc/library/exceptions.rst
@@ -335,9 +335,9 @@ The following exceptions are the exceptions that are usually raised.
.. note::
- ``NotImplementedError`` and ``NotImplemented`` are not interchangeable,
+ ``NotImplementedError`` and :data:`NotImplemented` are not interchangeable,
even though they have similar names and purposes. See
- :data:`NotImplemented` for details on when to use it.
+ :data:`!NotImplemented` for details on when to use it.
.. exception:: OSError([arg])
OSError(errno, strerror[, filename[, winerror[, filename2]]])
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index 5978945fcd20f4..e9200dd1e2d027 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -329,7 +329,7 @@ ABC hierarchy::
when invalidating the caches of all finders on :data:`sys.meta_path`.
.. versionchanged:: 3.4
- Returns ``None`` when called instead of ``NotImplemented``.
+ Returns ``None`` when called instead of :data:`NotImplemented`.
.. class:: PathEntryFinder
diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst
index 17d1a275f04c9b..306bdd94aaca13 100644
--- a/Doc/library/numbers.rst
+++ b/Doc/library/numbers.rst
@@ -166,7 +166,7 @@ Complex``. I'll consider ``a + b``:
2. If ``A`` falls back to the boilerplate code, and it were to
return a value from :meth:`~object.__add__`, we'd miss the possibility
that ``B`` defines a more intelligent :meth:`~object.__radd__`, so the
- boilerplate should return :const:`NotImplemented` from
+ boilerplate should return :data:`NotImplemented` from
:meth:`!__add__`. (Or ``A`` may not implement :meth:`!__add__` at
all.)
3. Then ``B``'s :meth:`~object.__radd__` gets a chance. If it accepts
diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst
index b8c9787adc42ec..49417ad24dc6fe 100644
--- a/Doc/library/pickle.rst
+++ b/Doc/library/pickle.rst
@@ -373,7 +373,7 @@ The :mod:`pickle` module exports three classes, :class:`Pickler`,
Special reducer that can be defined in :class:`Pickler` subclasses. This
method has priority over any reducer in the :attr:`dispatch_table`. It
should conform to the same interface as a :meth:`~object.__reduce__` method, and
- can optionally return ``NotImplemented`` to fallback on
+ can optionally return :data:`NotImplemented` to fallback on
:attr:`dispatch_table`-registered reducers to pickle ``obj``.
For a detailed example, see :ref:`reducer_override`.
@@ -495,7 +495,7 @@ What can be pickled and unpickled?
The following types can be pickled:
* built-in constants (``None``, ``True``, ``False``, ``Ellipsis``, and
- ``NotImplemented``);
+ :data:`NotImplemented`);
* integers, floating-point numbers, complex numbers;
@@ -897,7 +897,7 @@ functions and classes.
For those cases, it is possible to subclass from the :class:`Pickler` class and
implement a :meth:`~Pickler.reducer_override` method. This method can return an
arbitrary reduction tuple (see :meth:`~object.__reduce__`). It can alternatively return
-``NotImplemented`` to fallback to the traditional behavior.
+:data:`NotImplemented` to fallback to the traditional behavior.
If both the :attr:`~Pickler.dispatch_table` and
:meth:`~Pickler.reducer_override` are defined, then
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index db9815733fc870..b5bbff077f030e 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -5392,10 +5392,10 @@ The NotImplemented Object
This object is returned from comparisons and binary operations when they are
asked to operate on types they don't support. See :ref:`comparisons` for more
-information. There is exactly one ``NotImplemented`` object.
-``type(NotImplemented)()`` produces the singleton instance.
+information. There is exactly one :data:`NotImplemented` object.
+:code:`type(NotImplemented)()` produces the singleton instance.
-It is written as ``NotImplemented``.
+It is written as :code:`NotImplemented`.
.. _bltin-boolean-values:
diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst
index 837eb14d4c8114..b626c0036fca67 100644
--- a/Doc/library/unittest.mock.rst
+++ b/Doc/library/unittest.mock.rst
@@ -2092,10 +2092,10 @@ to change the default.
Methods and their defaults:
-* ``__lt__``: ``NotImplemented``
-* ``__gt__``: ``NotImplemented``
-* ``__le__``: ``NotImplemented``
-* ``__ge__``: ``NotImplemented``
+* ``__lt__``: :data:`NotImplemented`
+* ``__gt__``: :data:`!NotImplemented`
+* ``__le__``: :data:`!NotImplemented`
+* ``__ge__``: :data:`!NotImplemented`
* ``__int__``: ``1``
* ``__contains__``: ``False``
* ``__len__``: ``0``
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index 10c72dcae3735b..5a1777e7b92f3e 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -159,7 +159,7 @@ NotImplemented
.. index:: pair: object; NotImplemented
This type has a single value. There is a single object with this value. This
-object is accessed through the built-in name ``NotImplemented``. Numeric methods
+object is accessed through the built-in name :data:`NotImplemented`. Numeric methods
and rich comparison methods should return this value if they do not implement the
operation for the operands provided. (The interpreter will then try the
reflected operation, or some other fallback, depending on the operator.) It
@@ -170,7 +170,7 @@ See
for more details.
.. versionchanged:: 3.9
- Evaluating ``NotImplemented`` in a boolean context is deprecated. While
+ Evaluating :data:`NotImplemented` in a boolean context is deprecated. While
it currently evaluates as true, it will emit a :exc:`DeprecationWarning`.
It will raise a :exc:`TypeError` in a future version of Python.
@@ -1763,7 +1763,7 @@ Basic customization
``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and ``x>=y`` calls
``x.__ge__(y)``.
- A rich comparison method may return the singleton ``NotImplemented`` if it does
+ A rich comparison method may return the singleton :data:`NotImplemented` if it does
not implement the operation for a given pair of arguments. By convention,
``False`` and ``True`` are returned for a successful comparison. However, these
methods can return any value, so if the comparison operator is used in a Boolean
@@ -1771,10 +1771,10 @@ Basic customization
:func:`bool` on the value to determine if the result is true or false.
By default, ``object`` implements :meth:`__eq__` by using ``is``, returning
- ``NotImplemented`` in the case of a false comparison:
+ :data:`NotImplemented` in the case of a false comparison:
``True if x is y else NotImplemented``. For :meth:`__ne__`, by default it
delegates to :meth:`__eq__` and inverts the result unless it is
- ``NotImplemented``. There are no other implied relationships among the
+ :data:`!NotImplemented`. There are no other implied relationships among the
comparison operators or default implementations; for example, the truth of
``(x<y or x==y)`` does not imply ``x<=y``. To automatically generate ordering
operations from a single root operation, see :func:`functools.total_ordering`.
@@ -2800,7 +2800,7 @@ through the object's keys; for sequences, it should iterate through the values.
Called to implement :func:`operator.length_hint`. Should return an estimated
length for the object (which may be greater or less than the actual length).
The length must be an integer ``>=`` 0. The return value may also be
- :const:`NotImplemented`, which is treated the same as if the
+ :data:`NotImplemented`, which is treated the same as if the
``__length_hint__`` method didn't exist at all. This method is purely an
optimization and is never required for correctness.
@@ -2952,7 +2952,7 @@ left undefined.
function is to be supported.
If one of those methods does not support the operation with the supplied
- arguments, it should return ``NotImplemented``.
+ arguments, it should return :data:`NotImplemented`.
.. method:: object.__radd__(self, other)
@@ -2982,7 +2982,7 @@ left undefined.
types. [#]_ For instance, to evaluate the expression ``x - y``, where *y* is
an instance of a class that has an :meth:`__rsub__` method,
``type(y).__rsub__(y, x)`` is called if ``type(x).__sub__(x, y)`` returns
- *NotImplemented*.
+ :data:`NotImplemented`.
.. index:: pair: built-in function; pow
@@ -3428,7 +3428,7 @@ An example of an asynchronous context manager class::
the behavior that ``None`` is not callable.
.. [#] "Does not support" here means that the class has no such method, or
- the method returns ``NotImplemented``. Do not set the method to
+ the method returns :data:`NotImplemented`. Do not set the method to
``None`` if you want to force fallback to the right operand's reflected
method—that will instead have the opposite effect of explicitly
*blocking* such fallback.
diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
index 2f346fbde39ecf..ed0b08c1bf6a0f 100644
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -1522,7 +1522,7 @@ built-in types.
``x == x`` are all false, while ``x != x`` is true. This behavior is
compliant with IEEE 754.
-* ``None`` and ``NotImplemented`` are singletons. :PEP:`8` advises that
+* ``None`` and :data:`NotImplemented` are singletons. :PEP:`8` advises that
comparisons for singletons should always be done with ``is`` or ``is not``,
never the equality operators.
diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst
index bfeef935f6eafb..f91ced2c8c8f34 100644
--- a/Doc/whatsnew/2.7.rst
+++ b/Doc/whatsnew/2.7.rst
@@ -1130,7 +1130,7 @@ changes, or look through the Subversion logs for all the details.
(Added by Raymond Hettinger; :issue:`1818`.)
Finally, the :class:`~collections.abc.Mapping` abstract base class now
- returns :const:`NotImplemented` if a mapping is compared to
+ returns :data:`NotImplemented` if a mapping is compared to
another type that isn't a :class:`Mapping`.
(Fixed by Daniel Stutzbach; :issue:`8729`.)
diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst
index 48e4f3c2b45adf..37105469d04424 100644
--- a/Doc/whatsnew/3.10.rst
+++ b/Doc/whatsnew/3.10.rst
@@ -827,7 +827,7 @@ Other Language Changes
:meth:`~object.__index__` method).
(Contributed by Serhiy Storchaka in :issue:`37999`.)
-* If :func:`object.__ipow__` returns :const:`NotImplemented`, the operator will
+* If :func:`object.__ipow__` returns :data:`NotImplemented`, the operator will
correctly fall back to :func:`object.__pow__` and :func:`object.__rpow__` as expected.
(Contributed by Alex Shkop in :issue:`38302`.)
diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst
index 97153c2fddf8bb..676be753440117 100644
--- a/Doc/whatsnew/3.4.rst
+++ b/Doc/whatsnew/3.4.rst
@@ -872,7 +872,7 @@ multiple implementations of an operation that allows it to work with
PEP written and implemented by Łukasz Langa.
:func:`~functools.total_ordering` now supports a return value of
-:const:`NotImplemented` from the underlying comparison function. (Contributed
+:data:`NotImplemented` from the underlying comparison function. (Contributed
by Katie Miller in :issue:`10042`.)
A pure-python version of the :func:`~functools.partial` function is now in the
diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst
index 25abb79fb0b774..bb0703ab6835bf 100644
--- a/Doc/whatsnew/3.9.rst
+++ b/Doc/whatsnew/3.9.rst
@@ -1126,7 +1126,7 @@ Changes in the Python API
``logging.getLogger(__name__)`` in some top-level module called ``'root.py'``.
(Contributed by Vinay Sajip in :issue:`37742`.)
-* Division handling of :class:`~pathlib.PurePath` now returns ``NotImplemented``
+* Division handling of :class:`~pathlib.PurePath` now returns :data:`NotImplemented`
instead of raising a :exc:`TypeError` when passed something other than an
instance of ``str`` or :class:`~pathlib.PurePath`. This allows creating
compatible classes that don't inherit from those mentioned types.
diff --git a/Misc/NEWS.d/3.10.0a6.rst b/Misc/NEWS.d/3.10.0a6.rst
index c379b968c9885b..bad3528084897b 100644
--- a/Misc/NEWS.d/3.10.0a6.rst
+++ b/Misc/NEWS.d/3.10.0a6.rst
@@ -158,7 +158,7 @@ tests that are unrelated to :class:`ProcessPoolExecutor` on those platforms.
.. nonce: hsCNgX
.. section: Core and Builtins
-If :func:`object.__ipow__` returns :const:`NotImplemented`, the operator
+If :func:`object.__ipow__` returns :data:`NotImplemented`, the operator
will correctly fall back to :func:`object.__pow__` and
:func:`object.__rpow__` as expected.
diff --git a/Misc/NEWS.d/3.11.0a1.rst b/Misc/NEWS.d/3.11.0a1.rst
index 8c2535939ff688..ba4fa6497df15e 100644
--- a/Misc/NEWS.d/3.11.0a1.rst
+++ b/Misc/NEWS.d/3.11.0a1.rst
@@ -660,7 +660,7 @@ Karabas.
.. section: Core and Builtins
Parameter substitution of the union type with wrong types now raises
-``TypeError`` instead of returning ``NotImplemented``.
+``TypeError`` instead of returning :data:`NotImplemented`.
..
1
0
[3.12] Docs: mark up NotImplemented using the :data: role throughout the docs (GH-116135) (#116147)
by erlend-aasland Feb. 29, 2024
by erlend-aasland Feb. 29, 2024
Feb. 29, 2024
https://github.com/python/cpython/commit/240e5f613b40e8c24fddbec23351ca45d1…
commit: 240e5f613b40e8c24fddbec23351ca45d1fda8bf
branch: 3.12
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: erlend-aasland <erlend.aasland(a)protonmail.com>
date: 2024-02-29T20:53:51Z
summary:
[3.12] Docs: mark up NotImplemented using the :data: role throughout the docs (GH-116135) (#116147)
(cherry picked from commit dbe44f150cd161bd327ed662e527a4c93829fb3e)
Co-authored-by: Erlend E. Aasland <erlend(a)python.org>
files:
M Doc/library/abc.rst
M Doc/library/constants.rst
M Doc/library/exceptions.rst
M Doc/library/importlib.rst
M Doc/library/numbers.rst
M Doc/library/pickle.rst
M Doc/library/stdtypes.rst
M Doc/library/unittest.mock.rst
M Doc/reference/datamodel.rst
M Doc/reference/expressions.rst
M Doc/whatsnew/2.7.rst
M Doc/whatsnew/3.10.rst
M Doc/whatsnew/3.4.rst
M Doc/whatsnew/3.9.rst
M Misc/NEWS.d/3.10.0a6.rst
M Misc/NEWS.d/3.11.0a1.rst
diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst
index c073ea955abaa4..10e2cba50e49b0 100644
--- a/Doc/library/abc.rst
+++ b/Doc/library/abc.rst
@@ -101,11 +101,11 @@ a helper class :class:`ABC` to alternatively define ABCs through inheritance:
subclass of the ABC. (This class method is called from the
:meth:`~class.__subclasscheck__` method of the ABC.)
- This method should return ``True``, ``False`` or ``NotImplemented``. If
+ This method should return ``True``, ``False`` or :data:`NotImplemented`. If
it returns ``True``, the *subclass* is considered a subclass of this ABC.
If it returns ``False``, the *subclass* is not considered a subclass of
this ABC, even if it would normally be one. If it returns
- ``NotImplemented``, the subclass check is continued with the usual
+ :data:`!NotImplemented`, the subclass check is continued with the usual
mechanism.
.. XXX explain the "usual mechanism"
diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst
index 401dc9a320c5e0..93a7244f87de6b 100644
--- a/Doc/library/constants.rst
+++ b/Doc/library/constants.rst
@@ -33,27 +33,27 @@ A small number of constants live in the built-in namespace. They are:
the other type; may be returned by the in-place binary special methods
(e.g. :meth:`~object.__imul__`, :meth:`~object.__iand__`, etc.) for the same purpose.
It should not be evaluated in a boolean context.
- ``NotImplemented`` is the sole instance of the :data:`types.NotImplementedType` type.
+ :data:`!NotImplemented` is the sole instance of the :data:`types.NotImplementedType` type.
.. note::
- When a binary (or in-place) method returns ``NotImplemented`` the
+ When a binary (or in-place) method returns :data:`!NotImplemented` the
interpreter will try the reflected operation on the other type (or some
other fallback, depending on the operator). If all attempts return
- ``NotImplemented``, the interpreter will raise an appropriate exception.
- Incorrectly returning ``NotImplemented`` will result in a misleading
- error message or the ``NotImplemented`` value being returned to Python code.
+ :data:`!NotImplemented`, the interpreter will raise an appropriate exception.
+ Incorrectly returning :data:`!NotImplemented` will result in a misleading
+ error message or the :data:`!NotImplemented` value being returned to Python code.
See :ref:`implementing-the-arithmetic-operations` for examples.
.. note::
- ``NotImplementedError`` and ``NotImplemented`` are not interchangeable,
+ ``NotImplementedError`` and :data:`!NotImplemented` are not interchangeable,
even though they have similar names and purposes.
See :exc:`NotImplementedError` for details on when to use it.
.. versionchanged:: 3.9
- Evaluating ``NotImplemented`` in a boolean context is deprecated. While
+ Evaluating :data:`!NotImplemented` in a boolean context is deprecated. While
it currently evaluates as true, it will emit a :exc:`DeprecationWarning`.
It will raise a :exc:`TypeError` in a future version of Python.
diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst
index eed0ad18b992e4..60600b2436b734 100644
--- a/Doc/library/exceptions.rst
+++ b/Doc/library/exceptions.rst
@@ -335,9 +335,9 @@ The following exceptions are the exceptions that are usually raised.
.. note::
- ``NotImplementedError`` and ``NotImplemented`` are not interchangeable,
+ ``NotImplementedError`` and :data:`NotImplemented` are not interchangeable,
even though they have similar names and purposes. See
- :data:`NotImplemented` for details on when to use it.
+ :data:`!NotImplemented` for details on when to use it.
.. exception:: OSError([arg])
OSError(errno, strerror[, filename[, winerror[, filename2]]])
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index 2402bc5cd3ee2c..d92bb2f8e5cf83 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -265,7 +265,7 @@ ABC hierarchy::
when invalidating the caches of all finders on :data:`sys.meta_path`.
.. versionchanged:: 3.4
- Returns ``None`` when called instead of ``NotImplemented``.
+ Returns ``None`` when called instead of :data:`NotImplemented`.
.. class:: PathEntryFinder
diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst
index 17d1a275f04c9b..306bdd94aaca13 100644
--- a/Doc/library/numbers.rst
+++ b/Doc/library/numbers.rst
@@ -166,7 +166,7 @@ Complex``. I'll consider ``a + b``:
2. If ``A`` falls back to the boilerplate code, and it were to
return a value from :meth:`~object.__add__`, we'd miss the possibility
that ``B`` defines a more intelligent :meth:`~object.__radd__`, so the
- boilerplate should return :const:`NotImplemented` from
+ boilerplate should return :data:`NotImplemented` from
:meth:`!__add__`. (Or ``A`` may not implement :meth:`!__add__` at
all.)
3. Then ``B``'s :meth:`~object.__radd__` gets a chance. If it accepts
diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst
index b8c9787adc42ec..49417ad24dc6fe 100644
--- a/Doc/library/pickle.rst
+++ b/Doc/library/pickle.rst
@@ -373,7 +373,7 @@ The :mod:`pickle` module exports three classes, :class:`Pickler`,
Special reducer that can be defined in :class:`Pickler` subclasses. This
method has priority over any reducer in the :attr:`dispatch_table`. It
should conform to the same interface as a :meth:`~object.__reduce__` method, and
- can optionally return ``NotImplemented`` to fallback on
+ can optionally return :data:`NotImplemented` to fallback on
:attr:`dispatch_table`-registered reducers to pickle ``obj``.
For a detailed example, see :ref:`reducer_override`.
@@ -495,7 +495,7 @@ What can be pickled and unpickled?
The following types can be pickled:
* built-in constants (``None``, ``True``, ``False``, ``Ellipsis``, and
- ``NotImplemented``);
+ :data:`NotImplemented`);
* integers, floating-point numbers, complex numbers;
@@ -897,7 +897,7 @@ functions and classes.
For those cases, it is possible to subclass from the :class:`Pickler` class and
implement a :meth:`~Pickler.reducer_override` method. This method can return an
arbitrary reduction tuple (see :meth:`~object.__reduce__`). It can alternatively return
-``NotImplemented`` to fallback to the traditional behavior.
+:data:`NotImplemented` to fallback to the traditional behavior.
If both the :attr:`~Pickler.dispatch_table` and
:meth:`~Pickler.reducer_override` are defined, then
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index ccc00198b67be4..3b42bb0843adab 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -5447,10 +5447,10 @@ The NotImplemented Object
This object is returned from comparisons and binary operations when they are
asked to operate on types they don't support. See :ref:`comparisons` for more
-information. There is exactly one ``NotImplemented`` object.
-``type(NotImplemented)()`` produces the singleton instance.
+information. There is exactly one :data:`NotImplemented` object.
+:code:`type(NotImplemented)()` produces the singleton instance.
-It is written as ``NotImplemented``.
+It is written as :code:`NotImplemented`.
.. _typesinternal:
diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst
index cb9e7203fc640b..478c4e29136494 100644
--- a/Doc/library/unittest.mock.rst
+++ b/Doc/library/unittest.mock.rst
@@ -2094,10 +2094,10 @@ to change the default.
Methods and their defaults:
-* ``__lt__``: ``NotImplemented``
-* ``__gt__``: ``NotImplemented``
-* ``__le__``: ``NotImplemented``
-* ``__ge__``: ``NotImplemented``
+* ``__lt__``: :data:`NotImplemented`
+* ``__gt__``: :data:`!NotImplemented`
+* ``__le__``: :data:`!NotImplemented`
+* ``__ge__``: :data:`!NotImplemented`
* ``__int__``: ``1``
* ``__contains__``: ``False``
* ``__len__``: ``0``
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index 80dc9349b3dbb6..146743221cc1b5 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -159,7 +159,7 @@ NotImplemented
.. index:: pair: object; NotImplemented
This type has a single value. There is a single object with this value. This
-object is accessed through the built-in name ``NotImplemented``. Numeric methods
+object is accessed through the built-in name :data:`NotImplemented`. Numeric methods
and rich comparison methods should return this value if they do not implement the
operation for the operands provided. (The interpreter will then try the
reflected operation, or some other fallback, depending on the operator.) It
@@ -170,7 +170,7 @@ See
for more details.
.. versionchanged:: 3.9
- Evaluating ``NotImplemented`` in a boolean context is deprecated. While
+ Evaluating :data:`NotImplemented` in a boolean context is deprecated. While
it currently evaluates as true, it will emit a :exc:`DeprecationWarning`.
It will raise a :exc:`TypeError` in a future version of Python.
@@ -1780,7 +1780,7 @@ Basic customization
``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and ``x>=y`` calls
``x.__ge__(y)``.
- A rich comparison method may return the singleton ``NotImplemented`` if it does
+ A rich comparison method may return the singleton :data:`NotImplemented` if it does
not implement the operation for a given pair of arguments. By convention,
``False`` and ``True`` are returned for a successful comparison. However, these
methods can return any value, so if the comparison operator is used in a Boolean
@@ -1788,10 +1788,10 @@ Basic customization
:func:`bool` on the value to determine if the result is true or false.
By default, ``object`` implements :meth:`__eq__` by using ``is``, returning
- ``NotImplemented`` in the case of a false comparison:
+ :data:`NotImplemented` in the case of a false comparison:
``True if x is y else NotImplemented``. For :meth:`__ne__`, by default it
delegates to :meth:`__eq__` and inverts the result unless it is
- ``NotImplemented``. There are no other implied relationships among the
+ :data:`!NotImplemented`. There are no other implied relationships among the
comparison operators or default implementations; for example, the truth of
``(x<y or x==y)`` does not imply ``x<=y``. To automatically generate ordering
operations from a single root operation, see :func:`functools.total_ordering`.
@@ -2821,7 +2821,7 @@ through the object's keys; for sequences, it should iterate through the values.
Called to implement :func:`operator.length_hint`. Should return an estimated
length for the object (which may be greater or less than the actual length).
The length must be an integer ``>=`` 0. The return value may also be
- :const:`NotImplemented`, which is treated the same as if the
+ :data:`NotImplemented`, which is treated the same as if the
``__length_hint__`` method didn't exist at all. This method is purely an
optimization and is never required for correctness.
@@ -2973,7 +2973,7 @@ left undefined.
function is to be supported.
If one of those methods does not support the operation with the supplied
- arguments, it should return ``NotImplemented``.
+ arguments, it should return :data:`NotImplemented`.
.. method:: object.__radd__(self, other)
@@ -3003,7 +3003,7 @@ left undefined.
types. [#]_ For instance, to evaluate the expression ``x - y``, where *y* is
an instance of a class that has an :meth:`__rsub__` method,
``type(y).__rsub__(y, x)`` is called if ``type(x).__sub__(x, y)`` returns
- *NotImplemented*.
+ :data:`NotImplemented`.
.. index:: pair: built-in function; pow
@@ -3495,7 +3495,7 @@ An example of an asynchronous context manager class::
the behavior that ``None`` is not callable.
.. [#] "Does not support" here means that the class has no such method, or
- the method returns ``NotImplemented``. Do not set the method to
+ the method returns :data:`NotImplemented`. Do not set the method to
``None`` if you want to force fallback to the right operand's reflected
method—that will instead have the opposite effect of explicitly
*blocking* such fallback.
diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
index 8f7c014a6a4a9d..38f00ae2aa03c9 100644
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -1532,7 +1532,7 @@ built-in types.
``x == x`` are all false, while ``x != x`` is true. This behavior is
compliant with IEEE 754.
-* ``None`` and ``NotImplemented`` are singletons. :PEP:`8` advises that
+* ``None`` and :data:`NotImplemented` are singletons. :PEP:`8` advises that
comparisons for singletons should always be done with ``is`` or ``is not``,
never the equality operators.
diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst
index d7cd33e1003bae..383dd77da451e2 100644
--- a/Doc/whatsnew/2.7.rst
+++ b/Doc/whatsnew/2.7.rst
@@ -1130,7 +1130,7 @@ changes, or look through the Subversion logs for all the details.
(Added by Raymond Hettinger; :issue:`1818`.)
Finally, the :class:`~collections.abc.Mapping` abstract base class now
- returns :const:`NotImplemented` if a mapping is compared to
+ returns :data:`NotImplemented` if a mapping is compared to
another type that isn't a :class:`Mapping`.
(Fixed by Daniel Stutzbach; :issue:`8729`.)
diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst
index d0a3b1ad2ca31d..aa4ab300304705 100644
--- a/Doc/whatsnew/3.10.rst
+++ b/Doc/whatsnew/3.10.rst
@@ -828,7 +828,7 @@ Other Language Changes
:meth:`~object.__index__` method).
(Contributed by Serhiy Storchaka in :issue:`37999`.)
-* If :func:`object.__ipow__` returns :const:`NotImplemented`, the operator will
+* If :func:`object.__ipow__` returns :data:`NotImplemented`, the operator will
correctly fall back to :func:`object.__pow__` and :func:`object.__rpow__` as expected.
(Contributed by Alex Shkop in :issue:`38302`.)
diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst
index 4fb4f3e5bee2c5..5a629cd78aba11 100644
--- a/Doc/whatsnew/3.4.rst
+++ b/Doc/whatsnew/3.4.rst
@@ -872,7 +872,7 @@ multiple implementations of an operation that allows it to work with
PEP written and implemented by Łukasz Langa.
:func:`~functools.total_ordering` now supports a return value of
-:const:`NotImplemented` from the underlying comparison function. (Contributed
+:data:`NotImplemented` from the underlying comparison function. (Contributed
by Katie Miller in :issue:`10042`.)
A pure-python version of the :func:`~functools.partial` function is now in the
diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst
index c4a868c9a238fc..d3cdd8271cbe7e 100644
--- a/Doc/whatsnew/3.9.rst
+++ b/Doc/whatsnew/3.9.rst
@@ -1126,7 +1126,7 @@ Changes in the Python API
``logging.getLogger(__name__)`` in some top-level module called ``'root.py'``.
(Contributed by Vinay Sajip in :issue:`37742`.)
-* Division handling of :class:`~pathlib.PurePath` now returns ``NotImplemented``
+* Division handling of :class:`~pathlib.PurePath` now returns :data:`NotImplemented`
instead of raising a :exc:`TypeError` when passed something other than an
instance of ``str`` or :class:`~pathlib.PurePath`. This allows creating
compatible classes that don't inherit from those mentioned types.
diff --git a/Misc/NEWS.d/3.10.0a6.rst b/Misc/NEWS.d/3.10.0a6.rst
index c379b968c9885b..bad3528084897b 100644
--- a/Misc/NEWS.d/3.10.0a6.rst
+++ b/Misc/NEWS.d/3.10.0a6.rst
@@ -158,7 +158,7 @@ tests that are unrelated to :class:`ProcessPoolExecutor` on those platforms.
.. nonce: hsCNgX
.. section: Core and Builtins
-If :func:`object.__ipow__` returns :const:`NotImplemented`, the operator
+If :func:`object.__ipow__` returns :data:`NotImplemented`, the operator
will correctly fall back to :func:`object.__pow__` and
:func:`object.__rpow__` as expected.
diff --git a/Misc/NEWS.d/3.11.0a1.rst b/Misc/NEWS.d/3.11.0a1.rst
index 3728086e93d3d7..717d79df487dba 100644
--- a/Misc/NEWS.d/3.11.0a1.rst
+++ b/Misc/NEWS.d/3.11.0a1.rst
@@ -660,7 +660,7 @@ Karabas.
.. section: Core and Builtins
Parameter substitution of the union type with wrong types now raises
-``TypeError`` instead of returning ``NotImplemented``.
+``TypeError`` instead of returning :data:`NotImplemented`.
..
1
0
Docs: mark up NotImplemented using the :data: role throughout the docs (#116135)
by erlend-aasland Feb. 29, 2024
by erlend-aasland Feb. 29, 2024
Feb. 29, 2024
https://github.com/python/cpython/commit/dbe44f150cd161bd327ed662e527a4c938…
commit: dbe44f150cd161bd327ed662e527a4c93829fb3e
branch: main
author: Erlend E. Aasland <erlend(a)python.org>
committer: erlend-aasland <erlend.aasland(a)protonmail.com>
date: 2024-02-29T20:46:12Z
summary:
Docs: mark up NotImplemented using the :data: role throughout the docs (#116135)
files:
M Doc/library/abc.rst
M Doc/library/constants.rst
M Doc/library/exceptions.rst
M Doc/library/importlib.rst
M Doc/library/numbers.rst
M Doc/library/pickle.rst
M Doc/library/stdtypes.rst
M Doc/library/unittest.mock.rst
M Doc/reference/datamodel.rst
M Doc/reference/expressions.rst
M Doc/whatsnew/2.7.rst
M Doc/whatsnew/3.10.rst
M Doc/whatsnew/3.4.rst
M Doc/whatsnew/3.9.rst
M Misc/NEWS.d/3.10.0a6.rst
M Misc/NEWS.d/3.11.0a1.rst
diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst
index c073ea955abaa4..10e2cba50e49b0 100644
--- a/Doc/library/abc.rst
+++ b/Doc/library/abc.rst
@@ -101,11 +101,11 @@ a helper class :class:`ABC` to alternatively define ABCs through inheritance:
subclass of the ABC. (This class method is called from the
:meth:`~class.__subclasscheck__` method of the ABC.)
- This method should return ``True``, ``False`` or ``NotImplemented``. If
+ This method should return ``True``, ``False`` or :data:`NotImplemented`. If
it returns ``True``, the *subclass* is considered a subclass of this ABC.
If it returns ``False``, the *subclass* is not considered a subclass of
this ABC, even if it would normally be one. If it returns
- ``NotImplemented``, the subclass check is continued with the usual
+ :data:`!NotImplemented`, the subclass check is continued with the usual
mechanism.
.. XXX explain the "usual mechanism"
diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst
index 401dc9a320c5e0..93a7244f87de6b 100644
--- a/Doc/library/constants.rst
+++ b/Doc/library/constants.rst
@@ -33,27 +33,27 @@ A small number of constants live in the built-in namespace. They are:
the other type; may be returned by the in-place binary special methods
(e.g. :meth:`~object.__imul__`, :meth:`~object.__iand__`, etc.) for the same purpose.
It should not be evaluated in a boolean context.
- ``NotImplemented`` is the sole instance of the :data:`types.NotImplementedType` type.
+ :data:`!NotImplemented` is the sole instance of the :data:`types.NotImplementedType` type.
.. note::
- When a binary (or in-place) method returns ``NotImplemented`` the
+ When a binary (or in-place) method returns :data:`!NotImplemented` the
interpreter will try the reflected operation on the other type (or some
other fallback, depending on the operator). If all attempts return
- ``NotImplemented``, the interpreter will raise an appropriate exception.
- Incorrectly returning ``NotImplemented`` will result in a misleading
- error message or the ``NotImplemented`` value being returned to Python code.
+ :data:`!NotImplemented`, the interpreter will raise an appropriate exception.
+ Incorrectly returning :data:`!NotImplemented` will result in a misleading
+ error message or the :data:`!NotImplemented` value being returned to Python code.
See :ref:`implementing-the-arithmetic-operations` for examples.
.. note::
- ``NotImplementedError`` and ``NotImplemented`` are not interchangeable,
+ ``NotImplementedError`` and :data:`!NotImplemented` are not interchangeable,
even though they have similar names and purposes.
See :exc:`NotImplementedError` for details on when to use it.
.. versionchanged:: 3.9
- Evaluating ``NotImplemented`` in a boolean context is deprecated. While
+ Evaluating :data:`!NotImplemented` in a boolean context is deprecated. While
it currently evaluates as true, it will emit a :exc:`DeprecationWarning`.
It will raise a :exc:`TypeError` in a future version of Python.
diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst
index 88417b40e4aa7f..7879fb015bddfa 100644
--- a/Doc/library/exceptions.rst
+++ b/Doc/library/exceptions.rst
@@ -335,9 +335,9 @@ The following exceptions are the exceptions that are usually raised.
.. note::
- ``NotImplementedError`` and ``NotImplemented`` are not interchangeable,
+ ``NotImplementedError`` and :data:`NotImplemented` are not interchangeable,
even though they have similar names and purposes. See
- :data:`NotImplemented` for details on when to use it.
+ :data:`!NotImplemented` for details on when to use it.
.. exception:: OSError([arg])
OSError(errno, strerror[, filename[, winerror[, filename2]]])
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index 2402bc5cd3ee2c..d92bb2f8e5cf83 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -265,7 +265,7 @@ ABC hierarchy::
when invalidating the caches of all finders on :data:`sys.meta_path`.
.. versionchanged:: 3.4
- Returns ``None`` when called instead of ``NotImplemented``.
+ Returns ``None`` when called instead of :data:`NotImplemented`.
.. class:: PathEntryFinder
diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst
index 17d1a275f04c9b..306bdd94aaca13 100644
--- a/Doc/library/numbers.rst
+++ b/Doc/library/numbers.rst
@@ -166,7 +166,7 @@ Complex``. I'll consider ``a + b``:
2. If ``A`` falls back to the boilerplate code, and it were to
return a value from :meth:`~object.__add__`, we'd miss the possibility
that ``B`` defines a more intelligent :meth:`~object.__radd__`, so the
- boilerplate should return :const:`NotImplemented` from
+ boilerplate should return :data:`NotImplemented` from
:meth:`!__add__`. (Or ``A`` may not implement :meth:`!__add__` at
all.)
3. Then ``B``'s :meth:`~object.__radd__` gets a chance. If it accepts
diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst
index cb517681fa81b9..223c27237e4d34 100644
--- a/Doc/library/pickle.rst
+++ b/Doc/library/pickle.rst
@@ -377,7 +377,7 @@ The :mod:`pickle` module exports three classes, :class:`Pickler`,
Special reducer that can be defined in :class:`Pickler` subclasses. This
method has priority over any reducer in the :attr:`dispatch_table`. It
should conform to the same interface as a :meth:`~object.__reduce__` method, and
- can optionally return ``NotImplemented`` to fallback on
+ can optionally return :data:`NotImplemented` to fallback on
:attr:`dispatch_table`-registered reducers to pickle ``obj``.
For a detailed example, see :ref:`reducer_override`.
@@ -503,7 +503,7 @@ What can be pickled and unpickled?
The following types can be pickled:
* built-in constants (``None``, ``True``, ``False``, ``Ellipsis``, and
- ``NotImplemented``);
+ :data:`NotImplemented`);
* integers, floating-point numbers, complex numbers;
@@ -905,7 +905,7 @@ functions and classes.
For those cases, it is possible to subclass from the :class:`Pickler` class and
implement a :meth:`~Pickler.reducer_override` method. This method can return an
arbitrary reduction tuple (see :meth:`~object.__reduce__`). It can alternatively return
-``NotImplemented`` to fallback to the traditional behavior.
+:data:`NotImplemented` to fallback to the traditional behavior.
If both the :attr:`~Pickler.dispatch_table` and
:meth:`~Pickler.reducer_override` are defined, then
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 1a4c12590c1018..c81626a194e640 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -5450,10 +5450,10 @@ The NotImplemented Object
This object is returned from comparisons and binary operations when they are
asked to operate on types they don't support. See :ref:`comparisons` for more
-information. There is exactly one ``NotImplemented`` object.
-``type(NotImplemented)()`` produces the singleton instance.
+information. There is exactly one :data:`NotImplemented` object.
+:code:`type(NotImplemented)()` produces the singleton instance.
-It is written as ``NotImplemented``.
+It is written as :code:`NotImplemented`.
.. _typesinternal:
diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst
index b0a5d96c38d375..1f25a16f544da8 100644
--- a/Doc/library/unittest.mock.rst
+++ b/Doc/library/unittest.mock.rst
@@ -2143,10 +2143,10 @@ to change the default.
Methods and their defaults:
-* ``__lt__``: ``NotImplemented``
-* ``__gt__``: ``NotImplemented``
-* ``__le__``: ``NotImplemented``
-* ``__ge__``: ``NotImplemented``
+* ``__lt__``: :data:`NotImplemented`
+* ``__gt__``: :data:`!NotImplemented`
+* ``__le__``: :data:`!NotImplemented`
+* ``__ge__``: :data:`!NotImplemented`
* ``__int__``: ``1``
* ``__contains__``: ``False``
* ``__len__``: ``0``
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index 6438abbba10e37..1aef2668e82cd1 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -159,7 +159,7 @@ NotImplemented
.. index:: pair: object; NotImplemented
This type has a single value. There is a single object with this value. This
-object is accessed through the built-in name ``NotImplemented``. Numeric methods
+object is accessed through the built-in name :data:`NotImplemented`. Numeric methods
and rich comparison methods should return this value if they do not implement the
operation for the operands provided. (The interpreter will then try the
reflected operation, or some other fallback, depending on the operator.) It
@@ -170,7 +170,7 @@ See
for more details.
.. versionchanged:: 3.9
- Evaluating ``NotImplemented`` in a boolean context is deprecated. While
+ Evaluating :data:`NotImplemented` in a boolean context is deprecated. While
it currently evaluates as true, it will emit a :exc:`DeprecationWarning`.
It will raise a :exc:`TypeError` in a future version of Python.
@@ -1787,7 +1787,7 @@ Basic customization
``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and ``x>=y`` calls
``x.__ge__(y)``.
- A rich comparison method may return the singleton ``NotImplemented`` if it does
+ A rich comparison method may return the singleton :data:`NotImplemented` if it does
not implement the operation for a given pair of arguments. By convention,
``False`` and ``True`` are returned for a successful comparison. However, these
methods can return any value, so if the comparison operator is used in a Boolean
@@ -1795,10 +1795,10 @@ Basic customization
:func:`bool` on the value to determine if the result is true or false.
By default, ``object`` implements :meth:`__eq__` by using ``is``, returning
- ``NotImplemented`` in the case of a false comparison:
+ :data:`NotImplemented` in the case of a false comparison:
``True if x is y else NotImplemented``. For :meth:`__ne__`, by default it
delegates to :meth:`__eq__` and inverts the result unless it is
- ``NotImplemented``. There are no other implied relationships among the
+ :data:`!NotImplemented`. There are no other implied relationships among the
comparison operators or default implementations; for example, the truth of
``(x<y or x==y)`` does not imply ``x<=y``. To automatically generate ordering
operations from a single root operation, see :func:`functools.total_ordering`.
@@ -2828,7 +2828,7 @@ through the object's keys; for sequences, it should iterate through the values.
Called to implement :func:`operator.length_hint`. Should return an estimated
length for the object (which may be greater or less than the actual length).
The length must be an integer ``>=`` 0. The return value may also be
- :const:`NotImplemented`, which is treated the same as if the
+ :data:`NotImplemented`, which is treated the same as if the
``__length_hint__`` method didn't exist at all. This method is purely an
optimization and is never required for correctness.
@@ -2980,7 +2980,7 @@ left undefined.
function is to be supported.
If one of those methods does not support the operation with the supplied
- arguments, it should return ``NotImplemented``.
+ arguments, it should return :data:`NotImplemented`.
.. method:: object.__radd__(self, other)
@@ -3010,7 +3010,7 @@ left undefined.
types. [#]_ For instance, to evaluate the expression ``x - y``, where *y* is
an instance of a class that has an :meth:`__rsub__` method,
``type(y).__rsub__(y, x)`` is called if ``type(x).__sub__(x, y)`` returns
- *NotImplemented*.
+ :data:`NotImplemented`.
.. index:: pair: built-in function; pow
@@ -3503,7 +3503,7 @@ An example of an asynchronous context manager class::
the behavior that ``None`` is not callable.
.. [#] "Does not support" here means that the class has no such method, or
- the method returns ``NotImplemented``. Do not set the method to
+ the method returns :data:`NotImplemented`. Do not set the method to
``None`` if you want to force fallback to the right operand's reflected
method—that will instead have the opposite effect of explicitly
*blocking* such fallback.
diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
index 50e0f97a6534af..00b57effd3e1c0 100644
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -1539,7 +1539,7 @@ built-in types.
``x == x`` are all false, while ``x != x`` is true. This behavior is
compliant with IEEE 754.
-* ``None`` and ``NotImplemented`` are singletons. :PEP:`8` advises that
+* ``None`` and :data:`NotImplemented` are singletons. :PEP:`8` advises that
comparisons for singletons should always be done with ``is`` or ``is not``,
never the equality operators.
diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst
index 2a42664c02852c..5c99fbc503ba65 100644
--- a/Doc/whatsnew/2.7.rst
+++ b/Doc/whatsnew/2.7.rst
@@ -1130,7 +1130,7 @@ changes, or look through the Subversion logs for all the details.
(Added by Raymond Hettinger; :issue:`1818`.)
Finally, the :class:`~collections.abc.Mapping` abstract base class now
- returns :const:`NotImplemented` if a mapping is compared to
+ returns :data:`NotImplemented` if a mapping is compared to
another type that isn't a :class:`Mapping`.
(Fixed by Daniel Stutzbach; :issue:`8729`.)
diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst
index 9770b12c8af711..e35179a2d8e513 100644
--- a/Doc/whatsnew/3.10.rst
+++ b/Doc/whatsnew/3.10.rst
@@ -828,7 +828,7 @@ Other Language Changes
:meth:`~object.__index__` method).
(Contributed by Serhiy Storchaka in :issue:`37999`.)
-* If :func:`object.__ipow__` returns :const:`NotImplemented`, the operator will
+* If :func:`object.__ipow__` returns :data:`NotImplemented`, the operator will
correctly fall back to :func:`object.__pow__` and :func:`object.__rpow__` as expected.
(Contributed by Alex Shkop in :issue:`38302`.)
diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst
index e07eda985d9bad..3dd400c3771ed2 100644
--- a/Doc/whatsnew/3.4.rst
+++ b/Doc/whatsnew/3.4.rst
@@ -872,7 +872,7 @@ multiple implementations of an operation that allows it to work with
PEP written and implemented by Łukasz Langa.
:func:`~functools.total_ordering` now supports a return value of
-:const:`NotImplemented` from the underlying comparison function. (Contributed
+:data:`NotImplemented` from the underlying comparison function. (Contributed
by Katie Miller in :issue:`10042`.)
A pure-python version of the :func:`~functools.partial` function is now in the
diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst
index b24c13813be220..49d926b0edcd0f 100644
--- a/Doc/whatsnew/3.9.rst
+++ b/Doc/whatsnew/3.9.rst
@@ -1126,7 +1126,7 @@ Changes in the Python API
``logging.getLogger(__name__)`` in some top-level module called ``'root.py'``.
(Contributed by Vinay Sajip in :issue:`37742`.)
-* Division handling of :class:`~pathlib.PurePath` now returns ``NotImplemented``
+* Division handling of :class:`~pathlib.PurePath` now returns :data:`NotImplemented`
instead of raising a :exc:`TypeError` when passed something other than an
instance of ``str`` or :class:`~pathlib.PurePath`. This allows creating
compatible classes that don't inherit from those mentioned types.
diff --git a/Misc/NEWS.d/3.10.0a6.rst b/Misc/NEWS.d/3.10.0a6.rst
index c379b968c9885b..bad3528084897b 100644
--- a/Misc/NEWS.d/3.10.0a6.rst
+++ b/Misc/NEWS.d/3.10.0a6.rst
@@ -158,7 +158,7 @@ tests that are unrelated to :class:`ProcessPoolExecutor` on those platforms.
.. nonce: hsCNgX
.. section: Core and Builtins
-If :func:`object.__ipow__` returns :const:`NotImplemented`, the operator
+If :func:`object.__ipow__` returns :data:`NotImplemented`, the operator
will correctly fall back to :func:`object.__pow__` and
:func:`object.__rpow__` as expected.
diff --git a/Misc/NEWS.d/3.11.0a1.rst b/Misc/NEWS.d/3.11.0a1.rst
index e8d4a02a11e0f9..754e782dfe661b 100644
--- a/Misc/NEWS.d/3.11.0a1.rst
+++ b/Misc/NEWS.d/3.11.0a1.rst
@@ -660,7 +660,7 @@ Karabas.
.. section: Core and Builtins
Parameter substitution of the union type with wrong types now raises
-``TypeError`` instead of returning ``NotImplemented``.
+``TypeError`` instead of returning :data:`NotImplemented`.
..
1
0