Accepting request 1228975 from devel:languages:python:Factory
- Add CVE-2024-12254-unbound-mem-buffering-SelectorSocketTransport.writelines.patch preventing exhaustion of memory (gh#python/cpython#127655, bsc#1234290, CVE-2024-12254). - Update to 3.12.8: - Tools/Demos - gh-126807: Fix extraction warnings in pygettext.py caused by mistaking function definitions for function calls. - Tests - gh-126909: Fix test_os extended attribute tests to work on filesystems with 1 KiB xattr size limit. - gh-125041: Re-enable skipped tests for zlib on the s390x architecture: only skip checks of the compressed bytes, which can be different between zlib’s software implementation and the hardware-accelerated implementation. - gh-124295: Add translation tests to the argparse module. - Security - gh-126623: Upgrade libexpat to 2.6.4 - Library - gh-127303: Publicly expose EXACT_TOKEN_TYPES in token.__all__. - gh-123967: Fix faulthandler for trampoline frames. If the top-most frame is a trampoline frame, skip it. Patch by Victor Stinner. - gh-127182: Fix io.StringIO.__setstate__() crash, when None was passed as the first value. - gh-127217: Fix urllib.request.pathname2url() for paths starting with multiple slashes on Posix. - gh-127035: Fix shutil.which on Windows. Now it looks at direct match if and only if the command ends with a PATHEXT extension or X_OK is not in mode. Support extensionless files if “.” is in PATHEXT. Support PATHEXT extensions that end with a dot. - gh-127078: Fix issue where urllib.request.url2pathname() failed to discard an extra slash before a UNC drive in the URL path on Windows. - gh-126766: Fix issue where urllib.request.url2pathname() failed to discard any ‘localhost’ authority present in the URL. - gh-126997: Fix support of STRING and GLOBAL opcodes with non-ASCII arguments in pickletools. pickletools.dis() now outputs non-ASCII bytes in STRING, BINSTRING and SHORT_BINSTRING arguments as escaped (\xXX). - gh-126618: Fix the representation of itertools.count objects when the count value is sys.maxsize. - gh-85168: Fix issue where urllib.request.url2pathname() and pathname2url() always used UTF-8 when quoting and unquoting file URIs. They now use the filesystem encoding and error handler. - gh-67877: Fix memory leaks when regular expression matching terminates abruptly, either because of a signal or because memory allocation fails. - gh-126789: Fixed the values of sysconfig.get_config_vars(), sysconfig.get_paths(), and their siblings when the site initialization happens after sysconfig has built a cache for sysconfig.get_config_vars(). - gh-126188: Update bundled pip to 24.3.1 - gh-126766: Fix issue where urllib.request.url2pathname() failed to discard two leading slashes introducing an empty authority section. - gh-126727: locale.nl_langinfo(locale.ERA) now returns multiple era description segments separated by semicolons. Previously it only returned the first segment on platforms with Glibc. - gh-126699: Allow collections.abc.AsyncIterator to be a base for Protocols. - gh-104745: Limit starting a patcher (from unittest.mock.patch() or unittest.mock.patch.object()) more than once without stopping it - gh-126595: Fix a crash when instantiating itertools.count with an initial count of sys.maxsize on debug builds. Patch by Bénédikt Tran. - gh-120423: Fix issue where urllib.request.pathname2url() mishandled Windows paths with embedded forward slashes. - gh-126565: Improve performances of zipfile.Path.open() for non-reading modes. - gh-126505: Fix bugs in compiling case-insensitive regular expressions with character classes containing non-BMP characters: upper-case non-BMP character did was ignored and the ASCII flag was ignored when matching a character range whose upper bound is beyond the BMP region. - gh-117378: Fixed the multiprocessing "forkserver" start method forkserver process to correctly inherit the parent’s sys.path during the importing of multiprocessing.set_forkserver_preload() modules in the same manner as sys.path is configured in workers before executing work items. This bug caused some forkserver module preloading to silently fail to preload. This manifested as a performance degration in child processes when the sys.path was required due to additional repeated work in every worker. It could also have a side effect of "" remaining in sys.path during forkserver preload imports instead of the absolute path from os.getcwd() at multiprocessing import time used in the worker sys.path. The sys.path differences between phases in the child process could potentially have caused preload to import incorrect things from the wrong location. We are unaware of that actually having happened in practice. - gh-125679: The multiprocessing.Lock and multiprocessing.RLock repr values no longer say “unknown” on macOS. - gh-126476: Raise calendar.IllegalMonthError (now a subclass of IndexError) for calendar.month() when the input month is not correct. - gh-126489: The Python implementation of pickle no longer calls pickle.Pickler.persistent_id() for the result of persistent_id(). - gh-126303: Fix pickling and copying of os.sched_param objects. - gh-126138: Fix a use-after-free crash on asyncio.Task objects whose underlying coroutine yields an object that implements an evil __getattribute__(). Patch by Nico Posada. - gh-126220: Fix crash in cProfile.Profile and _lsprof.Profiler when their callbacks were directly called with 0 arguments. - gh-126212: Fix issue where urllib.request.pathname2url() and url2pathname() removed slashes from Windows DOS drive paths and URLs. - gh-126205: Fix issue where urllib.request.pathname2url() generated URLs beginning with four slashes (rather than two) when given a Windows UNC path. - gh-126105: Fix a crash in ast when the ast.AST._fields attribute is deleted. - gh-126106: Fixes a possible NULL pointer dereference in ssl. - gh-126080: Fix a use-after-free crash on asyncio.Task objects for which the underlying event loop implements an evil __getattribute__(). Reported by Nico-Posada. Patch by Bénédikt Tran. - gh-126083: Fixed a reference leak in asyncio.Task objects when reinitializing the same object with a non-None context. Patch by Nico Posada. - gh-125984: Fix use-after-free crashes on asyncio.Future objects for which the underlying event loop implements an evil __getattribute__(). Reported by Nico-Posada. Patch by Bénédikt Tran. - gh-125969: Fix an out-of-bounds crash when an evil asyncio.loop.call_soon() mutates the length of the internal callbacks list. Patch by Bénédikt Tran. - gh-125966: Fix a use-after-free crash in asyncio.Future.remove_done_callback(). Patch by Bénédikt Tran. - gh-125789: Fix possible crash when mutating list of callbacks returned by asyncio.Future._callbacks. It now always returns a new copy in C implementation _asyncio. Patch by Kumar Aditya. - gh-124452: Fix an issue in email.policy.EmailPolicy.header_source_parse() and email.policy.Compat32.header_source_parse() that introduced spurious leading whitespaces into header values when the header includes a newline character after the header name delimiter (:) and before the value. - gh-125884: Fixed the bug for pdb where it can’t set breakpoints on functions with certain annotations. - gh-125355: Fix several bugs in argparse.ArgumentParser.parse_intermixed_args(). The parser no longer changes temporarily during parsing. Default values are not processed twice. Required mutually exclusive groups containing positional arguments are now supported. The missing arguments report now includes the names of all required optional and positional arguments. Unknown options can be intermixed with positional arguments in parse_known_intermixed_args(). - gh-125682: Reject non-ASCII digits in the Python implementation of json.loads() conforming to the JSON specification. - gh-125660: Reject invalid unicode escapes for Python implementation of json.loads(). - gh-125259: Fix the notes removal logic for errors thrown in enum initialization. - gh-125519: Improve traceback if importlib.reload() is called with an object that is not a module. Patch by Alex Waygood. - gh-125451: Fix deadlock when concurrent.futures.ProcessPoolExecutor shuts down concurrently with an error when feeding a job to a worker process. - gh-125422: Fixed the bug where pdb and bdb can step into the bottom caller frame. - gh-100141: Fixed the bug where pdb will be stuck in an infinite loop when debugging an empty file. - gh-53203: Fix time.strptime() for %c, %x and %X formats in many locales that use non-ASCII digits, like Persian, Burmese, Odia and Shan. - gh-125254: Fix a bug where ArgumentError includes the incorrect ambiguous option in argparse. - gh-61011: Fix inheritance of nested mutually exclusive groups from parent parser in argparse.ArgumentParser. Previously, all nested mutually exclusive groups lost their connection to the group containing them and were displayed as belonging directly to the parser. - gh-52551: Fix encoding issues in time.strftime(), the strftime() method of the datetime classes datetime, date and time and formatting of these classes. Characters not encodable in the current locale are now acceptable in the format string. Surrogate pairs and sequence of surrogatescape-encoded bytes are no longer recombinated. Embedded null character no longer terminates the format string. - gh-125118: Don’t copy arbitrary values to _Bool in the struct module. - gh-125069: Fix an issue where providing a pathlib.PurePath object as an initializer argument to a second PurePath object with a different flavour resulted in arguments to the former object’s initializer being joined by the latter object’s flavour. - gh-124969: Fix locale.nl_langinfo(locale.ALT_DIGITS) on platforms with glibc. Now it returns a string consisting of up to 100 semicolon-separated symbols (an empty string in most locales) on all Posix platforms. Previously it only returned the first symbol or an empty string. - gh-124958: Fix refcycles in exceptions raised from asyncio.TaskGroup and the python implementation of asyncio.Future - gh-53203: Fix time.strptime() for %c and %x formats in many locales: Arabic, Bislama, Breton, Bodo, Kashubian, Chuvash, Estonian, French, Irish, Ge’ez, Gurajati, Manx Gaelic, Hebrew, Hindi, Chhattisgarhi, Haitian Kreyol, Japanese, Kannada, Korean, Marathi, Malay, Norwegian, Nynorsk, Punjabi, Rajasthani, Tok Pisin, Yoruba, Yue Chinese, Yau/Nungon and Chinese. - gh-124917: Allow calling os.path.exists() and os.path.lexists() with keyword arguments on Windows. Fixes a regression in 3.12.4. - gh-124653: Fix detection of the minimal Queue API needed by the logging module. Patch by Bénédikt Tran. - gh-124858: Fix reference cycles left in tracebacks in asyncio.open_connection() when used with happy_eyeballs_delay - gh-124390: Fixed AssertionError when using asyncio.staggered.staggered_race() with asyncio.eager_task_factory. - gh-124651: Properly quote template strings in venv activation scripts. - gh-124594: All asyncio REPL prompts run in the same context. Contributed by Bartosz Sławecki. - gh-120378: Fix a crash related to an integer overflow in curses.resizeterm() and curses.resize_term(). - gh-123884: Fixed bug in itertools.tee() handling of other tee inputs (a tee in a tee). The output now has the promised n independent new iterators. Formerly, the first iterator was identical (not independent) to the input iterator. This would sometimes give surprising results. - gh-123978: Remove broken time.thread_time() and time.thread_time_ns() on NetBSD. - gh-124008: Fix possible crash (in debug build), incorrect output or returning incorrect value from raw binary write() when writing to console on Windows. - gh-123370: Fix the canvas not clearing after running turtledemo clock. - gh-120754: Update unbounded read calls in zipfile to specify an explicit size putting a limit on how much data they may read. This also updates handling around ZIP max comment size to match the standard instead of reading comments that are one byte too long. - gh-70764: Fixed an issue where inspect.getclosurevars() would incorrectly classify an attribute name as a global variable when the name exists both as an attribute name and a global variable. - gh-119826: Always return an absolute path for os.path.abspath() on Windows. - gh-117766: Always use str() to print choices in argparse. - gh-101955: Fix SystemError when match regular expression pattern containing some combination of possessive quantifier, alternative and capture group. - gh-88110: Fixed multiprocessing.Process reporting a .exitcode of 1 even on success when using the "fork" start method while using a concurrent.futures.ThreadPoolExecutor. - gh-71936: Fix a race condition in multiprocessing.pool.Pool. - bpo-46128: Strip unittest.IsolatedAsyncioTestCase stack frames from reported stacktraces. - bpo-14074: Fix argparse metavar processing to allow positional arguments to have a tuple metavar. - IDLE - gh-122392: Increase currently inadequate vertical spacing for the IDLE browsers (path, module, and stack) on high-resolution monitors. - Documentation - gh-125277: Require Sphinx 7.2.6 or later to build the Python documentation. Patch by Adam Turner. - gh-125018: The importlib.metadata documentation now includes semantic cross-reference targets for the significant documented APIs. This means intersphinx references like importlib.metadata.version() will now work as expected. - gh-121277: Writers of CPython’s documentation can now use next as the version for the versionchanged, versionadded, deprecated directives. - gh-60712: Include the object type in the lists of documented types. Change by Furkan Onder and Martin Panter. - Core and Builtins - gh-113841: Fix possible undefined behavior division by zero in complex’s _Py_c_pow(). - gh-126341: Now ValueError is raised instead of SystemError when trying to iterate over a released memoryview object. - gh-126066: Fix importlib to not write an incomplete .pyc files when a ulimit or some other operating system mechanism is preventing the write to go through fully. - gh-126139: Provide better error location when attempting to use a future statement with an unknown future feature. - gh-125008: Fix tokenize.untokenize() producing invalid syntax for double braces preceded by certain escape characters. - gh-123378: Fix a crash in the __str__() method of UnicodeError objects when the UnicodeError.start and UnicodeError.end values are invalid or out-of-range. Patch by Bénédikt Tran. - gh-116510: Fix a crash caused by immortal interned strings being shared between sub-interpreters that use basic single-phase init. In that case, the string can be used by an interpreter that outlives the interpreter that created and interned it. For interpreters that share obmalloc state, also share the interned dict with the main interpreter. - gh-118950: Fix bug where SSLProtocol.connection_lost wasn’t getting called when OSError was thrown on writing to socket. - gh-113570: Fixed a bug in reprlib.repr where it incorrectly called the repr method on shadowed Python built-in types. - gh-109746: If _thread.start_new_thread() fails to start a new thread, it deletes its state from interpreter and thus avoids its repeated cleanup on finalization. - C API - gh-113601: Removed debug build assertions related to interning strings, which were falsely triggered by stable ABI extensions. - Build - gh-89640: Hard-code float word ordering as little endian on WASM. - gh-89640: Improve detection of float word ordering on Linux when link-time optimizations are enabled. - Remove upstreamed patches: - CVE-2024-9287-venv_path_unquoted.patch OBS-URL: https://build.opensuse.org/request/show/1228975 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python312?expand=0&rev=26
This commit is contained in:
commit
9431cf257f
@ -0,0 +1,46 @@
|
||||
From bfc2e93d755bf496e5ef4cae9609d2823122c909 Mon Sep 17 00:00:00 2001
|
||||
From: "J. Nick Koston" <nick@koston.org>
|
||||
Date: Thu, 5 Dec 2024 10:01:10 -0600
|
||||
Subject: [PATCH 01/10] Ensure writelines pauses the protocol if needed
|
||||
|
||||
---
|
||||
Lib/asyncio/selector_events.py | 1
|
||||
Lib/test/test_asyncio/test_selector_events.py | 12 ++++++++++
|
||||
Misc/NEWS.d/next/Security/2024-12-05-21-35-19.gh-issue-127655.xpPoOf.rst | 1
|
||||
3 files changed, 14 insertions(+)
|
||||
|
||||
--- a/Lib/asyncio/selector_events.py
|
||||
+++ b/Lib/asyncio/selector_events.py
|
||||
@@ -1183,6 +1183,7 @@ class _SelectorSocketTransport(_Selector
|
||||
# If the entire buffer couldn't be written, register a write handler
|
||||
if self._buffer:
|
||||
self._loop._add_writer(self._sock_fd, self._write_ready)
|
||||
+ self._maybe_pause_protocol()
|
||||
|
||||
def can_write_eof(self):
|
||||
return True
|
||||
--- a/Lib/test/test_asyncio/test_selector_events.py
|
||||
+++ b/Lib/test/test_asyncio/test_selector_events.py
|
||||
@@ -805,6 +805,18 @@ class SelectorSocketTransportTests(test_
|
||||
self.assertTrue(self.sock.send.called)
|
||||
self.assertTrue(self.loop.writers)
|
||||
|
||||
+ def test_writelines_pauses_protocol(self):
|
||||
+ data = memoryview(b'data')
|
||||
+ self.sock.send.return_value = 2
|
||||
+ self.sock.send.fileno.return_value = 7
|
||||
+
|
||||
+ transport = self.socket_transport()
|
||||
+ transport._high_water = 1
|
||||
+ transport.writelines([data])
|
||||
+ self.assertTrue(self.protocol.pause_writing.called)
|
||||
+ self.assertTrue(self.sock.send.called)
|
||||
+ self.assertTrue(self.loop.writers)
|
||||
+
|
||||
@unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg')
|
||||
def test_write_sendmsg_full(self):
|
||||
data = memoryview(b'data')
|
||||
--- /dev/null
|
||||
+++ b/Misc/NEWS.d/next/Security/2024-12-05-21-35-19.gh-issue-127655.xpPoOf.rst
|
||||
@@ -0,0 +1 @@
|
||||
+Fixed the :class:`!asyncio.selector_events._SelectorSocketTransport` transport not pausing writes for the protocol when the buffer reaches the high water mark when using :meth:`asyncio.WriteTransport.writelines`.
|
@ -1,303 +0,0 @@
|
||||
From 1408cc9bf9e8b19968761548c30b78d37074c21c Mon Sep 17 00:00:00 2001
|
||||
From: Y5 <124019959+y5c4l3@users.noreply.github.com>
|
||||
Date: Tue, 22 Oct 2024 04:48:04 +0800
|
||||
Subject: [PATCH] gh-124651: Quote template strings in `venv` activation
|
||||
scripts (GH-124712)
|
||||
|
||||
This patch properly quotes template strings in `venv` activation
|
||||
scripts. This mitigates potential command injection.
|
||||
|
||||
(cherry picked from commit d48cc82ed25e26b02eb97c6263d95dcaa1e9111b)
|
||||
---
|
||||
Lib/test/test_venv.py | 81 ++++++++++
|
||||
Lib/venv/__init__.py | 42 ++++-
|
||||
Lib/venv/scripts/common/activate | 10 -
|
||||
Lib/venv/scripts/nt/activate.bat | 6
|
||||
Lib/venv/scripts/posix/activate.csh | 8
|
||||
Lib/venv/scripts/posix/activate.fish | 8
|
||||
Misc/NEWS.d/next/Library/2024-09-28-02-03-04.gh-issue-124651.bLBGtH.rst | 1
|
||||
7 files changed, 135 insertions(+), 21 deletions(-)
|
||||
create mode 100644 Misc/NEWS.d/next/Library/2024-09-28-02-03-04.gh-issue-124651.bLBGtH.rst
|
||||
|
||||
--- a/Lib/test/test_venv.py
|
||||
+++ b/Lib/test/test_venv.py
|
||||
@@ -17,6 +17,7 @@ import subprocess
|
||||
import sys
|
||||
import sysconfig
|
||||
import tempfile
|
||||
+import shlex
|
||||
from test.support import (captured_stdout, captured_stderr,
|
||||
skip_if_broken_multiprocessing_synchronize, verbose,
|
||||
requires_subprocess, is_emscripten, is_wasi,
|
||||
@@ -97,6 +98,10 @@ class BaseTest(unittest.TestCase):
|
||||
result = f.read()
|
||||
return result
|
||||
|
||||
+ def assertEndsWith(self, string, tail):
|
||||
+ if not string.endswith(tail):
|
||||
+ self.fail(f"String {string!r} does not end with {tail!r}")
|
||||
+
|
||||
class BasicTest(BaseTest):
|
||||
"""Test venv module functionality."""
|
||||
|
||||
@@ -446,6 +451,82 @@ class BasicTest(BaseTest):
|
||||
'import sys; print(sys.executable)'])
|
||||
self.assertEqual(out.strip(), envpy.encode())
|
||||
|
||||
+ # gh-124651: test quoted strings
|
||||
+ @unittest.skipIf(os.name == 'nt', 'contains invalid characters on Windows')
|
||||
+ def test_special_chars_bash(self):
|
||||
+ """
|
||||
+ Test that the template strings are quoted properly (bash)
|
||||
+ """
|
||||
+ rmtree(self.env_dir)
|
||||
+ bash = shutil.which('bash')
|
||||
+ if bash is None:
|
||||
+ self.skipTest('bash required for this test')
|
||||
+ env_name = '"\';&&$e|\'"'
|
||||
+ env_dir = os.path.join(os.path.realpath(self.env_dir), env_name)
|
||||
+ builder = venv.EnvBuilder(clear=True)
|
||||
+ builder.create(env_dir)
|
||||
+ activate = os.path.join(env_dir, self.bindir, 'activate')
|
||||
+ test_script = os.path.join(self.env_dir, 'test_special_chars.sh')
|
||||
+ with open(test_script, "w") as f:
|
||||
+ f.write(f'source {shlex.quote(activate)}\n'
|
||||
+ 'python -c \'import sys; print(sys.executable)\'\n'
|
||||
+ 'python -c \'import os; print(os.environ["VIRTUAL_ENV"])\'\n'
|
||||
+ 'deactivate\n')
|
||||
+ out, err = check_output([bash, test_script])
|
||||
+ lines = out.splitlines()
|
||||
+ self.assertTrue(env_name.encode() in lines[0])
|
||||
+ self.assertEndsWith(lines[1], env_name.encode())
|
||||
+
|
||||
+ # gh-124651: test quoted strings
|
||||
+ @unittest.skipIf(os.name == 'nt', 'contains invalid characters on Windows')
|
||||
+ def test_special_chars_csh(self):
|
||||
+ """
|
||||
+ Test that the template strings are quoted properly (csh)
|
||||
+ """
|
||||
+ rmtree(self.env_dir)
|
||||
+ csh = shutil.which('tcsh') or shutil.which('csh')
|
||||
+ if csh is None:
|
||||
+ self.skipTest('csh required for this test')
|
||||
+ env_name = '"\';&&$e|\'"'
|
||||
+ env_dir = os.path.join(os.path.realpath(self.env_dir), env_name)
|
||||
+ builder = venv.EnvBuilder(clear=True)
|
||||
+ builder.create(env_dir)
|
||||
+ activate = os.path.join(env_dir, self.bindir, 'activate.csh')
|
||||
+ test_script = os.path.join(self.env_dir, 'test_special_chars.csh')
|
||||
+ with open(test_script, "w") as f:
|
||||
+ f.write(f'source {shlex.quote(activate)}\n'
|
||||
+ 'python -c \'import sys; print(sys.executable)\'\n'
|
||||
+ 'python -c \'import os; print(os.environ["VIRTUAL_ENV"])\'\n'
|
||||
+ 'deactivate\n')
|
||||
+ out, err = check_output([csh, test_script])
|
||||
+ lines = out.splitlines()
|
||||
+ self.assertTrue(env_name.encode() in lines[0])
|
||||
+ self.assertEndsWith(lines[1], env_name.encode())
|
||||
+
|
||||
+ # gh-124651: test quoted strings on Windows
|
||||
+ @unittest.skipUnless(os.name == 'nt', 'only relevant on Windows')
|
||||
+ def test_special_chars_windows(self):
|
||||
+ """
|
||||
+ Test that the template strings are quoted properly on Windows
|
||||
+ """
|
||||
+ rmtree(self.env_dir)
|
||||
+ env_name = "'&&^$e"
|
||||
+ env_dir = os.path.join(os.path.realpath(self.env_dir), env_name)
|
||||
+ builder = venv.EnvBuilder(clear=True)
|
||||
+ builder.create(env_dir)
|
||||
+ activate = os.path.join(env_dir, self.bindir, 'activate.bat')
|
||||
+ test_batch = os.path.join(self.env_dir, 'test_special_chars.bat')
|
||||
+ with open(test_batch, "w") as f:
|
||||
+ f.write('@echo off\n'
|
||||
+ f'"{activate}" & '
|
||||
+ f'{self.exe} -c "import sys; print(sys.executable)" & '
|
||||
+ f'{self.exe} -c "import os; print(os.environ[\'VIRTUAL_ENV\'])" & '
|
||||
+ 'deactivate')
|
||||
+ out, err = check_output([test_batch])
|
||||
+ lines = out.splitlines()
|
||||
+ self.assertTrue(env_name.encode() in lines[0])
|
||||
+ self.assertEndsWith(lines[1], env_name.encode())
|
||||
+
|
||||
@unittest.skipUnless(os.name == 'nt', 'only relevant on Windows')
|
||||
def test_unicode_in_batch_file(self):
|
||||
"""
|
||||
--- a/Lib/venv/__init__.py
|
||||
+++ b/Lib/venv/__init__.py
|
||||
@@ -11,6 +11,7 @@ import subprocess
|
||||
import sys
|
||||
import sysconfig
|
||||
import types
|
||||
+import shlex
|
||||
|
||||
|
||||
CORE_VENV_DEPS = ('pip',)
|
||||
@@ -422,11 +423,41 @@ class EnvBuilder:
|
||||
:param context: The information for the environment creation request
|
||||
being processed.
|
||||
"""
|
||||
- text = text.replace('__VENV_DIR__', context.env_dir)
|
||||
- text = text.replace('__VENV_NAME__', context.env_name)
|
||||
- text = text.replace('__VENV_PROMPT__', context.prompt)
|
||||
- text = text.replace('__VENV_BIN_NAME__', context.bin_name)
|
||||
- text = text.replace('__VENV_PYTHON__', context.env_exe)
|
||||
+ replacements = {
|
||||
+ '__VENV_DIR__': context.env_dir,
|
||||
+ '__VENV_NAME__': context.env_name,
|
||||
+ '__VENV_PROMPT__': context.prompt,
|
||||
+ '__VENV_BIN_NAME__': context.bin_name,
|
||||
+ '__VENV_PYTHON__': context.env_exe,
|
||||
+ }
|
||||
+
|
||||
+ def quote_ps1(s):
|
||||
+ """
|
||||
+ This should satisfy PowerShell quoting rules [1], unless the quoted
|
||||
+ string is passed directly to Windows native commands [2].
|
||||
+ [1]: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules
|
||||
+ [2]: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing#passing-arguments-that-contain-quote-characters
|
||||
+ """
|
||||
+ s = s.replace("'", "''")
|
||||
+ return f"'{s}'"
|
||||
+
|
||||
+ def quote_bat(s):
|
||||
+ return s
|
||||
+
|
||||
+ # gh-124651: need to quote the template strings properly
|
||||
+ quote = shlex.quote
|
||||
+ script_path = context.script_path
|
||||
+ if script_path.endswith('.ps1'):
|
||||
+ quote = quote_ps1
|
||||
+ elif script_path.endswith('.bat'):
|
||||
+ quote = quote_bat
|
||||
+ else:
|
||||
+ # fallbacks to POSIX shell compliant quote
|
||||
+ quote = shlex.quote
|
||||
+
|
||||
+ replacements = {key: quote(s) for key, s in replacements.items()}
|
||||
+ for key, quoted in replacements.items():
|
||||
+ text = text.replace(key, quoted)
|
||||
return text
|
||||
|
||||
def install_scripts(self, context, path):
|
||||
@@ -466,6 +497,7 @@ class EnvBuilder:
|
||||
with open(srcfile, 'rb') as f:
|
||||
data = f.read()
|
||||
if not srcfile.endswith(('.exe', '.pdb')):
|
||||
+ context.script_path = srcfile
|
||||
try:
|
||||
data = data.decode('utf-8')
|
||||
data = self.replace_variables(data, context)
|
||||
--- a/Lib/venv/scripts/common/activate
|
||||
+++ b/Lib/venv/scripts/common/activate
|
||||
@@ -39,14 +39,14 @@ deactivate nondestructive
|
||||
if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then
|
||||
# transform D:\path\to\venv to /d/path/to/venv on MSYS
|
||||
# and to /cygdrive/d/path/to/venv on Cygwin
|
||||
- export VIRTUAL_ENV=$(cygpath "__VENV_DIR__")
|
||||
+ export VIRTUAL_ENV=$(cygpath __VENV_DIR__)
|
||||
else
|
||||
# use the path as-is
|
||||
- export VIRTUAL_ENV="__VENV_DIR__"
|
||||
+ export VIRTUAL_ENV=__VENV_DIR__
|
||||
fi
|
||||
|
||||
_OLD_VIRTUAL_PATH="$PATH"
|
||||
-PATH="$VIRTUAL_ENV/__VENV_BIN_NAME__:$PATH"
|
||||
+PATH="$VIRTUAL_ENV/"__VENV_BIN_NAME__":$PATH"
|
||||
export PATH
|
||||
|
||||
# unset PYTHONHOME if set
|
||||
@@ -59,9 +59,9 @@ fi
|
||||
|
||||
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
|
||||
_OLD_VIRTUAL_PS1="${PS1:-}"
|
||||
- PS1="__VENV_PROMPT__${PS1:-}"
|
||||
+ PS1=__VENV_PROMPT__"${PS1:-}"
|
||||
export PS1
|
||||
- VIRTUAL_ENV_PROMPT="__VENV_PROMPT__"
|
||||
+ VIRTUAL_ENV_PROMPT=__VENV_PROMPT__
|
||||
export VIRTUAL_ENV_PROMPT
|
||||
fi
|
||||
|
||||
--- a/Lib/venv/scripts/nt/activate.bat
|
||||
+++ b/Lib/venv/scripts/nt/activate.bat
|
||||
@@ -8,7 +8,7 @@ if defined _OLD_CODEPAGE (
|
||||
"%SystemRoot%\System32\chcp.com" 65001 > nul
|
||||
)
|
||||
|
||||
-set VIRTUAL_ENV=__VENV_DIR__
|
||||
+set "VIRTUAL_ENV=__VENV_DIR__"
|
||||
|
||||
if not defined PROMPT set PROMPT=$P$G
|
||||
|
||||
@@ -24,8 +24,8 @@ set PYTHONHOME=
|
||||
if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%
|
||||
if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH%
|
||||
|
||||
-set PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH%
|
||||
-set VIRTUAL_ENV_PROMPT=__VENV_PROMPT__
|
||||
+set "PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH%"
|
||||
+set "VIRTUAL_ENV_PROMPT=__VENV_PROMPT__"
|
||||
|
||||
:END
|
||||
if defined _OLD_CODEPAGE (
|
||||
--- a/Lib/venv/scripts/posix/activate.csh
|
||||
+++ b/Lib/venv/scripts/posix/activate.csh
|
||||
@@ -9,17 +9,17 @@ alias deactivate 'test $?_OLD_VIRTUAL_PA
|
||||
# Unset irrelevant variables.
|
||||
deactivate nondestructive
|
||||
|
||||
-setenv VIRTUAL_ENV "__VENV_DIR__"
|
||||
+setenv VIRTUAL_ENV __VENV_DIR__
|
||||
|
||||
set _OLD_VIRTUAL_PATH="$PATH"
|
||||
-setenv PATH "$VIRTUAL_ENV/__VENV_BIN_NAME__:$PATH"
|
||||
+setenv PATH "$VIRTUAL_ENV/"__VENV_BIN_NAME__":$PATH"
|
||||
|
||||
|
||||
set _OLD_VIRTUAL_PROMPT="$prompt"
|
||||
|
||||
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
|
||||
- set prompt = "__VENV_PROMPT__$prompt"
|
||||
- setenv VIRTUAL_ENV_PROMPT "__VENV_PROMPT__"
|
||||
+ set prompt = __VENV_PROMPT__"$prompt"
|
||||
+ setenv VIRTUAL_ENV_PROMPT __VENV_PROMPT__
|
||||
endif
|
||||
|
||||
alias pydoc python -m pydoc
|
||||
--- a/Lib/venv/scripts/posix/activate.fish
|
||||
+++ b/Lib/venv/scripts/posix/activate.fish
|
||||
@@ -33,10 +33,10 @@ end
|
||||
# Unset irrelevant variables.
|
||||
deactivate nondestructive
|
||||
|
||||
-set -gx VIRTUAL_ENV "__VENV_DIR__"
|
||||
+set -gx VIRTUAL_ENV __VENV_DIR__
|
||||
|
||||
set -gx _OLD_VIRTUAL_PATH $PATH
|
||||
-set -gx PATH "$VIRTUAL_ENV/__VENV_BIN_NAME__" $PATH
|
||||
+set -gx PATH "$VIRTUAL_ENV/"__VENV_BIN_NAME__ $PATH
|
||||
|
||||
# Unset PYTHONHOME if set.
|
||||
if set -q PYTHONHOME
|
||||
@@ -56,7 +56,7 @@ if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
|
||||
set -l old_status $status
|
||||
|
||||
# Output the venv prompt; color taken from the blue of the Python logo.
|
||||
- printf "%s%s%s" (set_color 4B8BBE) "__VENV_PROMPT__" (set_color normal)
|
||||
+ printf "%s%s%s" (set_color 4B8BBE) __VENV_PROMPT__ (set_color normal)
|
||||
|
||||
# Restore the return status of the previous command.
|
||||
echo "exit $old_status" | .
|
||||
@@ -65,5 +65,5 @@ if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
|
||||
end
|
||||
|
||||
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
|
||||
- set -gx VIRTUAL_ENV_PROMPT "__VENV_PROMPT__"
|
||||
+ set -gx VIRTUAL_ENV_PROMPT __VENV_PROMPT__
|
||||
end
|
||||
--- /dev/null
|
||||
+++ b/Misc/NEWS.d/next/Library/2024-09-28-02-03-04.gh-issue-124651.bLBGtH.rst
|
||||
@@ -0,0 +1 @@
|
||||
+Properly quote template strings in :mod:`venv` activation scripts.
|
@ -24,15 +24,12 @@ Co-authored-by: Miro Hrončok <miro@hroncok.cz>
|
||||
Co-authored-by: Michal Cyprian <m.cyprian@gmail.com>
|
||||
Co-authored-by: Lumír Balhar <frenzy.madness@gmail.com>
|
||||
---
|
||||
Lib/site.py | 9 ++++++-
|
||||
Lib/sysconfig.py | 49 +++++++++++++++++++++++++++++++++++++-
|
||||
Lib/test/test_sysconfig.py | 17 +++++++++++--
|
||||
3 files changed, 71 insertions(+), 4 deletions(-)
|
||||
Lib/sysconfig.py | 51 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
Lib/test/test_sysconfig.py | 17 +++++++++++++--
|
||||
2 files changed, 65 insertions(+), 3 deletions(-)
|
||||
|
||||
Index: Python-3.12.4/Lib/sysconfig.py
|
||||
===================================================================
|
||||
--- Python-3.12.4.orig/Lib/sysconfig.py
|
||||
+++ Python-3.12.4/Lib/sysconfig.py
|
||||
--- a/Lib/sysconfig.py
|
||||
+++ b/Lib/sysconfig.py
|
||||
@@ -104,6 +104,11 @@ if os.name == 'nt':
|
||||
else:
|
||||
_INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv']
|
||||
@ -45,7 +42,7 @@ Index: Python-3.12.4/Lib/sysconfig.py
|
||||
|
||||
# NOTE: site.py has copy of this function.
|
||||
# Sync it when modify this function.
|
||||
@@ -163,6 +168,19 @@ if _HAS_USER_BASE:
|
||||
@@ -163,13 +168,28 @@ if _HAS_USER_BASE:
|
||||
},
|
||||
}
|
||||
|
||||
@ -65,7 +62,16 @@ Index: Python-3.12.4/Lib/sysconfig.py
|
||||
_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',
|
||||
'scripts', 'data')
|
||||
|
||||
@@ -263,11 +281,40 @@ def _extend_dict(target_dict, other_dict
|
||||
_PY_VERSION = sys.version.split()[0]
|
||||
_PY_VERSION_SHORT = f'{sys.version_info[0]}.{sys.version_info[1]}'
|
||||
_PY_VERSION_SHORT_NO_DOT = f'{sys.version_info[0]}{sys.version_info[1]}'
|
||||
+_PREFIX = os.path.normpath(sys.prefix)
|
||||
_BASE_PREFIX = os.path.normpath(sys.base_prefix)
|
||||
+_EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
|
||||
_BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
|
||||
# Mutex guarding initialization of _CONFIG_VARS.
|
||||
_CONFIG_VARS_LOCK = threading.RLock()
|
||||
@@ -261,11 +281,40 @@ def _extend_dict(target_dict, other_dict
|
||||
target_dict[key] = value
|
||||
|
||||
|
||||
@ -107,11 +113,9 @@ Index: Python-3.12.4/Lib/sysconfig.py
|
||||
if os.name == 'nt':
|
||||
# On Windows we want to substitute 'lib' for schemes rather
|
||||
# than the native value (without modifying vars, in case it
|
||||
Index: Python-3.12.4/Lib/test/test_sysconfig.py
|
||||
===================================================================
|
||||
--- Python-3.12.4.orig/Lib/test/test_sysconfig.py
|
||||
+++ Python-3.12.4/Lib/test/test_sysconfig.py
|
||||
@@ -110,8 +110,19 @@ class TestSysConfig(unittest.TestCase):
|
||||
--- a/Lib/test/test_sysconfig.py
|
||||
+++ b/Lib/test/test_sysconfig.py
|
||||
@@ -119,8 +119,19 @@ class TestSysConfig(unittest.TestCase):
|
||||
for scheme in _INSTALL_SCHEMES:
|
||||
for name in _INSTALL_SCHEMES[scheme]:
|
||||
expected = _INSTALL_SCHEMES[scheme][name].format(**config_vars)
|
||||
@ -132,7 +136,7 @@ Index: Python-3.12.4/Lib/test/test_sysconfig.py
|
||||
os.path.normpath(expected),
|
||||
)
|
||||
|
||||
@@ -344,7 +355,7 @@ class TestSysConfig(unittest.TestCase):
|
||||
@@ -353,7 +364,7 @@ class TestSysConfig(unittest.TestCase):
|
||||
self.assertTrue(os.path.isfile(config_h), config_h)
|
||||
|
||||
def test_get_scheme_names(self):
|
||||
@ -141,7 +145,7 @@ Index: Python-3.12.4/Lib/test/test_sysconfig.py
|
||||
if HAS_USER_BASE:
|
||||
wanted.extend(['nt_user', 'osx_framework_user', 'posix_user'])
|
||||
self.assertEqual(get_scheme_names(), tuple(sorted(wanted)))
|
||||
@@ -356,6 +367,8 @@ class TestSysConfig(unittest.TestCase):
|
||||
@@ -365,6 +376,8 @@ class TestSysConfig(unittest.TestCase):
|
||||
cmd = "-c", "import sysconfig; print(sysconfig.get_platform())"
|
||||
self.assertEqual(py.call_real(*cmd), py.call_link(*cmd))
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:24887b92e2afd4a2ac602419ad4b596372f67ac9b077190f459aba390faf5550
|
||||
size 20444032
|
@ -1,18 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQKTBAABCgB9FiEEcWlgX2LHUTVtBUomqCHmgOX6YwUFAmb7fPtfFIAAAAAALgAo
|
||||
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDcx
|
||||
Njk2MDVGNjJDNzUxMzU2RDA1NEEyNkE4MjFFNjgwRTVGQTYzMDUACgkQqCHmgOX6
|
||||
YwUVbw//ZIkOgBaCTVKbjfLbOj9aui1v4kFEex0AB4H/RdmJwrO4S+p76UuHb2c3
|
||||
eG65uL8KWwo1CmX7O62YFVjVkMCaYn5J96ReDVP4XygglYv1HtxFhOwH9OhsAjhT
|
||||
1HIvdx22mO+xpqMBus5+1W6pwgfmMV6eWvVQasDp3mXPRv/x7imjZUfT5sr8kH49
|
||||
BWztinQ3PIN4JsPdAXGT/H08FVR5zC/4BG5GRMcDH+g5kqFCF97TxLoY2auP8XS+
|
||||
WDAomj5wfPdsGk5CDZ5ImRikwJlsr5A9QZxCv4FWH4j4ndUr/i9Spuut9t+hBgrd
|
||||
jYc2vMPkm97RDlSd78Bfz5kUCH9hJSC3r/kpa0rk1QLKHk8h8OGMgXG4FLGl4hVw
|
||||
M/NZQ9A7A6FDApvLXc5CbTEpgRlldkIr2kae9KR803E28sdEl6pQqr0lvhoLPe5i
|
||||
OhPvsmJdazIo/R7AJkNdmU7T+E0Ikova3TOxVyr3ryyjW4UrppIdxiWeAJ8ood4U
|
||||
tcJ1Dq9+Zj5oo/88TR/KwkYrM7FFUKRa1AgirUk88v+16z2qVgf0cSUAW10rTWAZ
|
||||
FP8K+ADR31AXAQrxLOAzaP/NXgAjRuTmuTLrdWE5K+kbSTKbUigKY4z+IKVvq/qA
|
||||
SoN2v6/22do+z4OQMnPDGBU3t8iTqIeuvOMCfYsQBTAZqqq5y4Q=
|
||||
=kx8a
|
||||
-----END PGP SIGNATURE-----
|
3
Python-3.12.8.tar.xz
Normal file
3
Python-3.12.8.tar.xz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c909157bb25ec114e5869124cc2a9c4a4d4c1e957ca4ff553f1edc692101154e
|
||||
size 20489808
|
18
Python-3.12.8.tar.xz.asc
Normal file
18
Python-3.12.8.tar.xz.asc
Normal file
@ -0,0 +1,18 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQKTBAABCgB9FiEEcWlgX2LHUTVtBUomqCHmgOX6YwUFAmdPZepfFIAAAAAALgAo
|
||||
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDcx
|
||||
Njk2MDVGNjJDNzUxMzU2RDA1NEEyNkE4MjFFNjgwRTVGQTYzMDUACgkQqCHmgOX6
|
||||
YwV2vQ//enP0FhpesVqbIf52CDqRUxRmO29bgW+a4wvRMMcGhMwVhDYKBSXwpI1O
|
||||
FJDm6y16mjfgVDJ17aU15+NUGqEDEcDj/59LUgOBkbgGkhhi7qPvqG+8YJoTJtFr
|
||||
0N3dcYwMSJQmN+y+xAWWHhc576KSkASqTG5OcS/n6yTG+zjFkN2Iznp0INQZpSt2
|
||||
44YocvRIK0vozabd47JCx5w/txE3nYtsl6nG5VTMeavbWYzgFBJhVSyykLSJxlyU
|
||||
mJgL0DMspjsUH2ZeYkHqqnuEZkogwJfI3eL2Z4BdVb96hh/s/L4UaSa3GI1a2Tdf
|
||||
c6UJLGWTqaFFcohIVrGhgckAQRrit7AZCBb/FwTsDXahxau7ECLNpgcRQCWgAXlN
|
||||
l7SSQkI2snUs5c+mCuBspDvBVxhAWq1VUelkPurQymR/ajGywwXgdGQwmq7BO+Wr
|
||||
E7fChlwTKLFkQorrzKw7FoL674gTolCHoO/XTDmCNIkEblykSl9mz9FnI2q1C0id
|
||||
Q+rM1rGo2ubJhthvpKdA5jDpzK6tPqG2xNgV6+xhXl4Bg7w4dhEKIu1vKH4RRBgR
|
||||
GTf9LSlJMdaDIyWbbuMFpthCrhnmXbK0qe4whQRtip/TB+1qjl1e5gB0kULujApj
|
||||
RbtxbR50cCDmocM6nae2P1tq0s3jaSs/VemiptexdTilGcm3088=
|
||||
=2KVU
|
||||
-----END PGP SIGNATURE-----
|
@ -1,24 +1,25 @@
|
||||
---
|
||||
Doc/conf.py | 4 +-
|
||||
Doc/conf.py | 8 ++--
|
||||
Doc/tools/check-warnings.py | 3 +
|
||||
Doc/tools/extensions/audit_events.py | 54 ++++++++++++++++----------------
|
||||
Doc/tools/extensions/availability.py | 15 ++++----
|
||||
Doc/tools/extensions/c_annotations.py | 37 ++++++++++-----------
|
||||
Doc/tools/extensions/glossary_search.py | 10 +----
|
||||
Doc/tools/extensions/patchlevel.py | 9 ++---
|
||||
6 files changed, 58 insertions(+), 59 deletions(-)
|
||||
7 files changed, 67 insertions(+), 69 deletions(-)
|
||||
|
||||
--- a/Doc/conf.py
|
||||
+++ b/Doc/conf.py
|
||||
@@ -76,7 +76,7 @@ today_fmt = '%B %d, %Y'
|
||||
@@ -85,7 +85,7 @@ today_fmt = '%B %d, %Y'
|
||||
highlight_language = 'python3'
|
||||
|
||||
# Minimum version of sphinx required
|
||||
-needs_sphinx = '6.2.1'
|
||||
-needs_sphinx = '7.2.6'
|
||||
+needs_sphinx = '4.2.0'
|
||||
|
||||
# Create table of contents entries for domain objects (e.g. functions, classes,
|
||||
# attributes, etc.). Default is True.
|
||||
@@ -329,7 +329,7 @@ html_short_title = f'{release} Documenta
|
||||
@@ -342,7 +342,7 @@ html_short_title = f'{release} Documenta
|
||||
# (See .readthedocs.yml and https://docs.readthedocs.io/en/stable/reference/environment-variables.html)
|
||||
is_deployment_preview = os.getenv("READTHEDOCS_VERSION_TYPE") == "external"
|
||||
repository_url = os.getenv("READTHEDOCS_GIT_CLONE_URL", "")
|
||||
@ -27,6 +28,22 @@
|
||||
html_context = {
|
||||
"is_deployment_preview": is_deployment_preview,
|
||||
"repository_url": repository_url or None,
|
||||
@@ -598,13 +598,13 @@ extlinks_detect_hardcoded_links = True
|
||||
|
||||
if sphinx.version_info[:2] < (8, 1):
|
||||
# Sphinx 8.1 has in-built CVE and CWE roles.
|
||||
- extlinks |= {
|
||||
+ extlinks.update({
|
||||
"cve": (
|
||||
"https://www.cve.org/CVERecord?id=CVE-%s",
|
||||
"CVE-%s",
|
||||
),
|
||||
"cwe": ("https://cwe.mitre.org/data/definitions/%s.html", "CWE-%s"),
|
||||
- }
|
||||
+ })
|
||||
|
||||
# Options for c_annotations extension
|
||||
# -----------------------------------
|
||||
--- a/Doc/tools/check-warnings.py
|
||||
+++ b/Doc/tools/check-warnings.py
|
||||
@@ -228,7 +228,8 @@ def fail_if_regression(
|
||||
@ -181,6 +198,61 @@
|
||||
) -> nodes.row:
|
||||
row = nodes.row()
|
||||
name_node = nodes.paragraph("", nodes.Text(name))
|
||||
--- a/Doc/tools/extensions/availability.py
|
||||
+++ b/Doc/tools/extensions/availability.py
|
||||
@@ -1,8 +1,6 @@
|
||||
"""Support for documenting platform availability"""
|
||||
|
||||
-from __future__ import annotations
|
||||
-
|
||||
-from typing import TYPE_CHECKING
|
||||
+from typing import Dict, List, TYPE_CHECKING, Union
|
||||
|
||||
from docutils import nodes
|
||||
from sphinx import addnodes
|
||||
@@ -52,7 +50,7 @@ class Availability(SphinxDirective):
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
|
||||
- def run(self) -> list[nodes.container]:
|
||||
+ def run(self) -> List[nodes.container]:
|
||||
title = "Availability"
|
||||
refnode = addnodes.pending_xref(
|
||||
title,
|
||||
@@ -76,7 +74,7 @@ class Availability(SphinxDirective):
|
||||
|
||||
return [cnode]
|
||||
|
||||
- def parse_platforms(self) -> dict[str, str | bool]:
|
||||
+ def parse_platforms(self) -> Dict[str, Union[str, bool]]:
|
||||
"""Parse platform information from arguments
|
||||
|
||||
Arguments is a comma-separated string of platforms. A platform may
|
||||
@@ -95,12 +93,13 @@ class Availability(SphinxDirective):
|
||||
platform, _, version = arg.partition(" >= ")
|
||||
if platform.startswith("not "):
|
||||
version = False
|
||||
- platform = platform.removeprefix("not ")
|
||||
+ platform = platform[len("not "):]
|
||||
elif not version:
|
||||
version = True
|
||||
platforms[platform] = version
|
||||
|
||||
- if unknown := set(platforms).difference(KNOWN_PLATFORMS):
|
||||
+ unknown = set(platforms).difference(KNOWN_PLATFORMS)
|
||||
+ if unknown:
|
||||
logger.warning(
|
||||
"Unknown platform%s or syntax '%s' in '.. availability:: %s', "
|
||||
"see %s:KNOWN_PLATFORMS for a set of known platforms.",
|
||||
@@ -113,7 +112,7 @@ class Availability(SphinxDirective):
|
||||
return platforms
|
||||
|
||||
|
||||
-def setup(app: Sphinx) -> ExtensionMetadata:
|
||||
+def setup(app):
|
||||
app.add_directive("availability", Availability)
|
||||
|
||||
return {
|
||||
--- a/Doc/tools/extensions/c_annotations.py
|
||||
+++ b/Doc/tools/extensions/c_annotations.py
|
||||
@@ -9,12 +9,10 @@ Configuration:
|
||||
|
@ -42,8 +42,8 @@
|
||||
|
||||
--- a/Doc/tools/extensions/pyspecific.py
|
||||
+++ b/Doc/tools/extensions/pyspecific.py
|
||||
@@ -27,7 +27,10 @@ from sphinx.locale import _ as sphinx_ge
|
||||
from sphinx.util import logging
|
||||
@@ -26,7 +26,10 @@ from sphinx.domains.python import PyFunc
|
||||
from sphinx.locale import _ as sphinx_gettext
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
from sphinx.writers.text import TextWriter, TextTranslator
|
||||
-from sphinx.util.display import status_iterator
|
||||
|
@ -21,7 +21,7 @@
|
||||
Create a Python.framework rather than a traditional Unix install. Optional
|
||||
--- a/Misc/NEWS
|
||||
+++ b/Misc/NEWS
|
||||
@@ -14138,7 +14138,7 @@ C API
|
||||
@@ -14575,7 +14575,7 @@ C API
|
||||
- bpo-40939: Removed documentation for the removed ``PyParser_*`` C API.
|
||||
|
||||
- bpo-43795: The list in :ref:`limited-api-list` now shows the public name
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
--- a/Lib/test/test_posix.py
|
||||
+++ b/Lib/test/test_posix.py
|
||||
@@ -435,7 +435,7 @@ class PosixTester(unittest.TestCase):
|
||||
@@ -437,7 +437,7 @@ class PosixTester(unittest.TestCase):
|
||||
def test_posix_fadvise(self):
|
||||
fd = os.open(os_helper.TESTFN, os.O_RDONLY)
|
||||
try:
|
||||
|
@ -1,3 +1,348 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Dec 6 20:39:56 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
|
||||
|
||||
- Add CVE-2024-12254-unbound-mem-buffering-SelectorSocketTransport.writelines.patch
|
||||
preventing exhaustion of memory (gh#python/cpython#127655,
|
||||
bsc#1234290, CVE-2024-12254).
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Dec 4 21:47:08 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
|
||||
|
||||
- Update to 3.12.8:
|
||||
- Tools/Demos
|
||||
- gh-126807: Fix extraction warnings in pygettext.py caused
|
||||
by mistaking function definitions for function calls.
|
||||
- Tests
|
||||
- gh-126909: Fix test_os extended attribute tests to work on
|
||||
filesystems with 1 KiB xattr size limit.
|
||||
- gh-125041: Re-enable skipped tests for zlib on the
|
||||
s390x architecture: only skip checks of the compressed
|
||||
bytes, which can be different between zlib’s software
|
||||
implementation and the hardware-accelerated implementation.
|
||||
- gh-124295: Add translation tests to the argparse module.
|
||||
- Security
|
||||
- gh-126623: Upgrade libexpat to 2.6.4
|
||||
- Library
|
||||
- gh-127303: Publicly expose EXACT_TOKEN_TYPES in
|
||||
token.__all__.
|
||||
- gh-123967: Fix faulthandler for trampoline frames. If the
|
||||
top-most frame is a trampoline frame, skip it. Patch by
|
||||
Victor Stinner.
|
||||
- gh-127182: Fix io.StringIO.__setstate__() crash, when None
|
||||
was passed as the first value.
|
||||
- gh-127217: Fix urllib.request.pathname2url() for paths
|
||||
starting with multiple slashes on Posix.
|
||||
- gh-127035: Fix shutil.which on Windows. Now it looks at
|
||||
direct match if and only if the command ends with a PATHEXT
|
||||
extension or X_OK is not in mode. Support extensionless
|
||||
files if “.” is in PATHEXT. Support PATHEXT extensions that
|
||||
end with a dot.
|
||||
- gh-127078: Fix issue where urllib.request.url2pathname()
|
||||
failed to discard an extra slash before a UNC drive in the
|
||||
URL path on Windows.
|
||||
- gh-126766: Fix issue where urllib.request.url2pathname()
|
||||
failed to discard any ‘localhost’ authority present in the
|
||||
URL.
|
||||
- gh-126997: Fix support of STRING and GLOBAL opcodes with
|
||||
non-ASCII arguments in pickletools. pickletools.dis()
|
||||
now outputs non-ASCII bytes in STRING, BINSTRING and
|
||||
SHORT_BINSTRING arguments as escaped (\xXX).
|
||||
- gh-126618: Fix the representation of itertools.count
|
||||
objects when the count value is sys.maxsize.
|
||||
- gh-85168: Fix issue where urllib.request.url2pathname() and
|
||||
pathname2url() always used UTF-8 when quoting and unquoting
|
||||
file URIs. They now use the filesystem encoding and error
|
||||
handler.
|
||||
- gh-67877: Fix memory leaks when regular expression matching
|
||||
terminates abruptly, either because of a signal or because
|
||||
memory allocation fails.
|
||||
- gh-126789: Fixed the values of sysconfig.get_config_vars(),
|
||||
sysconfig.get_paths(), and their siblings when the site
|
||||
initialization happens after sysconfig has built a cache
|
||||
for sysconfig.get_config_vars().
|
||||
- gh-126188: Update bundled pip to 24.3.1
|
||||
- gh-126766: Fix issue where urllib.request.url2pathname()
|
||||
failed to discard two leading slashes introducing an empty
|
||||
authority section.
|
||||
- gh-126727: locale.nl_langinfo(locale.ERA) now returns
|
||||
multiple era description segments separated by
|
||||
semicolons. Previously it only returned the first segment
|
||||
on platforms with Glibc.
|
||||
- gh-126699: Allow collections.abc.AsyncIterator to be a base
|
||||
for Protocols.
|
||||
- gh-104745: Limit starting a patcher (from
|
||||
unittest.mock.patch() or unittest.mock.patch.object()) more
|
||||
than once without stopping it
|
||||
- gh-126595: Fix a crash when instantiating itertools.count
|
||||
with an initial count of sys.maxsize on debug builds. Patch
|
||||
by Bénédikt Tran.
|
||||
- gh-120423: Fix issue where urllib.request.pathname2url()
|
||||
mishandled Windows paths with embedded forward slashes.
|
||||
- gh-126565: Improve performances of zipfile.Path.open() for
|
||||
non-reading modes.
|
||||
- gh-126505: Fix bugs in compiling case-insensitive regular
|
||||
expressions with character classes containing non-BMP
|
||||
characters: upper-case non-BMP character did was ignored
|
||||
and the ASCII flag was ignored when matching a character
|
||||
range whose upper bound is beyond the BMP region.
|
||||
- gh-117378: Fixed the multiprocessing "forkserver"
|
||||
start method forkserver process to correctly inherit
|
||||
the parent’s sys.path during the importing of
|
||||
multiprocessing.set_forkserver_preload() modules in the
|
||||
same manner as sys.path is configured in workers before
|
||||
executing work items.
|
||||
This bug caused some forkserver module preloading to silently
|
||||
fail to preload. This manifested as a performance degration
|
||||
in child processes when the sys.path was required due to
|
||||
additional repeated work in every worker.
|
||||
It could also have a side effect of "" remaining in
|
||||
sys.path during forkserver preload imports instead of the
|
||||
absolute path from os.getcwd() at multiprocessing import time
|
||||
used in the worker sys.path.
|
||||
The sys.path differences between phases in the child
|
||||
process could potentially have caused preload to import incorrect
|
||||
things from the wrong location. We are unaware of that actually
|
||||
having happened in practice.
|
||||
- gh-125679: The multiprocessing.Lock and
|
||||
multiprocessing.RLock repr values no longer say “unknown”
|
||||
on macOS.
|
||||
- gh-126476: Raise calendar.IllegalMonthError (now a subclass
|
||||
of IndexError) for calendar.month() when the input month is
|
||||
not correct.
|
||||
- gh-126489: The Python implementation of pickle no longer
|
||||
calls pickle.Pickler.persistent_id() for the result of
|
||||
persistent_id().
|
||||
- gh-126303: Fix pickling and copying of os.sched_param
|
||||
objects.
|
||||
- gh-126138: Fix a use-after-free crash on asyncio.Task
|
||||
objects whose underlying coroutine yields an object that
|
||||
implements an evil __getattribute__(). Patch by Nico
|
||||
Posada.
|
||||
- gh-126220: Fix crash in cProfile.Profile and
|
||||
_lsprof.Profiler when their callbacks were directly called
|
||||
with 0 arguments.
|
||||
- gh-126212: Fix issue where urllib.request.pathname2url()
|
||||
and url2pathname() removed slashes from Windows DOS drive
|
||||
paths and URLs.
|
||||
- gh-126205: Fix issue where urllib.request.pathname2url()
|
||||
generated URLs beginning with four slashes (rather than
|
||||
two) when given a Windows UNC path.
|
||||
- gh-126105: Fix a crash in ast when the ast.AST._fields
|
||||
attribute is deleted.
|
||||
- gh-126106: Fixes a possible NULL pointer dereference in
|
||||
ssl.
|
||||
- gh-126080: Fix a use-after-free crash on asyncio.Task
|
||||
objects for which the underlying event loop implements an
|
||||
evil __getattribute__(). Reported by Nico-Posada. Patch by
|
||||
Bénédikt Tran.
|
||||
- gh-126083: Fixed a reference leak in asyncio.Task objects
|
||||
when reinitializing the same object with a non-None
|
||||
context. Patch by Nico Posada.
|
||||
- gh-125984: Fix use-after-free crashes on asyncio.Future
|
||||
objects for which the underlying event loop implements an
|
||||
evil __getattribute__(). Reported by Nico-Posada. Patch by
|
||||
Bénédikt Tran.
|
||||
- gh-125969: Fix an out-of-bounds crash when an evil
|
||||
asyncio.loop.call_soon() mutates the length of the internal
|
||||
callbacks list. Patch by Bénédikt Tran.
|
||||
- gh-125966: Fix a use-after-free crash in
|
||||
asyncio.Future.remove_done_callback(). Patch by Bénédikt
|
||||
Tran.
|
||||
- gh-125789: Fix possible crash when mutating list of
|
||||
callbacks returned by asyncio.Future._callbacks. It
|
||||
now always returns a new copy in C implementation
|
||||
_asyncio. Patch by Kumar Aditya.
|
||||
- gh-124452: Fix an issue in
|
||||
email.policy.EmailPolicy.header_source_parse() and
|
||||
email.policy.Compat32.header_source_parse() that introduced
|
||||
spurious leading whitespaces into header values when the
|
||||
header includes a newline character after the header name
|
||||
delimiter (:) and before the value.
|
||||
- gh-125884: Fixed the bug for pdb where it can’t set
|
||||
breakpoints on functions with certain annotations.
|
||||
- gh-125355: Fix several bugs in
|
||||
argparse.ArgumentParser.parse_intermixed_args().
|
||||
The parser no longer changes temporarily during parsing.
|
||||
Default values are not processed twice.
|
||||
Required mutually exclusive groups containing positional
|
||||
arguments are now supported.
|
||||
The missing arguments report now includes the names of
|
||||
all required optional and positional arguments.
|
||||
Unknown options can be intermixed with positional
|
||||
arguments in parse_known_intermixed_args().
|
||||
- gh-125682: Reject non-ASCII digits in the Python
|
||||
implementation of json.loads() conforming to the JSON
|
||||
specification.
|
||||
- gh-125660: Reject invalid unicode escapes for Python
|
||||
implementation of json.loads().
|
||||
- gh-125259: Fix the notes removal logic for errors thrown in
|
||||
enum initialization.
|
||||
- gh-125519: Improve traceback if importlib.reload() is
|
||||
called with an object that is not a module. Patch by Alex
|
||||
Waygood.
|
||||
- gh-125451: Fix deadlock when
|
||||
concurrent.futures.ProcessPoolExecutor shuts down
|
||||
concurrently with an error when feeding a job to a worker
|
||||
process.
|
||||
- gh-125422: Fixed the bug where pdb and bdb can step into
|
||||
the bottom caller frame.
|
||||
- gh-100141: Fixed the bug where pdb will be stuck in an
|
||||
infinite loop when debugging an empty file.
|
||||
- gh-53203: Fix time.strptime() for %c, %x and %X formats
|
||||
in many locales that use non-ASCII digits, like Persian,
|
||||
Burmese, Odia and Shan.
|
||||
- gh-125254: Fix a bug where ArgumentError includes the
|
||||
incorrect ambiguous option in argparse.
|
||||
- gh-61011: Fix inheritance of nested mutually
|
||||
exclusive groups from parent parser in
|
||||
argparse.ArgumentParser. Previously, all nested mutually
|
||||
exclusive groups lost their connection to the group
|
||||
containing them and were displayed as belonging directly to
|
||||
the parser.
|
||||
- gh-52551: Fix encoding issues in time.strftime(), the
|
||||
strftime() method of the datetime classes datetime, date
|
||||
and time and formatting of these classes. Characters
|
||||
not encodable in the current locale are now acceptable
|
||||
in the format string. Surrogate pairs and sequence
|
||||
of surrogatescape-encoded bytes are no longer
|
||||
recombinated. Embedded null character no longer terminates
|
||||
the format string.
|
||||
- gh-125118: Don’t copy arbitrary values to _Bool in the
|
||||
struct module.
|
||||
- gh-125069: Fix an issue where providing a pathlib.PurePath
|
||||
object as an initializer argument to a second PurePath
|
||||
object with a different flavour resulted in arguments to
|
||||
the former object’s initializer being joined by the latter
|
||||
object’s flavour.
|
||||
- gh-124969: Fix locale.nl_langinfo(locale.ALT_DIGITS) on
|
||||
platforms with glibc. Now it returns a string consisting of
|
||||
up to 100 semicolon-separated symbols (an empty string in
|
||||
most locales) on all Posix platforms. Previously it only
|
||||
returned the first symbol or an empty string.
|
||||
- gh-124958: Fix refcycles in exceptions raised from
|
||||
asyncio.TaskGroup and the python implementation of
|
||||
asyncio.Future
|
||||
- gh-53203: Fix time.strptime() for %c and %x formats in many
|
||||
locales: Arabic, Bislama, Breton, Bodo, Kashubian, Chuvash,
|
||||
Estonian, French, Irish, Ge’ez, Gurajati, Manx Gaelic,
|
||||
Hebrew, Hindi, Chhattisgarhi, Haitian Kreyol, Japanese,
|
||||
Kannada, Korean, Marathi, Malay, Norwegian, Nynorsk,
|
||||
Punjabi, Rajasthani, Tok Pisin, Yoruba, Yue Chinese,
|
||||
Yau/Nungon and Chinese.
|
||||
- gh-124917: Allow calling os.path.exists() and
|
||||
os.path.lexists() with keyword arguments on Windows. Fixes
|
||||
a regression in 3.12.4.
|
||||
- gh-124653: Fix detection of the minimal Queue API needed by
|
||||
the logging module. Patch by Bénédikt Tran.
|
||||
- gh-124858: Fix reference cycles left in tracebacks
|
||||
in asyncio.open_connection() when used with
|
||||
happy_eyeballs_delay
|
||||
- gh-124390: Fixed AssertionError when using
|
||||
asyncio.staggered.staggered_race() with
|
||||
asyncio.eager_task_factory.
|
||||
- gh-124651: Properly quote template strings in venv
|
||||
activation scripts.
|
||||
- gh-124594: All asyncio REPL prompts run in the same
|
||||
context. Contributed by Bartosz Sławecki.
|
||||
- gh-120378: Fix a crash related to an integer overflow in
|
||||
curses.resizeterm() and curses.resize_term().
|
||||
- gh-123884: Fixed bug in itertools.tee() handling of other
|
||||
tee inputs (a tee in a tee). The output now has the
|
||||
promised n independent new iterators. Formerly, the first
|
||||
iterator was identical (not independent) to the input
|
||||
iterator. This would sometimes give surprising results.
|
||||
- gh-123978: Remove broken time.thread_time() and
|
||||
time.thread_time_ns() on NetBSD.
|
||||
- gh-124008: Fix possible crash (in debug build), incorrect
|
||||
output or returning incorrect value from raw binary write()
|
||||
when writing to console on Windows.
|
||||
- gh-123370: Fix the canvas not clearing after running
|
||||
turtledemo clock.
|
||||
- gh-120754: Update unbounded read calls in zipfile to
|
||||
specify an explicit size putting a limit on how much data
|
||||
they may read. This also updates handling around ZIP max
|
||||
comment size to match the standard instead of reading
|
||||
comments that are one byte too long.
|
||||
- gh-70764: Fixed an issue where inspect.getclosurevars()
|
||||
would incorrectly classify an attribute name as a global
|
||||
variable when the name exists both as an attribute name and
|
||||
a global variable.
|
||||
- gh-119826: Always return an absolute path for
|
||||
os.path.abspath() on Windows.
|
||||
- gh-117766: Always use str() to print choices in argparse.
|
||||
- gh-101955: Fix SystemError when match regular expression
|
||||
pattern containing some combination of possessive
|
||||
quantifier, alternative and capture group.
|
||||
- gh-88110: Fixed multiprocessing.Process reporting a
|
||||
.exitcode of 1 even on success when using the "fork" start
|
||||
method while using a concurrent.futures.ThreadPoolExecutor.
|
||||
- gh-71936: Fix a race condition in
|
||||
multiprocessing.pool.Pool.
|
||||
- bpo-46128: Strip unittest.IsolatedAsyncioTestCase stack
|
||||
frames from reported stacktraces.
|
||||
- bpo-14074: Fix argparse metavar processing to allow
|
||||
positional arguments to have a tuple metavar.
|
||||
- IDLE
|
||||
- gh-122392: Increase currently inadequate vertical spacing
|
||||
for the IDLE browsers (path, module, and stack) on
|
||||
high-resolution monitors.
|
||||
- Documentation
|
||||
- gh-125277: Require Sphinx 7.2.6 or later to build the
|
||||
Python documentation. Patch by Adam Turner.
|
||||
- gh-125018: The importlib.metadata documentation now
|
||||
includes semantic cross-reference targets for the
|
||||
significant documented APIs. This means intersphinx
|
||||
references like importlib.metadata.version() will now work
|
||||
as expected.
|
||||
- gh-121277: Writers of CPython’s documentation can now use
|
||||
next as the version for the versionchanged, versionadded,
|
||||
deprecated directives.
|
||||
- gh-60712: Include the object type in the lists of
|
||||
documented types. Change by Furkan Onder and Martin Panter.
|
||||
- Core and Builtins
|
||||
- gh-113841: Fix possible undefined behavior division by zero
|
||||
in complex’s _Py_c_pow().
|
||||
- gh-126341: Now ValueError is raised instead of SystemError
|
||||
when trying to iterate over a released memoryview object.
|
||||
- gh-126066: Fix importlib to not write an incomplete
|
||||
.pyc files when a ulimit or some other operating system
|
||||
mechanism is preventing the write to go through fully.
|
||||
- gh-126139: Provide better error location when attempting to
|
||||
use a future statement with an unknown future feature.
|
||||
- gh-125008: Fix tokenize.untokenize() producing invalid
|
||||
syntax for double braces preceded by certain escape
|
||||
characters.
|
||||
- gh-123378: Fix a crash in the __str__() method of
|
||||
UnicodeError objects when the UnicodeError.start and
|
||||
UnicodeError.end values are invalid or out-of-range. Patch
|
||||
by Bénédikt Tran.
|
||||
- gh-116510: Fix a crash caused by immortal interned strings
|
||||
being shared between sub-interpreters that use basic
|
||||
single-phase init. In that case, the string can be used
|
||||
by an interpreter that outlives the interpreter that
|
||||
created and interned it. For interpreters that share
|
||||
obmalloc state, also share the interned dict with the main
|
||||
interpreter.
|
||||
- gh-118950: Fix bug where SSLProtocol.connection_lost wasn’t
|
||||
getting called when OSError was thrown on writing to
|
||||
socket.
|
||||
- gh-113570: Fixed a bug in reprlib.repr where it incorrectly
|
||||
called the repr method on shadowed Python built-in types.
|
||||
- gh-109746: If _thread.start_new_thread() fails to start a
|
||||
new thread, it deletes its state from interpreter and thus
|
||||
avoids its repeated cleanup on finalization.
|
||||
- C API
|
||||
- gh-113601: Removed debug build assertions related to
|
||||
interning strings, which were falsely triggered by stable
|
||||
ABI extensions.
|
||||
- Build
|
||||
- gh-89640: Hard-code float word ordering as little endian on
|
||||
WASM.
|
||||
- gh-89640: Improve detection of float word ordering on Linux
|
||||
when link-time optimizations are enabled.
|
||||
- Remove upstreamed patches:
|
||||
- CVE-2024-9287-venv_path_unquoted.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Nov 28 22:20:25 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
|
||||
|
||||
|
@ -110,7 +110,7 @@
|
||||
# _md5.cpython-38m-x86_64-linux-gnu.so
|
||||
%define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so
|
||||
Name: %{python_pkg_name}%{psuffix}
|
||||
Version: 3.12.7
|
||||
Version: 3.12.8
|
||||
Release: 0
|
||||
Summary: Python 3 Interpreter
|
||||
License: Python-2.0
|
||||
@ -182,9 +182,9 @@ Patch41: docs-docutils_014-Sphinx_420.patch
|
||||
# PATCH-FIX-SLE doc-py38-to-py36.patch mcepl@suse.com
|
||||
# Make documentation extensions working with Python 3.6
|
||||
Patch44: doc-py38-to-py36.patch
|
||||
# PATCH-FIX-UPSTREAM CVE-2024-9287-venv_path_unquoted.patch gh#python/cpython#124651 mcepl@suse.com
|
||||
# venv should properly quote path names provided when creating a venv
|
||||
Patch45: CVE-2024-9287-venv_path_unquoted.patch
|
||||
# PATCH-FIX-UPSTREAM CVE-2024-12254-unbound-mem-buffering-SelectorSocketTransport.writelines.patch bsc#1234290 mcepl@suse.com
|
||||
# prevents exhaustion of memory
|
||||
Patch45: CVE-2024-12254-unbound-mem-buffering-SelectorSocketTransport.writelines.patch
|
||||
BuildRequires: autoconf-archive
|
||||
BuildRequires: automake
|
||||
BuildRequires: fdupes
|
||||
@ -441,8 +441,7 @@ This package contains libpython3.2 shared library for embedding in
|
||||
other applications.
|
||||
|
||||
%prep
|
||||
%setup -q -n %{tarname}
|
||||
%autopatch -p1
|
||||
%autosetup -p1 -n %{tarname}
|
||||
|
||||
# Fix devhelp doc build gh#python/cpython#120150
|
||||
echo "master_doc = 'contents'" >> Doc/conf.py
|
||||
|
Loading…
x
Reference in New Issue
Block a user