From 2670cb062c9ec31cd6df7be645f929a8398601c7 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 29 Jun 2026 09:02:42 +0300 Subject: [PATCH 1/9] gh-87577: Document that wm_manage does not accept ttk widgets (GH-152532) wm_manage() works only with the classic tkinter Frame, LabelFrame and Toplevel widgets, not their tkinter.ttk counterparts. Co-authored-by: Claude Opus 4.8 --- Doc/library/tkinter.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index c368141126403a..64ef07ede6fbda 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -2699,7 +2699,8 @@ Base and mixin classes Make *widget* a stand-alone top-level window, decorated by the window manager with a title bar and so on. Only :class:`Frame`, :class:`LabelFrame` and :class:`Toplevel` widgets - may be used; passing any other widget type raises an error. + may be used (the :mod:`tkinter.ttk` versions are **not** accepted); + passing any other widget type raises an error. :meth:`wm_manage` is an alias of :meth:`!manage`. .. versionadded:: 3.3 From 8ae1a236fd334a590e90028f615cd4a822ae6f97 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" <68491+gpshead@users.noreply.github.com> Date: Mon, 29 Jun 2026 01:11:14 -0700 Subject: [PATCH 2/9] gh-110357: hashlib no longer logs at import when a guaranteed hash is unavailable (GH-152538) When a normally-guaranteed hash algorithm cannot be constructed at import time (e.g. an OpenSSL FIPS configuration excludes it from the default provider, or the build used --without-builtin-hashlib-hashes), importing hashlib emitted an "ERROR:root:hash algorithm ... will not be supported at runtime" message to stderr. For the many programs that never use the missing algorithm this is pure noise. Worse, logging.error() lazily calls logging.basicConfig(), which mutates the root logger's handlers -- a global side effect that the test suite flags as an altered execution environment. Stop logging in that path. Code that actually uses a missing algorithm still gets a clear ValueError from the stub constructor installed in its place. The stray output has shown up incidentally in FIPS / "No Builtin Hashes" buildbot reports for years (e.g. gh-110357, gh-76902) without being the reported subject. --- Doc/library/hashlib.rst | 15 +++++++++------ Lib/hashlib.py | 12 +++++------- ...2026-06-29-01-08-53.gh-issue-110357.QGWdZQ.rst | 6 ++++++ 3 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-06-29-01-08-53.gh-issue-110357.QGWdZQ.rst diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index ed0b0b2735b5c3..5b666c5adac645 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -50,12 +50,15 @@ hash supplied more than 2047 bytes of data at once in its constructor or .. index:: single: OpenSSL; (use in module hashlib) Constructors for hash algorithms that are always present in this module are -:func:`sha1`, :func:`sha224`, :func:`sha256`, :func:`sha384`, :func:`sha512`, -:func:`sha3_224`, :func:`sha3_256`, :func:`sha3_384`, :func:`sha3_512`, -:func:`shake_128`, :func:`shake_256`, :func:`blake2b`, and :func:`blake2s`. -:func:`md5` is normally available as well, though it may be missing or blocked -if you are using a rare "FIPS compliant" build of Python. -These correspond to :data:`algorithms_guaranteed`. +:func:`md5`, :func:`sha1`, :func:`sha224`, :func:`sha256`, :func:`sha384`, +:func:`sha512`, :func:`sha3_224`, :func:`sha3_256`, :func:`sha3_384`, +:func:`sha3_512`, :func:`shake_128`, :func:`shake_256`, :func:`blake2b`, and +:func:`blake2s`. These correspond to :data:`algorithms_guaranteed`. + +Any of these may nonetheless be missing or blocked in unusual environments, +such as a rare "FIPS compliant" build of Python or when OpenSSL's "FIPS mode" +is configured to exclude some algorithms from its default provider. Calling +the constructor of an algorithm that is unavailable raises :exc:`ValueError`. Additional algorithms may also be available if your Python distribution's :mod:`!hashlib` was linked against a build of OpenSSL that provides others. diff --git a/Lib/hashlib.py b/Lib/hashlib.py index 6c73eb9f31f8e4..c1e2d07c4357ff 100644 --- a/Lib/hashlib.py +++ b/Lib/hashlib.py @@ -261,16 +261,15 @@ def file_digest(fileobj, digest, /, *, _bufsize=2**18): return digestobj -__logging = None for __func_name in __always_supported: # try them all, some may not work due to the OpenSSL # version not supporting that algorithm. try: globals()[__func_name] = __get_hash(__func_name) - except ValueError as __exc: - import logging as __logging - __logging.error('hash algorithm %s will not be supported at runtime ' - '[reason: %s]', __func_name, __exc) + except ValueError: + # Don't log here: logging at import time has global side effects and + # would tell the wrong audience; code that uses a missing algorithm + # gets a ValueError from the stub installed below. # The following code can be simplified in Python 3.19 # once "string" is removed from the signature. __code = f'''\ @@ -291,9 +290,8 @@ def {__func_name}(data=__UNSET, *, usedforsecurity=True, string=__UNSET): ''' exec(__code, {"__UNSET": object()}, __locals := {}) globals()[__func_name] = __locals[__func_name] - del __exc, __code, __locals + del __code, __locals # Cleanup locals() del __always_supported, __func_name, __get_hash del __py_new, __hash_new, __get_openssl_constructor -del __logging diff --git a/Misc/NEWS.d/next/Library/2026-06-29-01-08-53.gh-issue-110357.QGWdZQ.rst b/Misc/NEWS.d/next/Library/2026-06-29-01-08-53.gh-issue-110357.QGWdZQ.rst new file mode 100644 index 00000000000000..7c2384ea76fe53 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-29-01-08-53.gh-issue-110357.QGWdZQ.rst @@ -0,0 +1,6 @@ +Importing :mod:`hashlib` no longer logs an error to stderr when a normally +guaranteed hash algorithm is unavailable in the current runtime (for example +under an OpenSSL FIPS configuration or a build using +:option:`--without-builtin-hashlib-hashes <--with-builtin-hashlib-hashes>`). +Code that actually uses the missing algorithm still gets a clear +:exc:`ValueError`. From f6e904e1a666cb1e5664750b1c3d8f89cba3a769 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 29 Jun 2026 11:14:23 +0300 Subject: [PATCH 3/9] gh-85320: Use UTF-8 for IDLE configuration and breakpoint files (GH-152475) They were read and written using the locale encoding, which could corrupt non-ASCII paths and made them non-portable. Co-Authored-By: Claude Opus 4.8 --- Lib/idlelib/News3.txt | 5 +++++ Lib/idlelib/config.py | 9 +++++---- Lib/idlelib/pyshell.py | 8 +++++--- .../IDLE/2026-06-28-06-46-46.gh-issue-85320.Hq2vKn.rst | 4 ++++ 4 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2026-06-28-06-46-46.gh-issue-85320.Hq2vKn.rst diff --git a/Lib/idlelib/News3.txt b/Lib/idlelib/News3.txt index 0f61da8368f211..97becb858fea33 100644 --- a/Lib/idlelib/News3.txt +++ b/Lib/idlelib/News3.txt @@ -4,6 +4,11 @@ Released on 2026-10-01 ========================= +gh-85320: IDLE now reads and writes its configuration files and the +breakpoints file using UTF-8 instead of the locale encoding. +Files with non-ASCII characters and non-UTF-8 encoding may need +to be opened in an editor and resaved with UTF-8 encoding. + gh-143774: Better explain the operation of Format / Format Paragraph. Patch by Terry J. Reedy. diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index 1cabe479450015..82afd6c49269d2 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -73,8 +73,9 @@ def GetOptionList(self, section): def Load(self): "Load the configuration file from disk." - if self.file: - self.read(self.file) + if self.file and os.path.exists(self.file): + with open(self.file, encoding='utf-8', errors='replace') as f: + self.read_file(f) class IdleUserConfParser(IdleConfParser): """ @@ -133,10 +134,10 @@ def Save(self): if fname and fname[0] != '#': if not self.IsEmpty(): try: - cfgFile = open(fname, 'w') + cfgFile = open(fname, 'w', encoding='utf-8') except OSError: os.unlink(fname) - cfgFile = open(fname, 'w') + cfgFile = open(fname, 'w', encoding='utf-8') with cfgFile: self.write(cfgFile) elif os.path.exists(self.file): diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index b80c8e56c92810..b1662491935e4a 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -242,12 +242,13 @@ def store_file_breaks(self): breaks = self.breakpoints filename = self.io.filename try: - with open(self.breakpointPath) as fp: + with open(self.breakpointPath, + encoding='utf-8', errors='replace') as fp: lines = fp.readlines() except OSError: lines = [] try: - with open(self.breakpointPath, "w") as new_file: + with open(self.breakpointPath, "w", encoding='utf-8') as new_file: for line in lines: if not line.startswith(filename + '='): new_file.write(line) @@ -272,7 +273,8 @@ def restore_file_breaks(self): if filename is None: return if os.path.isfile(self.breakpointPath): - with open(self.breakpointPath) as fp: + with open(self.breakpointPath, + encoding='utf-8', errors='replace') as fp: lines = fp.readlines() for line in lines: if line.startswith(filename + '='): diff --git a/Misc/NEWS.d/next/IDLE/2026-06-28-06-46-46.gh-issue-85320.Hq2vKn.rst b/Misc/NEWS.d/next/IDLE/2026-06-28-06-46-46.gh-issue-85320.Hq2vKn.rst new file mode 100644 index 00000000000000..ec34bf8ead9eb9 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2026-06-28-06-46-46.gh-issue-85320.Hq2vKn.rst @@ -0,0 +1,4 @@ +IDLE now reads and writes its configuration files and the breakpoints file +using UTF-8 instead of the locale encoding. This keeps non-ASCII data (such +as non-ASCII paths) from being corrupted and makes the files portable between +environments. From 6d209cbb93d0871ad4a5883637a8f0aebc053f76 Mon Sep 17 00:00:00 2001 From: mdehoon Date: Mon, 29 Jun 2026 17:42:56 +0900 Subject: [PATCH 4/9] gh-140146: Fix for stdin redirection to a pipe with interactive tkinter on Windows (GH-148819) --- Lib/test/test_tkinter/test_tkinter_pipe.py | 55 +++++++++++++++++++ ...-04-21-16-07-11.gh-issue-140146.TAcUHA.rst | 3 + Modules/_tkinter.c | 32 ++++++++--- 3 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 Lib/test/test_tkinter/test_tkinter_pipe.py create mode 100644 Misc/NEWS.d/next/Windows/2026-04-21-16-07-11.gh-issue-140146.TAcUHA.rst diff --git a/Lib/test/test_tkinter/test_tkinter_pipe.py b/Lib/test/test_tkinter/test_tkinter_pipe.py new file mode 100644 index 00000000000000..775d0ff5e19b0c --- /dev/null +++ b/Lib/test/test_tkinter/test_tkinter_pipe.py @@ -0,0 +1,55 @@ +# test_tkinter_pipe.py +import unittest +import subprocess +import sys +from test import support + + +@unittest.skipUnless(support.has_subprocess_support, "test requires subprocess") +class TkinterPipeTest(unittest.TestCase): + + def test_tkinter_pipe_buffered(self): + args = [sys.executable, "-i"] + proc = subprocess.Popen(args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc.stdin.write(b"import tkinter\n") + proc.stdin.write(b"interpreter = tkinter.Tcl()\n") + proc.stdin.write(b"print('hello')\n") + proc.stdin.write(b"print('goodbye')\n") + proc.stdin.write(b"quit()\n") + stdout, stderr = proc.communicate(timeout=support.SHORT_TIMEOUT) + stdout = stdout.decode() + self.assertEqual(stdout.split(), ['hello', 'goodbye']) + + def test_tkinter_pipe_unbuffered(self): + args = [sys.executable, "-i", "-u"] + proc = subprocess.Popen(args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc.stdin.write(b"import tkinter\n") + proc.stdin.write(b"interpreter = tkinter.Tcl()\n") + + proc.stdin.write(b"print('hello')\n") + proc.stdin.flush() + stdout = proc.stdout.readline() + stdout = stdout.decode() + self.assertEqual(stdout.strip(), 'hello') + + proc.stdin.write(b"print('hello again')\n") + proc.stdin.flush() + stdout = proc.stdout.readline() + stdout = stdout.decode() + self.assertEqual(stdout.strip(), 'hello again') + + proc.stdin.write(b"print('goodbye')\n") + proc.stdin.write(b"quit()\n") + stdout, stderr = proc.communicate(timeout=support.SHORT_TIMEOUT) + stdout = stdout.decode() + self.assertEqual(stdout.strip(), 'goodbye') + + +if __name__ == "__main__": + unittest.main() diff --git a/Misc/NEWS.d/next/Windows/2026-04-21-16-07-11.gh-issue-140146.TAcUHA.rst b/Misc/NEWS.d/next/Windows/2026-04-21-16-07-11.gh-issue-140146.TAcUHA.rst new file mode 100644 index 00000000000000..2d3e42c86fd521 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2026-04-21-16-07-11.gh-issue-140146.TAcUHA.rst @@ -0,0 +1,3 @@ +Prevent :mod:`tkinter` from hanging on Windows if stdin is redirected to a pipe in an +interactive session. This is helpful for testing interactive usage of +tkinter from a script, for example as part of the cpython test suite. diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 1f1fe4a91addf4..62a79128d9726c 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3443,10 +3443,10 @@ static PyMethodDef moduleMethods[] = }; #ifdef WAIT_FOR_STDIN +#ifndef MS_WINDOWS static int stdin_ready = 0; -#ifndef MS_WINDOWS static void MyFileProc(void *clientData, int mask) { @@ -3465,22 +3465,40 @@ static PyThreadState *event_tstate = NULL; static int EventHook(void) { -#ifndef MS_WINDOWS +#ifdef MS_WINDOWS + HANDLE hStdin; + DWORD type; +#else int tfile; + stdin_ready = 0; #endif PyEval_RestoreThread(event_tstate); - stdin_ready = 0; errorInCmd = 0; -#ifndef MS_WINDOWS +#ifdef MS_WINDOWS + hStdin = GetStdHandle(STD_INPUT_HANDLE); + type = GetFileType(hStdin); + while (1) { +#else tfile = fileno(stdin); Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, (void *)(Py_intptr_t)tfile); -#endif while (!stdin_ready) { +#endif int result; #ifdef MS_WINDOWS - if (_kbhit()) { - stdin_ready = 1; + if (type == FILE_TYPE_CHAR) { + if (_kbhit()) break; + } + else if (type == FILE_TYPE_PIPE) { + DWORD available; + if (PeekNamedPipe(hStdin, NULL, 0, NULL, &available, NULL)) { + if (available > 0) break; + } + else { + if (GetLastError() == ERROR_BROKEN_PIPE) break; + } + } + else if (type == FILE_TYPE_DISK) { break; } #endif From cdec9acd63c33d9b822700de8f63eb94d86e1c93 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Mon, 29 Jun 2026 11:06:04 +0200 Subject: [PATCH 5/9] gh-152375: Fix undefined behaviour in the `INSTRUMENTED_JUMP` macro (#152376) --- .../2026-06-27-10-05-12.gh-issue-152375.L-ZBk6.rst | 2 ++ Python/ceval_macros.h | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-06-27-10-05-12.gh-issue-152375.L-ZBk6.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-27-10-05-12.gh-issue-152375.L-ZBk6.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-27-10-05-12.gh-issue-152375.L-ZBk6.rst new file mode 100644 index 00000000000000..db6ae3060d8328 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-27-10-05-12.gh-issue-152375.L-ZBk6.rst @@ -0,0 +1,2 @@ +Fix undefined behaviour when a :mod:`sys.monitoring` callback raised an +exception while the program was following a branch or loop. diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index 0de4477426af35..b13884bf8214d4 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -389,14 +389,15 @@ static void dtrace_function_return(_PyInterpreterFrame *); // for an exception handler, displaying the traceback, and so on #define INSTRUMENTED_JUMP(src, dest, event) \ do { \ + _Py_CODEUNIT *_dest = (dest); \ if (tstate->tracing) {\ - next_instr = dest; \ + next_instr = _dest; \ } else { \ _PyFrame_SetStackPointer(frame, stack_pointer); \ - next_instr = _Py_call_instrumentation_jump(this_instr, tstate, event, frame, src, dest); \ + next_instr = _Py_call_instrumentation_jump(this_instr, tstate, event, frame, src, _dest); \ stack_pointer = _PyFrame_GetStackPointer(frame); \ if (next_instr == NULL) { \ - next_instr = (dest)+1; \ + next_instr = _dest + 1; \ JUMP_TO_LABEL(error); \ } \ } \ From 7aae0e58b7c02cefd3e13b0d1b65b4ef5cb2b57e Mon Sep 17 00:00:00 2001 From: Ivy Xu Date: Mon, 29 Jun 2026 17:27:41 +0800 Subject: [PATCH 6/9] gh-148909: Fix broken author attribution URL in 'The Python 2.3 Method Resolution Order' doc (#149092) --- Doc/howto/mro.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/mro.rst b/Doc/howto/mro.rst index 0872bedcd3a2d3..72cc311e30d669 100644 --- a/Doc/howto/mro.rst +++ b/Doc/howto/mro.rst @@ -10,7 +10,7 @@ The Python 2.3 Method Resolution Order The Method Resolution Order discussed here was *introduced* in Python 2.3, but it is still used in later versions -- including Python 3. -By `Michele Simionato `__. +By `Michele Simionato `__. :Abstract: From 1540584d5d0b6483b78256194825e76d2e52ad21 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 29 Jun 2026 12:35:24 +0300 Subject: [PATCH 7/9] gh-71450: Document that Tcl sets the HOME variable on Windows (GH-152568) Also fix the ntpath.expanduser() docstring, which no longer uses $HOME. Co-authored-by: Claude Opus 4.8 --- Doc/library/tkinter.rst | 8 ++++++++ Lib/ntpath.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 64ef07ede6fbda..cf342d74bc433e 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -3394,6 +3394,14 @@ Toplevel widgets profile files is the :envvar:`HOME` environment variable or, if that isn't defined, then :data:`os.curdir`. + .. note:: + + On Windows, creating a Tcl interpreter (by instantiating :class:`Tk` or + calling :func:`Tcl`) sets the :envvar:`HOME` environment variable for + the process, if it is not already set, to ``%HOMEDRIVE%%HOMEPATH%`` (or + :envvar:`USERPROFILE`, or ``c:\``). This is done by Tcl and can affect + other code that reads :envvar:`HOME`. + .. attribute:: tk The Tk application object created by instantiating :class:`Tk`. This diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 811e796f7766e9..b3c23f0abc2d88 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -345,7 +345,7 @@ def _isreservedname(name): def expanduser(path): """Expand ~ and ~user constructs. - If user or $HOME is unknown, do nothing.""" + If user or home directory is unknown, do nothing.""" path = os.fspath(path) if isinstance(path, bytes): seps = b'\\/' From 8458582736b69b1ac05eef65230c4806f92891cd Mon Sep 17 00:00:00 2001 From: yzewei <141103849+yzewei@users.noreply.github.com> Date: Mon, 29 Jun 2026 17:48:05 +0800 Subject: [PATCH 8/9] gh-152240: Fix test_c_stack_unwind on Linux LoongArch builds (#152241) --- .../Build/2026-06-26-16-30-00.gh-issue-152240.loongarch.rst | 2 ++ Modules/_testinternalcapi.c | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 Misc/NEWS.d/next/Build/2026-06-26-16-30-00.gh-issue-152240.loongarch.rst diff --git a/Misc/NEWS.d/next/Build/2026-06-26-16-30-00.gh-issue-152240.loongarch.rst b/Misc/NEWS.d/next/Build/2026-06-26-16-30-00.gh-issue-152240.loongarch.rst new file mode 100644 index 00000000000000..ce9274a5c10837 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-06-26-16-30-00.gh-issue-152240.loongarch.rst @@ -0,0 +1,2 @@ +Fix C stack unwinding tests on Linux LoongArch builds by teaching the manual +frame pointer unwinder to recognize the LoongArch frame layout. diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index e3de9006d5a427..6506bd53b0377a 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -98,6 +98,12 @@ static const uintptr_t min_frame_pointer_addr = 0x1000; // https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#STACK # define FRAME_POINTER_NEXT_OFFSET 0 # define FRAME_POINTER_RETURN_OFFSET 2 +#elif defined(__loongarch__) +// On LoongArch, the frame pointer is the caller's stack pointer. +// The saved frame pointer is stored at fp[-2], and the return +// address is stored at fp[-1]. +# define FRAME_POINTER_NEXT_OFFSET -2 +# define FRAME_POINTER_RETURN_OFFSET -1 #else # define FRAME_POINTER_NEXT_OFFSET 0 # define FRAME_POINTER_RETURN_OFFSET 1 From 8ec36f14a552136d54072e3e5bb595ec1f4f0b5f Mon Sep 17 00:00:00 2001 From: Paper Moon Date: Mon, 29 Jun 2026 17:56:41 +0800 Subject: [PATCH 9/9] gh-152359: Update numbers.rst to reference numeric-hash docs (#152549) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Doc/library/numbers.rst | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst index 57b35017072c97..0ed24b4e6c5225 100644 --- a/Doc/library/numbers.rst +++ b/Doc/library/numbers.rst @@ -90,20 +90,7 @@ Notes for type implementers Implementers should be careful to make equal numbers equal and hash them to the same values. This may be subtle if there are two different -extensions of the real numbers. For example, :class:`fractions.Fraction` -implements :func:`hash` as follows:: - - def __hash__(self): - if self.denominator == 1: - # Get integers right. - return hash(self.numerator) - # Expensive check, but definitely correct. - if self == float(self): - return hash(float(self)) - else: - # Use tuple's hash to avoid a high collision rate on - # simple fractions. - return hash((self.numerator, self.denominator)) +extensions of the real numbers. See also :ref:`numeric-hash`. Adding More Numeric ABCs