aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Lib
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2024-08-17 21:51:59 +0300
committershadchin <shadchin@yandex-team.com>2024-08-17 22:04:51 +0300
commitee9edbd8878888bafcd0eeb3b528f3ec4311560b (patch)
treed54d8138e50a446904f10a2092719be86af011b7 /contrib/tools/python3/Lib
parent72cbe4bad58add0912623ba51351ff1db8587249 (diff)
downloadydb-ee9edbd8878888bafcd0eeb3b528f3ec4311560b.tar.gz
Update Python 3 to 3.12.5
https://docs.python.org/release/3.12.5/whatsnew/changelog.html#python-3-12-5-final de86cdeacd3a8653b9ec36e87975886fafcf6dc2
Diffstat (limited to 'contrib/tools/python3/Lib')
-rw-r--r--contrib/tools/python3/Lib/_pydatetime.py2
-rw-r--r--contrib/tools/python3/Lib/_pydecimal.py2
-rw-r--r--contrib/tools/python3/Lib/argparse.py26
-rw-r--r--contrib/tools/python3/Lib/asyncio/__main__.py2
-rw-r--r--contrib/tools/python3/Lib/asyncio/base_events.py5
-rw-r--r--contrib/tools/python3/Lib/calendar.py4
-rw-r--r--contrib/tools/python3/Lib/code.py19
-rw-r--r--contrib/tools/python3/Lib/colorsys.py2
-rw-r--r--contrib/tools/python3/Lib/concurrent/futures/__init__.py1
-rw-r--r--contrib/tools/python3/Lib/decimal.py4
-rw-r--r--contrib/tools/python3/Lib/email/_header_value_parser.py13
-rw-r--r--contrib/tools/python3/Lib/email/_policybase.py8
-rw-r--r--contrib/tools/python3/Lib/email/errors.py4
-rw-r--r--contrib/tools/python3/Lib/email/generator.py13
-rw-r--r--contrib/tools/python3/Lib/email/utils.py2
-rw-r--r--contrib/tools/python3/Lib/ensurepip/__init__.py2
-rw-r--r--contrib/tools/python3/Lib/filecmp.py10
-rw-r--r--contrib/tools/python3/Lib/fractions.py4
-rw-r--r--contrib/tools/python3/Lib/functools.py16
-rw-r--r--contrib/tools/python3/Lib/http/cookies.py2
-rw-r--r--contrib/tools/python3/Lib/importlib/metadata/__init__.py2
-rw-r--r--contrib/tools/python3/Lib/importlib/util.py4
-rw-r--r--contrib/tools/python3/Lib/inspect.py14
-rw-r--r--contrib/tools/python3/Lib/ipaddress.py2
-rw-r--r--contrib/tools/python3/Lib/linecache.py6
-rw-r--r--contrib/tools/python3/Lib/logging/config.py56
-rw-r--r--contrib/tools/python3/Lib/logging/handlers.py6
-rw-r--r--contrib/tools/python3/Lib/mimetypes.py2
-rwxr-xr-xcontrib/tools/python3/Lib/pdb.py24
-rw-r--r--contrib/tools/python3/Lib/pickle.py99
-rw-r--r--contrib/tools/python3/Lib/pstats.py2
-rwxr-xr-xcontrib/tools/python3/Lib/pydoc.py8
-rw-r--r--contrib/tools/python3/Lib/pydoc_data/topics.py330
-rw-r--r--contrib/tools/python3/Lib/re/_casefix.py2
-rw-r--r--contrib/tools/python3/Lib/sched.py2
-rw-r--r--contrib/tools/python3/Lib/socket.py104
-rw-r--r--contrib/tools/python3/Lib/statistics.py2
-rw-r--r--contrib/tools/python3/Lib/symtable.py31
-rwxr-xr-xcontrib/tools/python3/Lib/tabnanny.py8
-rw-r--r--contrib/tools/python3/Lib/threading.py8
-rw-r--r--contrib/tools/python3/Lib/typing.py23
-rw-r--r--contrib/tools/python3/Lib/unittest/mock.py30
-rw-r--r--contrib/tools/python3/Lib/xml/etree/ElementTree.py2
-rw-r--r--contrib/tools/python3/Lib/ya.make4
44 files changed, 589 insertions, 323 deletions
diff --git a/contrib/tools/python3/Lib/_pydatetime.py b/contrib/tools/python3/Lib/_pydatetime.py
index cd0ea900bfb..ad6292e1e41 100644
--- a/contrib/tools/python3/Lib/_pydatetime.py
+++ b/contrib/tools/python3/Lib/_pydatetime.py
@@ -970,6 +970,8 @@ class date:
@classmethod
def fromtimestamp(cls, t):
"Construct a date from a POSIX timestamp (like time.time())."
+ if t is None:
+ raise TypeError("'NoneType' object cannot be interpreted as an integer")
y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t)
return cls(y, m, d)
diff --git a/contrib/tools/python3/Lib/_pydecimal.py b/contrib/tools/python3/Lib/_pydecimal.py
index 613123ec7b4..75df3db2624 100644
--- a/contrib/tools/python3/Lib/_pydecimal.py
+++ b/contrib/tools/python3/Lib/_pydecimal.py
@@ -424,7 +424,7 @@ def localcontext(ctx=None, **kwargs):
# numbers.py for more detail.
class Decimal(object):
- """Floating point class for decimal arithmetic."""
+ """Floating-point class for decimal arithmetic."""
__slots__ = ('_exp','_int','_sign', '_is_special')
# Generally, the value of the Decimal instance is given by
diff --git a/contrib/tools/python3/Lib/argparse.py b/contrib/tools/python3/Lib/argparse.py
index 120cb6c8458..e4892955e4f 100644
--- a/contrib/tools/python3/Lib/argparse.py
+++ b/contrib/tools/python3/Lib/argparse.py
@@ -1843,7 +1843,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# ==================================
def add_subparsers(self, **kwargs):
if self._subparsers is not None:
- self.error(_('cannot have multiple subparser arguments'))
+ raise ArgumentError(None, _('cannot have multiple subparser arguments'))
# add the parser class to the arguments if it's not present
kwargs.setdefault('parser_class', type(self))
@@ -1895,8 +1895,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
def parse_args(self, args=None, namespace=None):
args, argv = self.parse_known_args(args, namespace)
if argv:
- msg = _('unrecognized arguments: %s')
- self.error(msg % ' '.join(argv))
+ msg = _('unrecognized arguments: %s') % ' '.join(argv)
+ if self.exit_on_error:
+ self.error(msg)
+ else:
+ raise ArgumentError(None, msg)
return args
def parse_known_args(self, args=None, namespace=None):
@@ -2175,7 +2178,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
self._get_value(action, action.default))
if required_actions:
- self.error(_('the following arguments are required: %s') %
+ raise ArgumentError(None, _('the following arguments are required: %s') %
', '.join(required_actions))
# make sure all required groups had one option present
@@ -2191,7 +2194,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
for action in group._group_actions
if action.help is not SUPPRESS]
msg = _('one of the arguments %s is required')
- self.error(msg % ' '.join(names))
+ raise ArgumentError(None, msg % ' '.join(names))
# return the updated namespace and the extra arguments
return namespace, extras
@@ -2218,7 +2221,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
arg_strings = self._read_args_from_files(arg_strings)
new_arg_strings.extend(arg_strings)
except OSError as err:
- self.error(str(err))
+ raise ArgumentError(None, str(err))
# return the modified argument list
return new_arg_strings
@@ -2298,7 +2301,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
for action, option_string, sep, explicit_arg in option_tuples])
args = {'option': arg_string, 'matches': options}
msg = _('ambiguous option: %(option)s could match %(matches)s')
- self.error(msg % args)
+ raise ArgumentError(None, msg % args)
# if exactly one action matched, this segmentation is good,
# so return the parsed action
@@ -2358,7 +2361,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# shouldn't ever get here
else:
- self.error(_('unexpected option string: %s') % option_string)
+ raise ArgumentError(None, _('unexpected option string: %s') % option_string)
# return the collected option tuples
return result
@@ -2415,8 +2418,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
def parse_intermixed_args(self, args=None, namespace=None):
args, argv = self.parse_known_intermixed_args(args, namespace)
if argv:
- msg = _('unrecognized arguments: %s')
- self.error(msg % ' '.join(argv))
+ msg = _('unrecognized arguments: %s') % ' '.join(argv)
+ if self.exit_on_error:
+ self.error(msg)
+ else:
+ raise ArgumentError(None, msg)
return args
def parse_known_intermixed_args(self, args=None, namespace=None):
diff --git a/contrib/tools/python3/Lib/asyncio/__main__.py b/contrib/tools/python3/Lib/asyncio/__main__.py
index c39a31d7b3d..04655801151 100644
--- a/contrib/tools/python3/Lib/asyncio/__main__.py
+++ b/contrib/tools/python3/Lib/asyncio/__main__.py
@@ -89,6 +89,8 @@ class REPLThread(threading.Thread):
if __name__ == '__main__':
+ sys.audit("cpython.run_stdin")
+
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
diff --git a/contrib/tools/python3/Lib/asyncio/base_events.py b/contrib/tools/python3/Lib/asyncio/base_events.py
index 29eff0499cb..cb037fd472c 100644
--- a/contrib/tools/python3/Lib/asyncio/base_events.py
+++ b/contrib/tools/python3/Lib/asyncio/base_events.py
@@ -994,8 +994,7 @@ class BaseEventLoop(events.AbstractEventLoop):
except OSError as exc:
msg = (
f'error while attempting to bind on '
- f'address {laddr!r}: '
- f'{exc.strerror.lower()}'
+ f'address {laddr!r}: {str(exc).lower()}'
)
exc = OSError(exc.errno, msg)
my_exceptions.append(exc)
@@ -1561,7 +1560,7 @@ class BaseEventLoop(events.AbstractEventLoop):
except OSError as err:
msg = ('error while attempting '
'to bind on address %r: %s'
- % (sa, err.strerror.lower()))
+ % (sa, str(err).lower()))
if err.errno == errno.EADDRNOTAVAIL:
# Assume the family is not enabled (bpo-30945)
sockets.pop()
diff --git a/contrib/tools/python3/Lib/calendar.py b/contrib/tools/python3/Lib/calendar.py
index 97d7cab3365..ee3ec838c96 100644
--- a/contrib/tools/python3/Lib/calendar.py
+++ b/contrib/tools/python3/Lib/calendar.py
@@ -159,8 +159,8 @@ def weekday(year, month, day):
def monthrange(year, month):
- """Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for
- year, month."""
+ """Return weekday of first day of month (0-6 ~ Mon-Sun)
+ and number of days (28-31) for year, month."""
if not 1 <= month <= 12:
raise IllegalMonthError(month)
day1 = weekday(year, month, 1)
diff --git a/contrib/tools/python3/Lib/code.py b/contrib/tools/python3/Lib/code.py
index 2bd5fa3e795..b4b1ef3b8b9 100644
--- a/contrib/tools/python3/Lib/code.py
+++ b/contrib/tools/python3/Lib/code.py
@@ -127,7 +127,7 @@ class InteractiveInterpreter:
else:
# If someone has set sys.excepthook, we let that take precedence
# over self.write
- sys.excepthook(type, value, tb)
+ self._call_excepthook(type, value, tb)
def showtraceback(self):
"""Display the exception that just occurred.
@@ -141,16 +141,29 @@ class InteractiveInterpreter:
sys.last_traceback = last_tb
sys.last_exc = ei[1]
try:
- lines = traceback.format_exception(ei[0], ei[1], last_tb.tb_next)
if sys.excepthook is sys.__excepthook__:
+ lines = traceback.format_exception(ei[0], ei[1], last_tb.tb_next)
self.write(''.join(lines))
else:
# If someone has set sys.excepthook, we let that take precedence
# over self.write
- sys.excepthook(ei[0], ei[1], last_tb)
+ self._call_excepthook(ei[0], ei[1], last_tb)
finally:
last_tb = ei = None
+ def _call_excepthook(self, typ, value, tb):
+ try:
+ sys.excepthook(typ, value, tb)
+ except SystemExit:
+ raise
+ except BaseException as e:
+ e.__context__ = None
+ print('Error in sys.excepthook:', file=sys.stderr)
+ sys.__excepthook__(type(e), e, e.__traceback__.tb_next)
+ print(file=sys.stderr)
+ print('Original exception was:', file=sys.stderr)
+ sys.__excepthook__(typ, value, tb)
+
def write(self, data):
"""Write a string.
diff --git a/contrib/tools/python3/Lib/colorsys.py b/contrib/tools/python3/Lib/colorsys.py
index bc897bd0f99..e97f91718a3 100644
--- a/contrib/tools/python3/Lib/colorsys.py
+++ b/contrib/tools/python3/Lib/colorsys.py
@@ -24,7 +24,7 @@ HSV: Hue, Saturation, Value
__all__ = ["rgb_to_yiq","yiq_to_rgb","rgb_to_hls","hls_to_rgb",
"rgb_to_hsv","hsv_to_rgb"]
-# Some floating point constants
+# Some floating-point constants
ONE_THIRD = 1.0/3.0
ONE_SIXTH = 1.0/6.0
diff --git a/contrib/tools/python3/Lib/concurrent/futures/__init__.py b/contrib/tools/python3/Lib/concurrent/futures/__init__.py
index 292e886d5a8..72de617a5b6 100644
--- a/contrib/tools/python3/Lib/concurrent/futures/__init__.py
+++ b/contrib/tools/python3/Lib/concurrent/futures/__init__.py
@@ -23,6 +23,7 @@ __all__ = (
'ALL_COMPLETED',
'CancelledError',
'TimeoutError',
+ 'InvalidStateError',
'BrokenExecutor',
'Future',
'Executor',
diff --git a/contrib/tools/python3/Lib/decimal.py b/contrib/tools/python3/Lib/decimal.py
index d61e374b9f9..4d8e15cb68f 100644
--- a/contrib/tools/python3/Lib/decimal.py
+++ b/contrib/tools/python3/Lib/decimal.py
@@ -1,6 +1,6 @@
-"""Decimal fixed point and floating point arithmetic.
+"""Decimal fixed-point and floating-point arithmetic.
-This is an implementation of decimal floating point arithmetic based on
+This is an implementation of decimal floating-point arithmetic based on
the General Decimal Arithmetic Specification:
http://speleotrove.com/decimal/decarith.html
diff --git a/contrib/tools/python3/Lib/email/_header_value_parser.py b/contrib/tools/python3/Lib/email/_header_value_parser.py
index ab3c3031ef5..ec2215a5e5f 100644
--- a/contrib/tools/python3/Lib/email/_header_value_parser.py
+++ b/contrib/tools/python3/Lib/email/_header_value_parser.py
@@ -92,6 +92,8 @@ TOKEN_ENDS = TSPECIALS | WSP
ASPECIALS = TSPECIALS | set("*'%")
ATTRIBUTE_ENDS = ASPECIALS | WSP
EXTENDED_ATTRIBUTE_ENDS = ATTRIBUTE_ENDS - set('%')
+NLSET = {'\n', '\r'}
+SPECIALSNL = SPECIALS | NLSET
def quote_string(value):
return '"'+str(value).replace('\\', '\\\\').replace('"', r'\"')+'"'
@@ -2802,9 +2804,13 @@ def _refold_parse_tree(parse_tree, *, policy):
wrap_as_ew_blocked -= 1
continue
tstr = str(part)
- if part.token_type == 'ptext' and set(tstr) & SPECIALS:
- # Encode if tstr contains special characters.
- want_encoding = True
+ if not want_encoding:
+ if part.token_type == 'ptext':
+ # Encode if tstr contains special characters.
+ want_encoding = not SPECIALSNL.isdisjoint(tstr)
+ else:
+ # Encode if tstr contains newlines.
+ want_encoding = not NLSET.isdisjoint(tstr)
try:
tstr.encode(encoding)
charset = encoding
@@ -2988,6 +2994,7 @@ def _fold_as_ew(to_encode, lines, maxlen, last_ew, ew_combine_allowed, charset,
excess = len(encoded_word) - remaining_space
lines[-1] += encoded_word
to_encode = to_encode[len(to_encode_word):]
+ leading_whitespace = ''
if to_encode:
lines.append(' ')
diff --git a/contrib/tools/python3/Lib/email/_policybase.py b/contrib/tools/python3/Lib/email/_policybase.py
index 2ec54fbabae..5f9aa9fb091 100644
--- a/contrib/tools/python3/Lib/email/_policybase.py
+++ b/contrib/tools/python3/Lib/email/_policybase.py
@@ -157,6 +157,13 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta):
message_factory -- the class to use to create new message objects.
If the value is None, the default is Message.
+ verify_generated_headers
+ -- if true, the generator verifies that each header
+ they are properly folded, so that a parser won't
+ treat it as multiple headers, start-of-body, or
+ part of another header.
+ This is a check against custom Header & fold()
+ implementations.
"""
raise_on_defect = False
@@ -165,6 +172,7 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta):
max_line_length = 78
mangle_from_ = False
message_factory = None
+ verify_generated_headers = True
def handle_defect(self, obj, defect):
"""Based on policy, either raise defect or call register_defect.
diff --git a/contrib/tools/python3/Lib/email/errors.py b/contrib/tools/python3/Lib/email/errors.py
index 3ad00565549..02aa5eced6a 100644
--- a/contrib/tools/python3/Lib/email/errors.py
+++ b/contrib/tools/python3/Lib/email/errors.py
@@ -29,6 +29,10 @@ class CharsetError(MessageError):
"""An illegal charset was given."""
+class HeaderWriteError(MessageError):
+ """Error while writing headers."""
+
+
# These are parsing defects which the parser was able to work around.
class MessageDefect(ValueError):
"""Base class for a message defect."""
diff --git a/contrib/tools/python3/Lib/email/generator.py b/contrib/tools/python3/Lib/email/generator.py
index c8056ad47ba..47b9df8f4e6 100644
--- a/contrib/tools/python3/Lib/email/generator.py
+++ b/contrib/tools/python3/Lib/email/generator.py
@@ -14,12 +14,14 @@ import random
from copy import deepcopy
from io import StringIO, BytesIO
from email.utils import _has_surrogates
+from email.errors import HeaderWriteError
UNDERSCORE = '_'
NL = '\n' # XXX: no longer used by the code below.
NLCRE = re.compile(r'\r\n|\r|\n')
fcre = re.compile(r'^From ', re.MULTILINE)
+NEWLINE_WITHOUT_FWSP = re.compile(r'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]')
class Generator:
@@ -222,7 +224,16 @@ class Generator:
def _write_headers(self, msg):
for h, v in msg.raw_items():
- self.write(self.policy.fold(h, v))
+ folded = self.policy.fold(h, v)
+ if self.policy.verify_generated_headers:
+ linesep = self.policy.linesep
+ if not folded.endswith(self.policy.linesep):
+ raise HeaderWriteError(
+ f'folded header does not end with {linesep!r}: {folded!r}')
+ if NEWLINE_WITHOUT_FWSP.search(folded.removesuffix(linesep)):
+ raise HeaderWriteError(
+ f'folded header contains newline: {folded!r}')
+ self.write(folded)
# A blank line always separates headers from body
self.write(self._NL)
diff --git a/contrib/tools/python3/Lib/email/utils.py b/contrib/tools/python3/Lib/email/utils.py
index aa949aa933a..1de547a0117 100644
--- a/contrib/tools/python3/Lib/email/utils.py
+++ b/contrib/tools/python3/Lib/email/utils.py
@@ -128,7 +128,7 @@ def formatdate(timeval=None, localtime=False, usegmt=False):
Fri, 09 Nov 2001 01:08:47 -0000
- Optional timeval if given is a floating point time value as accepted by
+ Optional timeval if given is a floating-point time value as accepted by
gmtime() and localtime(), otherwise the current time is used.
Optional localtime is a flag that when True, interprets timeval, and
diff --git a/contrib/tools/python3/Lib/ensurepip/__init__.py b/contrib/tools/python3/Lib/ensurepip/__init__.py
index 2ac872c25c8..a7c84572382 100644
--- a/contrib/tools/python3/Lib/ensurepip/__init__.py
+++ b/contrib/tools/python3/Lib/ensurepip/__init__.py
@@ -10,7 +10,7 @@ from importlib import resources
__all__ = ["version", "bootstrap"]
_PACKAGE_NAMES = ('pip',)
-_PIP_VERSION = "24.0"
+_PIP_VERSION = "24.2"
_PROJECTS = [
("pip", _PIP_VERSION, "py3"),
]
diff --git a/contrib/tools/python3/Lib/filecmp.py b/contrib/tools/python3/Lib/filecmp.py
index 30bd900fa80..6fdb48f7a39 100644
--- a/contrib/tools/python3/Lib/filecmp.py
+++ b/contrib/tools/python3/Lib/filecmp.py
@@ -160,12 +160,14 @@ class dircmp:
ok = True
try:
a_stat = os.stat(a_path)
- except OSError:
+ except (OSError, ValueError):
+ # See https://github.com/python/cpython/issues/122400
+ # for the rationale for protecting against ValueError.
# print('Can\'t stat', a_path, ':', why.args[1])
ok = False
try:
b_stat = os.stat(b_path)
- except OSError:
+ except (OSError, ValueError):
# print('Can\'t stat', b_path, ':', why.args[1])
ok = False
@@ -280,12 +282,12 @@ def cmpfiles(a, b, common, shallow=True):
# Return:
# 0 for equal
# 1 for different
-# 2 for funny cases (can't stat, etc.)
+# 2 for funny cases (can't stat, NUL bytes, etc.)
#
def _cmp(a, b, sh, abs=abs, cmp=cmp):
try:
return not abs(cmp(a, b, sh))
- except OSError:
+ except (OSError, ValueError):
return 2
diff --git a/contrib/tools/python3/Lib/fractions.py b/contrib/tools/python3/Lib/fractions.py
index 88b418fe383..e3a8bbcfb3e 100644
--- a/contrib/tools/python3/Lib/fractions.py
+++ b/contrib/tools/python3/Lib/fractions.py
@@ -825,8 +825,10 @@ class Fraction(numbers.Rational):
# A fractional power will generally produce an
# irrational number.
return float(a) ** float(b)
- else:
+ elif isinstance(b, (float, complex)):
return float(a) ** b
+ else:
+ return NotImplemented
def __rpow__(b, a):
"""a ** b"""
diff --git a/contrib/tools/python3/Lib/functools.py b/contrib/tools/python3/Lib/functools.py
index 1f1ba638866..318efd04fd8 100644
--- a/contrib/tools/python3/Lib/functools.py
+++ b/contrib/tools/python3/Lib/functools.py
@@ -372,15 +372,13 @@ class partialmethod(object):
self.keywords = keywords
def __repr__(self):
- args = ", ".join(map(repr, self.args))
- keywords = ", ".join("{}={!r}".format(k, v)
- for k, v in self.keywords.items())
- format_string = "{module}.{cls}({func}, {args}, {keywords})"
- return format_string.format(module=self.__class__.__module__,
- cls=self.__class__.__qualname__,
- func=self.func,
- args=args,
- keywords=keywords)
+ cls = type(self)
+ module = cls.__module__
+ qualname = cls.__qualname__
+ args = [repr(self.func)]
+ args.extend(map(repr, self.args))
+ args.extend(f"{k}={v!r}" for k, v in self.keywords.items())
+ return f"{module}.{qualname}({', '.join(args)})"
def _make_unbound_method(self):
def _method(cls_or_self, /, *args, **keywords):
diff --git a/contrib/tools/python3/Lib/http/cookies.py b/contrib/tools/python3/Lib/http/cookies.py
index 35ac2dc6ae2..351faf428a2 100644
--- a/contrib/tools/python3/Lib/http/cookies.py
+++ b/contrib/tools/python3/Lib/http/cookies.py
@@ -234,7 +234,7 @@ def _unquote(str):
# header. By default, _getdate() returns the current time in the appropriate
# "expires" format for a Set-Cookie header. The one optional argument is an
# offset from now, in seconds. For example, an offset of -3600 means "one hour
-# ago". The offset may be a floating point number.
+# ago". The offset may be a floating-point number.
#
_weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
diff --git a/contrib/tools/python3/Lib/importlib/metadata/__init__.py b/contrib/tools/python3/Lib/importlib/metadata/__init__.py
index 54156e93afc..e6ca17821d1 100644
--- a/contrib/tools/python3/Lib/importlib/metadata/__init__.py
+++ b/contrib/tools/python3/Lib/importlib/metadata/__init__.py
@@ -534,7 +534,7 @@ class Distribution(DeprecatedNonAbstract):
paths = (
(subdir / name)
.resolve()
- .relative_to(self.locate_file('').resolve())
+ .relative_to(self.locate_file('').resolve(), walk_up=True)
.as_posix()
for name in text.splitlines()
)
diff --git a/contrib/tools/python3/Lib/importlib/util.py b/contrib/tools/python3/Lib/importlib/util.py
index 3743e6aa912..4b836f47120 100644
--- a/contrib/tools/python3/Lib/importlib/util.py
+++ b/contrib/tools/python3/Lib/importlib/util.py
@@ -13,7 +13,6 @@ from ._bootstrap_external import spec_from_file_location
import _imp
import sys
-import threading
import types
@@ -253,6 +252,9 @@ class LazyLoader(Loader):
def exec_module(self, module):
"""Make the module load lazily."""
+ # Threading is only needed for lazy loading, and importlib.util can
+ # be pulled in at interpreter startup, so defer until needed.
+ import threading
module.__spec__.loader = self.loader
module.__loader__ = self.loader
# Don't need to worry about deep-copying as trying to set an attribute
diff --git a/contrib/tools/python3/Lib/inspect.py b/contrib/tools/python3/Lib/inspect.py
index 497169dacb5..c43faa73159 100644
--- a/contrib/tools/python3/Lib/inspect.py
+++ b/contrib/tools/python3/Lib/inspect.py
@@ -280,7 +280,13 @@ def get_annotations(obj, *, globals=None, locals=None, eval_str=False):
if globals is None:
globals = obj_globals
if locals is None:
- locals = obj_locals
+ locals = obj_locals or {}
+
+ # "Inject" type parameters into the local namespace
+ # (unless they are shadowed by assignments *in* the local namespace),
+ # as a way of emulating annotation scopes when calling `eval()`
+ if type_params := getattr(obj, "__type_params__", ()):
+ locals = {param.__name__: param for param in type_params} | locals
return_value = {key:
value if not isinstance(value, str) else eval(value, globals, locals)
@@ -401,13 +407,13 @@ def isgeneratorfunction(obj):
return _has_code_flag(obj, CO_GENERATOR)
# A marker for markcoroutinefunction and iscoroutinefunction.
-_is_coroutine_marker = object()
+_is_coroutine_mark = object()
def _has_coroutine_mark(f):
while ismethod(f):
f = f.__func__
f = functools._unwrap_partial(f)
- return getattr(f, "_is_coroutine_marker", None) is _is_coroutine_marker
+ return getattr(f, "_is_coroutine_marker", None) is _is_coroutine_mark
def markcoroutinefunction(func):
"""
@@ -415,7 +421,7 @@ def markcoroutinefunction(func):
"""
if hasattr(func, '__func__'):
func = func.__func__
- func._is_coroutine_marker = _is_coroutine_marker
+ func._is_coroutine_marker = _is_coroutine_mark
return func
def iscoroutinefunction(obj):
diff --git a/contrib/tools/python3/Lib/ipaddress.py b/contrib/tools/python3/Lib/ipaddress.py
index d8f3b5e2e9e..816fbcd2bc4 100644
--- a/contrib/tools/python3/Lib/ipaddress.py
+++ b/contrib/tools/python3/Lib/ipaddress.py
@@ -310,7 +310,7 @@ def collapse_addresses(addresses):
[IPv4Network('192.0.2.0/24')]
Args:
- addresses: An iterator of IPv4Network or IPv6Network objects.
+ addresses: An iterable of IPv4Network or IPv6Network objects.
Returns:
An iterator of the collapsed IPv(4|6)Network objects.
diff --git a/contrib/tools/python3/Lib/linecache.py b/contrib/tools/python3/Lib/linecache.py
index 5585216d2b5..05eb49d3b05 100644
--- a/contrib/tools/python3/Lib/linecache.py
+++ b/contrib/tools/python3/Lib/linecache.py
@@ -70,7 +70,7 @@ def checkcache(filename=None):
continue # no-op for files loaded via a __loader__
try:
stat = os.stat(fullname)
- except OSError:
+ except (OSError, ValueError):
cache.pop(filename, None)
continue
if size != stat.st_size or mtime != stat.st_mtime:
@@ -140,10 +140,12 @@ def updatecache(filename, module_globals=None):
try:
stat = os.stat(fullname)
break
- except OSError:
+ except (OSError, ValueError):
pass
else:
return []
+ except ValueError: # may be raised by os.stat()
+ return []
try:
with tokenize.open(fullname) as fp:
lines = fp.readlines()
diff --git a/contrib/tools/python3/Lib/logging/config.py b/contrib/tools/python3/Lib/logging/config.py
index 1824d0aa747..ac90b537d8a 100644
--- a/contrib/tools/python3/Lib/logging/config.py
+++ b/contrib/tools/python3/Lib/logging/config.py
@@ -500,6 +500,33 @@ class BaseConfigurator(object):
value = tuple(value)
return value
+def _is_queue_like_object(obj):
+ """Check that *obj* implements the Queue API."""
+ if isinstance(obj, queue.Queue):
+ return True
+ # defer importing multiprocessing as much as possible
+ from multiprocessing.queues import Queue as MPQueue
+ if isinstance(obj, MPQueue):
+ return True
+ # Depending on the multiprocessing start context, we cannot create
+ # a multiprocessing.managers.BaseManager instance 'mm' to get the
+ # runtime type of mm.Queue() or mm.JoinableQueue() (see gh-119819).
+ #
+ # Since we only need an object implementing the Queue API, we only
+ # do a protocol check, but we do not use typing.runtime_checkable()
+ # and typing.Protocol to reduce import time (see gh-121723).
+ #
+ # Ideally, we would have wanted to simply use strict type checking
+ # instead of a protocol-based type checking since the latter does
+ # not check the method signatures.
+ queue_interface = [
+ 'empty', 'full', 'get', 'get_nowait',
+ 'put', 'put_nowait', 'join', 'qsize',
+ 'task_done',
+ ]
+ return all(callable(getattr(obj, method, None))
+ for method in queue_interface)
+
class DictConfigurator(BaseConfigurator):
"""
Configure logging using a dictionary-like object to describe the
@@ -787,25 +814,20 @@ class DictConfigurator(BaseConfigurator):
# if 'handlers' not in config:
# raise ValueError('No handlers specified for a QueueHandler')
if 'queue' in config:
- from multiprocessing.queues import Queue as MPQueue
- from multiprocessing import Manager as MM
- proxy_queue = MM().Queue()
- proxy_joinable_queue = MM().JoinableQueue()
qspec = config['queue']
- if not isinstance(qspec, (queue.Queue, MPQueue,
- type(proxy_queue), type(proxy_joinable_queue))):
- if isinstance(qspec, str):
- q = self.resolve(qspec)
- if not callable(q):
- raise TypeError('Invalid queue specifier %r' % qspec)
- q = q()
- elif isinstance(qspec, dict):
- if '()' not in qspec:
- raise TypeError('Invalid queue specifier %r' % qspec)
- q = self.configure_custom(dict(qspec))
- else:
+
+ if isinstance(qspec, str):
+ q = self.resolve(qspec)
+ if not callable(q):
raise TypeError('Invalid queue specifier %r' % qspec)
- config['queue'] = q
+ config['queue'] = q()
+ elif isinstance(qspec, dict):
+ if '()' not in qspec:
+ raise TypeError('Invalid queue specifier %r' % qspec)
+ config['queue'] = self.configure_custom(dict(qspec))
+ elif not _is_queue_like_object(qspec):
+ raise TypeError('Invalid queue specifier %r' % qspec)
+
if 'listener' in config:
lspec = config['listener']
if isinstance(lspec, type):
diff --git a/contrib/tools/python3/Lib/logging/handlers.py b/contrib/tools/python3/Lib/logging/handlers.py
index 1ae6bb84434..715bce785c1 100644
--- a/contrib/tools/python3/Lib/logging/handlers.py
+++ b/contrib/tools/python3/Lib/logging/handlers.py
@@ -187,15 +187,15 @@ class RotatingFileHandler(BaseRotatingHandler):
Basically, see if the supplied record would cause the file to exceed
the size limit we have.
"""
- # See bpo-45401: Never rollover anything other than regular files
- if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename):
- return False
if self.stream is None: # delay was set...
self.stream = self._open()
if self.maxBytes > 0: # are we rolling over?
msg = "%s\n" % self.format(record)
self.stream.seek(0, 2) #due to non-posix-compliant Windows feature
if self.stream.tell() + len(msg) >= self.maxBytes:
+ # See bpo-45401: Never rollover anything other than regular files
+ if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename):
+ return False
return True
return False
diff --git a/contrib/tools/python3/Lib/mimetypes.py b/contrib/tools/python3/Lib/mimetypes.py
index 3cc027aa368..10f3ddc5a15 100644
--- a/contrib/tools/python3/Lib/mimetypes.py
+++ b/contrib/tools/python3/Lib/mimetypes.py
@@ -551,6 +551,8 @@ def _default_mime_types():
'.csv' : 'text/csv',
'.html' : 'text/html',
'.htm' : 'text/html',
+ '.md' : 'text/markdown',
+ '.markdown': 'text/markdown',
'.n3' : 'text/n3',
'.txt' : 'text/plain',
'.bat' : 'text/plain',
diff --git a/contrib/tools/python3/Lib/pdb.py b/contrib/tools/python3/Lib/pdb.py
index 225c9f253ef..89cf975164a 100755
--- a/contrib/tools/python3/Lib/pdb.py
+++ b/contrib/tools/python3/Lib/pdb.py
@@ -395,7 +395,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
# Called before loop, handles display expressions
# Set up convenience variable containers
- def preloop(self):
+ def _show_display(self):
displaying = self.displaying.get(self.curframe)
if displaying:
for expr, oldvalue in displaying.items():
@@ -419,10 +419,16 @@ class Pdb(bdb.Bdb, cmd.Cmd):
else:
Pdb._previous_sigint_handler = None
self.setup(frame, traceback)
- # if we have more commands to process, do not show the stack entry
- if not self.cmdqueue:
- self.print_stack_entry(self.stack[self.curindex])
+ # We should print the stack entry if and only if the user input
+ # is expected, and we should print it right before the user input.
+ # We achieve this by appending _pdbcmd_print_frame_status to the
+ # command queue. If cmdqueue is not exausted, the user input is
+ # not expected and we will not print the stack entry.
+ self.cmdqueue.append('_pdbcmd_print_frame_status')
self._cmdloop()
+ # If _pdbcmd_print_frame_status is not used, pop it out
+ if self.cmdqueue and self.cmdqueue[-1] == '_pdbcmd_print_frame_status':
+ self.cmdqueue.pop()
self.forget()
def displayhook(self, obj):
@@ -524,6 +530,10 @@ class Pdb(bdb.Bdb, cmd.Cmd):
a breakpoint command list definition.
"""
if not self.commands_defining:
+ if line.startswith('_pdbcmd'):
+ command, arg, line = self.parseline(line)
+ if hasattr(self, command):
+ return getattr(self, command)(arg)
return cmd.Cmd.onecmd(self, line)
else:
return self.handle_command_def(line)
@@ -623,6 +633,12 @@ class Pdb(bdb.Bdb, cmd.Cmd):
# Complete a simple name.
return [n for n in ns.keys() if n.startswith(text)]
+ # Pdb meta commands, only intended to be used internally by pdb
+
+ def _pdbcmd_print_frame_status(self, arg):
+ self.print_stack_entry(self.stack[self.curindex])
+ self._show_display()
+
# Command definitions, called by cmdloop()
# The argument is the remaining string on the command line
# Return true to exit from the command loop
diff --git a/contrib/tools/python3/Lib/pickle.py b/contrib/tools/python3/Lib/pickle.py
index 6e3c61fd0b2..c4d6e658216 100644
--- a/contrib/tools/python3/Lib/pickle.py
+++ b/contrib/tools/python3/Lib/pickle.py
@@ -314,16 +314,17 @@ class _Unframer:
# Tools used for pickling.
def _getattribute(obj, name):
+ top = obj
for subpath in name.split('.'):
if subpath == '<locals>':
raise AttributeError("Can't get local attribute {!r} on {!r}"
- .format(name, obj))
+ .format(name, top))
try:
parent = obj
obj = getattr(obj, subpath)
except AttributeError:
raise AttributeError("Can't get attribute {!r} on {!r}"
- .format(name, obj)) from None
+ .format(name, top)) from None
return obj, parent
def whichmodule(obj, name):
@@ -780,14 +781,10 @@ class _Pickler:
self.write(FLOAT + repr(obj).encode("ascii") + b'\n')
dispatch[float] = save_float
- def save_bytes(self, obj):
- if self.proto < 3:
- if not obj: # bytes object is empty
- self.save_reduce(bytes, (), obj=obj)
- else:
- self.save_reduce(codecs.encode,
- (str(obj, 'latin1'), 'latin1'), obj=obj)
- return
+ def _save_bytes_no_memo(self, obj):
+ # helper for writing bytes objects for protocol >= 3
+ # without memoizing them
+ assert self.proto >= 3
n = len(obj)
if n <= 0xff:
self.write(SHORT_BINBYTES + pack("<B", n) + obj)
@@ -797,9 +794,29 @@ class _Pickler:
self._write_large_bytes(BINBYTES + pack("<I", n), obj)
else:
self.write(BINBYTES + pack("<I", n) + obj)
+
+ def save_bytes(self, obj):
+ if self.proto < 3:
+ if not obj: # bytes object is empty
+ self.save_reduce(bytes, (), obj=obj)
+ else:
+ self.save_reduce(codecs.encode,
+ (str(obj, 'latin1'), 'latin1'), obj=obj)
+ return
+ self._save_bytes_no_memo(obj)
self.memoize(obj)
dispatch[bytes] = save_bytes
+ def _save_bytearray_no_memo(self, obj):
+ # helper for writing bytearray objects for protocol >= 5
+ # without memoizing them
+ assert self.proto >= 5
+ n = len(obj)
+ if n >= self.framer._FRAME_SIZE_TARGET:
+ self._write_large_bytes(BYTEARRAY8 + pack("<Q", n), obj)
+ else:
+ self.write(BYTEARRAY8 + pack("<Q", n) + obj)
+
def save_bytearray(self, obj):
if self.proto < 5:
if not obj: # bytearray is empty
@@ -807,18 +824,14 @@ class _Pickler:
else:
self.save_reduce(bytearray, (bytes(obj),), obj=obj)
return
- n = len(obj)
- if n >= self.framer._FRAME_SIZE_TARGET:
- self._write_large_bytes(BYTEARRAY8 + pack("<Q", n), obj)
- else:
- self.write(BYTEARRAY8 + pack("<Q", n) + obj)
+ self._save_bytearray_no_memo(obj)
self.memoize(obj)
dispatch[bytearray] = save_bytearray
if _HAVE_PICKLE_BUFFER:
def save_picklebuffer(self, obj):
if self.proto < 5:
- raise PicklingError("PickleBuffer can only pickled with "
+ raise PicklingError("PickleBuffer can only be pickled with "
"protocol >= 5")
with obj.raw() as m:
if not m.contiguous:
@@ -830,10 +843,18 @@ class _Pickler:
if in_band:
# Write data in-band
# XXX The C implementation avoids a copy here
+ buf = m.tobytes()
+ in_memo = id(buf) in self.memo
if m.readonly:
- self.save_bytes(m.tobytes())
+ if in_memo:
+ self._save_bytes_no_memo(buf)
+ else:
+ self.save_bytes(buf)
else:
- self.save_bytearray(m.tobytes())
+ if in_memo:
+ self._save_bytearray_no_memo(buf)
+ else:
+ self.save_bytearray(buf)
else:
# Write data out-of-band
self.write(NEXT_BUFFER)
@@ -1088,11 +1109,35 @@ class _Pickler:
self.save(module_name)
self.save(name)
write(STACK_GLOBAL)
- elif parent is not module:
- self.save_reduce(getattr, (parent, lastname))
- elif self.proto >= 3:
- write(GLOBAL + bytes(module_name, "utf-8") + b'\n' +
- bytes(name, "utf-8") + b'\n')
+ elif '.' in name:
+ # In protocol < 4, objects with multi-part __qualname__
+ # are represented as
+ # getattr(getattr(..., attrname1), attrname2).
+ dotted_path = name.split('.')
+ name = dotted_path.pop(0)
+ save = self.save
+ for attrname in dotted_path:
+ save(getattr)
+ if self.proto < 2:
+ write(MARK)
+ self._save_toplevel_by_name(module_name, name)
+ for attrname in dotted_path:
+ save(attrname)
+ if self.proto < 2:
+ write(TUPLE)
+ else:
+ write(TUPLE2)
+ write(REDUCE)
+ else:
+ self._save_toplevel_by_name(module_name, name)
+
+ self.memoize(obj)
+
+ def _save_toplevel_by_name(self, module_name, name):
+ if self.proto >= 3:
+ # Non-ASCII identifiers are supported only with protocols >= 3.
+ self.write(GLOBAL + bytes(module_name, "utf-8") + b'\n' +
+ bytes(name, "utf-8") + b'\n')
else:
if self.fix_imports:
r_name_mapping = _compat_pickle.REVERSE_NAME_MAPPING
@@ -1102,14 +1147,12 @@ class _Pickler:
elif module_name in r_import_mapping:
module_name = r_import_mapping[module_name]
try:
- write(GLOBAL + bytes(module_name, "ascii") + b'\n' +
- bytes(name, "ascii") + b'\n')
+ self.write(GLOBAL + bytes(module_name, "ascii") + b'\n' +
+ bytes(name, "ascii") + b'\n')
except UnicodeEncodeError:
raise PicklingError(
"can't pickle global identifier '%s.%s' using "
- "pickle protocol %i" % (module, name, self.proto)) from None
-
- self.memoize(obj)
+ "pickle protocol %i" % (module_name, name, self.proto)) from None
def save_type(self, obj):
if obj is type(None):
diff --git a/contrib/tools/python3/Lib/pstats.py b/contrib/tools/python3/Lib/pstats.py
index 51bcca84188..f3611777dec 100644
--- a/contrib/tools/python3/Lib/pstats.py
+++ b/contrib/tools/python3/Lib/pstats.py
@@ -83,7 +83,7 @@ class Stats:
method now take arbitrarily many file names as arguments.
All the print methods now take an argument that indicates how many lines
- to print. If the arg is a floating point number between 0 and 1.0, then
+ to print. If the arg is a floating-point number between 0 and 1.0, then
it is taken as a decimal percentage of the available lines to be printed
(e.g., .1 means print 10% of all available lines). If it is an integer,
it is taken to mean the number of lines of data that you wish to have
diff --git a/contrib/tools/python3/Lib/pydoc.py b/contrib/tools/python3/Lib/pydoc.py
index 9a8812392af..e3745e5453b 100755
--- a/contrib/tools/python3/Lib/pydoc.py
+++ b/contrib/tools/python3/Lib/pydoc.py
@@ -2148,7 +2148,7 @@ has the same effect as typing a particular string at the help> prompt.
elif request in self.symbols: self.showsymbol(request)
elif request in ['True', 'False', 'None']:
# special case these keywords since they are objects too
- doc(eval(request), 'Help on %s:', is_cli=is_cli)
+ doc(eval(request), 'Help on %s:', output=self._output, is_cli=is_cli)
elif request in self.keywords: self.showtopic(request)
elif request in self.topics: self.showtopic(request)
elif request: doc(request, 'Help on %s:', output=self._output, is_cli=is_cli)
@@ -2241,7 +2241,11 @@ module "pydoc_data.topics" could not be found.
text = 'Related help topics: ' + ', '.join(xrefs.split()) + '\n'
wrapped_text = textwrap.wrap(text, 72)
doc += '\n%s\n' % '\n'.join(wrapped_text)
- pager(doc)
+
+ if self._output is None:
+ pager(doc)
+ else:
+ self.output.write(doc)
def _gettopic(self, topic, more_xrefs=''):
"""Return unbuffered tuple of (topic, xrefs).
diff --git a/contrib/tools/python3/Lib/pydoc_data/topics.py b/contrib/tools/python3/Lib/pydoc_data/topics.py
index e9e6337cbed..33b5834b863 100644
--- a/contrib/tools/python3/Lib/pydoc_data/topics.py
+++ b/contrib/tools/python3/Lib/pydoc_data/topics.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Autogenerated by Sphinx on Thu Jun 6 20:20:21 2024
+# Autogenerated by Sphinx on Tue Aug 6 21:02:50 2024
# as part of the release process.
topics = {'assert': 'The "assert" statement\n'
'**********************\n'
@@ -308,10 +308,10 @@ topics = {'assert': 'The "assert" statement\n'
'target.\n'
'The target is only evaluated once.\n'
'\n'
- 'An augmented assignment expression like "x += 1" can be '
- 'rewritten as\n'
- '"x = x + 1" to achieve a similar, but not exactly equal '
- 'effect. In the\n'
+ 'An augmented assignment statement like "x += 1" can be '
+ 'rewritten as "x\n'
+ '= x + 1" to achieve a similar, but not exactly equal effect. '
+ 'In the\n'
'augmented version, "x" is only evaluated once. Also, when '
'possible,\n'
'the actual operation is performed *in-place*, meaning that '
@@ -362,21 +362,26 @@ topics = {'assert': 'The "assert" statement\n'
'a single\n'
'target is allowed.\n'
'\n'
- 'For simple names as assignment targets, if in class or module '
- 'scope,\n'
- 'the annotations are evaluated and stored in a special class or '
- 'module\n'
- 'attribute "__annotations__" that is a dictionary mapping from '
- 'variable\n'
- 'names (mangled if private) to evaluated annotations. This '
- 'attribute is\n'
- 'writable and is automatically created at the start of class or '
- 'module\n'
- 'body execution, if annotations are found statically.\n'
- '\n'
- 'For expressions as assignment targets, the annotations are '
+ 'The assignment target is considered “simple” if it consists of '
+ 'a\n'
+ 'single name that is not enclosed in parentheses. For simple '
+ 'assignment\n'
+ 'targets, if in class or module scope, the annotations are '
'evaluated\n'
- 'if in class or module scope, but not stored.\n'
+ 'and stored in a special class or module attribute '
+ '"__annotations__"\n'
+ 'that is a dictionary mapping from variable names (mangled if '
+ 'private)\n'
+ 'to evaluated annotations. This attribute is writable and is\n'
+ 'automatically created at the start of class or module body '
+ 'execution,\n'
+ 'if annotations are found statically.\n'
+ '\n'
+ 'If the assignment target is not simple (an attribute, '
+ 'subscript node,\n'
+ 'or parenthesized name), the annotation is evaluated if in '
+ 'class or\n'
+ 'module scope, but not stored.\n'
'\n'
'If a name is annotated in a function scope, then this name is '
'local\n'
@@ -555,31 +560,67 @@ topics = {'assert': 'The "assert" statement\n'
'evaluate it\n'
'raises a "NameError" exception.\n'
'\n'
- '**Private name mangling:** When an identifier that '
- 'textually occurs in\n'
- 'a class definition begins with two or more underscore '
- 'characters and\n'
- 'does not end in two or more underscores, it is '
- 'considered a *private\n'
- 'name* of that class. Private names are transformed to a '
- 'longer form\n'
- 'before code is generated for them. The transformation '
- 'inserts the\n'
- 'class name, with leading underscores removed and a '
- 'single underscore\n'
- 'inserted, in front of the name. For example, the '
- 'identifier "__spam"\n'
- 'occurring in a class named "Ham" will be transformed to '
- '"_Ham__spam".\n'
- 'This transformation is independent of the syntactical '
+ '\n'
+ 'Private name mangling\n'
+ '=====================\n'
+ '\n'
+ 'When an identifier that textually occurs in a class '
+ 'definition begins\n'
+ 'with two or more underscore characters and does not end '
+ 'in two or more\n'
+ 'underscores, it is considered a *private name* of that '
+ 'class.\n'
+ '\n'
+ 'See also: The class specifications.\n'
+ '\n'
+ 'More precisely, private names are transformed to a '
+ 'longer form before\n'
+ 'code is generated for them. If the transformed name is '
+ 'longer than\n'
+ '255 characters, implementation-defined truncation may '
+ 'happen.\n'
+ '\n'
+ 'The transformation is independent of the syntactical '
'context in which\n'
- 'the identifier is used. If the transformed name is '
- 'extremely long\n'
- '(longer than 255 characters), implementation defined '
- 'truncation may\n'
- 'happen. If the class name consists only of underscores, '
- 'no\n'
- 'transformation is done.\n',
+ 'the identifier is used but only the following private '
+ 'identifiers are\n'
+ 'mangled:\n'
+ '\n'
+ '* Any name used as the name of a variable that is '
+ 'assigned or read or\n'
+ ' any name of an attribute being accessed.\n'
+ '\n'
+ ' The "__name__" attribute of nested functions, classes, '
+ 'and type\n'
+ ' aliases is however not mangled.\n'
+ '\n'
+ '* The name of imported modules, e.g., "__spam" in '
+ '"import __spam". If\n'
+ ' the module is part of a package (i.e., its name '
+ 'contains a dot), the\n'
+ ' name is *not* mangled, e.g., the "__foo" in "import '
+ '__foo.bar" is\n'
+ ' not mangled.\n'
+ '\n'
+ '* The name of an imported member, e.g., "__f" in "from '
+ 'spam import\n'
+ ' __f".\n'
+ '\n'
+ 'The transformation rule is defined as follows:\n'
+ '\n'
+ '* The class name, with leading underscores removed and a '
+ 'single\n'
+ ' leading underscore inserted, is inserted in front of '
+ 'the identifier,\n'
+ ' e.g., the identifier "__spam" occurring in a class '
+ 'named "Foo",\n'
+ ' "_Foo" or "__Foo" is transformed to "_Foo__spam".\n'
+ '\n'
+ '* If the class name consists only of underscores, the '
+ 'transformation\n'
+ ' is the identity, e.g., the identifier "__spam" '
+ 'occurring in a class\n'
+ ' named "_" or "__" is left as is.\n',
'atom-literals': 'Literals\n'
'********\n'
'\n'
@@ -592,10 +633,10 @@ topics = {'assert': 'The "assert" statement\n'
'\n'
'Evaluation of a literal yields an object of the given type '
'(string,\n'
- 'bytes, integer, floating point number, complex number) with '
+ 'bytes, integer, floating-point number, complex number) with '
'the given\n'
'value. The value may be approximated in the case of '
- 'floating point\n'
+ 'floating-point\n'
'and imaginary (complex) literals. See section Literals for '
'details.\n'
'\n'
@@ -1163,10 +1204,10 @@ topics = {'assert': 'The "assert" statement\n'
'target.\n'
'The target is only evaluated once.\n'
'\n'
- 'An augmented assignment expression like "x += 1" can be '
- 'rewritten as\n'
- '"x = x + 1" to achieve a similar, but not exactly equal effect. '
- 'In the\n'
+ 'An augmented assignment statement like "x += 1" can be '
+ 'rewritten as "x\n'
+ '= x + 1" to achieve a similar, but not exactly equal effect. In '
+ 'the\n'
'augmented version, "x" is only evaluated once. Also, when '
'possible,\n'
'the actual operation is performed *in-place*, meaning that '
@@ -1239,6 +1280,10 @@ topics = {'assert': 'The "assert" statement\n'
'The "@" (at) operator is intended to be used for matrix\n'
'multiplication. No builtin Python types implement this operator.\n'
'\n'
+ 'This operation can be customized using the special "__matmul__()" '
+ 'and\n'
+ '"__rmatmul__()" methods.\n'
+ '\n'
'Added in version 3.5.\n'
'\n'
'The "/" (division) and "//" (floor division) operators yield the\n'
@@ -1251,17 +1296,19 @@ topics = {'assert': 'The "assert" statement\n'
'result. Division by zero raises the "ZeroDivisionError" '
'exception.\n'
'\n'
- 'This operation can be customized using the special "__truediv__()" '
+ 'The division operation can be customized using the special\n'
+ '"__truediv__()" and "__rtruediv__()" methods. The floor division\n'
+ 'operation can be customized using the special "__floordiv__()" '
'and\n'
- '"__floordiv__()" methods.\n'
+ '"__rfloordiv__()" methods.\n'
'\n'
'The "%" (modulo) operator yields the remainder from the division '
'of\n'
'the first argument by the second. The numeric arguments are '
'first\n'
'converted to a common type. A zero right argument raises the\n'
- '"ZeroDivisionError" exception. The arguments may be floating '
- 'point\n'
+ '"ZeroDivisionError" exception. The arguments may be '
+ 'floating-point\n'
'numbers, e.g., "3.14%0.7" equals "0.34" (since "3.14" equals '
'"4*0.7 +\n'
'0.34".) The modulo operator always yields a result with the same '
@@ -1288,13 +1335,13 @@ topics = {'assert': 'The "assert" statement\n'
'\n'
'The *modulo* operation can be customized using the special '
'"__mod__()"\n'
- 'method.\n'
+ 'and "__rmod__()" methods.\n'
'\n'
'The floor division operator, the modulo operator, and the '
'"divmod()"\n'
'function are not defined for complex numbers. Instead, convert to '
'a\n'
- 'floating point number using the "abs()" function if appropriate.\n'
+ 'floating-point number using the "abs()" function if appropriate.\n'
'\n'
'The "+" (addition) operator yields the sum of its arguments. The\n'
'arguments must either both be numbers or both be sequences of the '
@@ -1313,7 +1360,8 @@ topics = {'assert': 'The "assert" statement\n'
'The numeric arguments are first converted to a common type.\n'
'\n'
'This operation can be customized using the special "__sub__()" '
- 'method.\n',
+ 'and\n'
+ '"__rsub__()" methods.\n',
'bitwise': 'Binary bitwise operations\n'
'*************************\n'
'\n'
@@ -2388,18 +2436,16 @@ topics = {'assert': 'The "assert" statement\n'
'An\n'
'expression-less "except" clause, if present, must be last; it '
'matches\n'
- 'any exception. For an "except" clause with an expression, that\n'
- 'expression is evaluated, and the clause matches the exception if '
- 'the\n'
- 'resulting object is “compatible” with the exception. An object '
- 'is\n'
- 'compatible with an exception if the object is the class or a '
- '*non-\n'
- 'virtual base class* of the exception object, or a tuple '
- 'containing an\n'
- 'item that is the class or a non-virtual base class of the '
- 'exception\n'
- 'object.\n'
+ 'any exception.\n'
+ '\n'
+ 'For an "except" clause with an expression, the expression must\n'
+ 'evaluate to an exception type or a tuple of exception types. '
+ 'The\n'
+ 'raised exception matches an "except" clause whose expression '
+ 'evaluates\n'
+ 'to the class or a *non-virtual base class* of the exception '
+ 'object, or\n'
+ 'to a tuple that contains such a class.\n'
'\n'
'If no "except" clause matches the exception, the search for an\n'
'exception handler continues in the surrounding code and on the\n'
@@ -2548,13 +2594,16 @@ topics = {'assert': 'The "assert" statement\n'
' ...\n'
" ExceptionGroup('', (BlockingIOError()))\n"
'\n'
- 'An "except*" clause must have a matching type, and this type '
- 'cannot be\n'
- 'a subclass of "BaseExceptionGroup". It is not possible to mix '
- '"except"\n'
- 'and "except*" in the same "try". "break", "continue" and '
- '"return"\n'
- 'cannot appear in an "except*" clause.\n'
+ 'An "except*" clause must have a matching expression; it cannot '
+ 'be\n'
+ '"except*:". Furthermore, this expression cannot contain '
+ 'exception\n'
+ 'group types, because that would have ambiguous semantics.\n'
+ '\n'
+ 'It is not possible to mix "except" and "except*" in the same '
+ '"try".\n'
+ '"break", "continue" and "return" cannot appear in an "except*" '
+ 'clause.\n'
'\n'
'\n'
'"else" clause\n'
@@ -4400,7 +4449,7 @@ topics = {'assert': 'The "assert" statement\n'
'converted to\n'
' complex;\n'
'\n'
- '* otherwise, if either argument is a floating point number, '
+ '* otherwise, if either argument is a floating-point number, '
'the other\n'
' is converted to floating point;\n'
'\n'
@@ -4511,6 +4560,10 @@ topics = {'assert': 'The "assert" statement\n'
' It is not guaranteed that "__del__()" methods are called '
'for\n'
' objects that still exist when the interpreter exits.\n'
+ ' "weakref.finalize" provides a straightforward way to '
+ 'register a\n'
+ ' cleanup function to be called when an object is garbage '
+ 'collected.\n'
'\n'
' Note:\n'
'\n'
@@ -6413,10 +6466,10 @@ topics = {'assert': 'The "assert" statement\n'
'that expression. (To create an empty tuple, use an empty pair '
'of\n'
'parentheses: "()".)\n',
- 'floating': 'Floating point literals\n'
+ 'floating': 'Floating-point literals\n'
'***********************\n'
'\n'
- 'Floating point literals are described by the following lexical\n'
+ 'Floating-point literals are described by the following lexical\n'
'definitions:\n'
'\n'
' floatnumber ::= pointfloat | exponentfloat\n'
@@ -6430,12 +6483,12 @@ topics = {'assert': 'The "assert" statement\n'
'using\n'
'radix 10. For example, "077e010" is legal, and denotes the same '
'number\n'
- 'as "77e10". The allowed range of floating point literals is\n'
+ 'as "77e10". The allowed range of floating-point literals is\n'
'implementation-dependent. As in integer literals, underscores '
'are\n'
'supported for digit grouping.\n'
'\n'
- 'Some examples of floating point literals:\n'
+ 'Some examples of floating-point literals:\n'
'\n'
' 3.14 10. .001 1e100 3.14e-10 0e0 '
'3.14_15_93\n'
@@ -6818,7 +6871,7 @@ topics = {'assert': 'The "assert" statement\n'
'\n'
'The "\'_\'" option signals the use of an underscore for a '
'thousands\n'
- 'separator for floating point presentation types and for '
+ 'separator for floating-point presentation types and for '
'integer\n'
'presentation type "\'d\'". For integer presentation types '
'"\'b\'", "\'o\'",\n'
@@ -6945,11 +6998,11 @@ topics = {'assert': 'The "assert" statement\n'
'\n'
'In addition to the above presentation types, integers can '
'be formatted\n'
- 'with the floating point presentation types listed below '
+ 'with the floating-point presentation types listed below '
'(except "\'n\'"\n'
'and "None"). When doing so, "float()" is used to convert '
'the integer\n'
- 'to a floating point number before formatting.\n'
+ 'to a floating-point number before formatting.\n'
'\n'
'The available presentation types for "float" and "Decimal" '
'values are:\n'
@@ -7807,11 +7860,11 @@ topics = {'assert': 'The "assert" statement\n'
'\n'
'An imaginary literal yields a complex number with a real part '
'of 0.0.\n'
- 'Complex numbers are represented as a pair of floating point '
+ 'Complex numbers are represented as a pair of floating-point '
'numbers\n'
'and have the same restrictions on their range. To create a '
'complex\n'
- 'number with a nonzero real part, add a floating point number to '
+ 'number with a nonzero real part, add a floating-point number to '
'it,\n'
'e.g., "(3+4j)". Some examples of imaginary literals:\n'
'\n'
@@ -8605,8 +8658,8 @@ topics = {'assert': 'The "assert" statement\n'
'numbers': 'Numeric literals\n'
'****************\n'
'\n'
- 'There are three types of numeric literals: integers, floating '
- 'point\n'
+ 'There are three types of numeric literals: integers, '
+ 'floating-point\n'
'numbers, and imaginary numbers. There are no complex literals\n'
'(complex numbers can be formed by adding a real number and an\n'
'imaginary number).\n'
@@ -9176,8 +9229,8 @@ topics = {'assert': 'The "assert" statement\n'
'"complex"\n'
'number. (In earlier versions it raised a "ValueError".)\n'
'\n'
- 'This operation can be customized using the special "__pow__()" '
- 'method.\n',
+ 'This operation can be customized using the special "__pow__()" and\n'
+ '"__rpow__()" methods.\n',
'raise': 'The "raise" statement\n'
'*********************\n'
'\n'
@@ -9591,9 +9644,12 @@ topics = {'assert': 'The "assert" statement\n'
'the\n'
'second argument.\n'
'\n'
- 'This operation can be customized using the special '
- '"__lshift__()" and\n'
- '"__rshift__()" methods.\n'
+ 'The left shift operation can be customized using the special\n'
+ '"__lshift__()" and "__rlshift__()" methods. The right shift '
+ 'operation\n'
+ 'can be customized using the special "__rshift__()" and '
+ '"__rrshift__()"\n'
+ 'methods.\n'
'\n'
'A right shift by *n* bits is defined as floor division by '
'"pow(2,n)".\n'
@@ -9863,6 +9919,10 @@ topics = {'assert': 'The "assert" statement\n'
' It is not guaranteed that "__del__()" methods are called '
'for\n'
' objects that still exist when the interpreter exits.\n'
+ ' "weakref.finalize" provides a straightforward way to '
+ 'register a\n'
+ ' cleanup function to be called when an object is garbage '
+ 'collected.\n'
'\n'
' Note:\n'
'\n'
@@ -12657,11 +12717,11 @@ topics = {'assert': 'The "assert" statement\n'
' and are deemed to delimit empty strings (for example,\n'
' "\'1,,2\'.split(\',\')" returns "[\'1\', \'\', '
'\'2\']"). The *sep* argument\n'
- ' may consist of multiple characters (for example,\n'
- ' "\'1<>2<>3\'.split(\'<>\')" returns "[\'1\', \'2\', '
- '\'3\']"). Splitting an\n'
- ' empty string with a specified separator returns '
- '"[\'\']".\n'
+ ' may consist of multiple characters as a single '
+ 'delimiter (to split\n'
+ ' with multiple delimiters, use "re.split()"). Splitting '
+ 'an empty\n'
+ ' string with a specified separator returns "[\'\']".\n'
'\n'
' For example:\n'
'\n'
@@ -12671,6 +12731,8 @@ topics = {'assert': 'The "assert" statement\n'
" ['1', '2,3']\n"
" >>> '1,2,,3,'.split(',')\n"
" ['1', '2', '', '3', '']\n"
+ " >>> '1<>2<>3<4'.split('<>')\n"
+ " ['1', '2', '3<4']\n"
'\n'
' If *sep* is not specified or is "None", a different '
'splitting\n'
@@ -13351,14 +13413,15 @@ topics = {'assert': 'The "assert" statement\n'
'clauses in turn until one is found that matches the exception. An\n'
'expression-less "except" clause, if present, must be last; it '
'matches\n'
- 'any exception. For an "except" clause with an expression, that\n'
- 'expression is evaluated, and the clause matches the exception if the\n'
- 'resulting object is “compatible” with the exception. An object is\n'
- 'compatible with an exception if the object is the class or a *non-\n'
- 'virtual base class* of the exception object, or a tuple containing '
- 'an\n'
- 'item that is the class or a non-virtual base class of the exception\n'
- 'object.\n'
+ 'any exception.\n'
+ '\n'
+ 'For an "except" clause with an expression, the expression must\n'
+ 'evaluate to an exception type or a tuple of exception types. The\n'
+ 'raised exception matches an "except" clause whose expression '
+ 'evaluates\n'
+ 'to the class or a *non-virtual base class* of the exception object, '
+ 'or\n'
+ 'to a tuple that contains such a class.\n'
'\n'
'If no "except" clause matches the exception, the search for an\n'
'exception handler continues in the surrounding code and on the\n'
@@ -13487,12 +13550,13 @@ topics = {'assert': 'The "assert" statement\n'
' ...\n'
" ExceptionGroup('', (BlockingIOError()))\n"
'\n'
- 'An "except*" clause must have a matching type, and this type cannot '
- 'be\n'
- 'a subclass of "BaseExceptionGroup". It is not possible to mix '
- '"except"\n'
- 'and "except*" in the same "try". "break", "continue" and "return"\n'
- 'cannot appear in an "except*" clause.\n'
+ 'An "except*" clause must have a matching expression; it cannot be\n'
+ '"except*:". Furthermore, this expression cannot contain exception\n'
+ 'group types, because that would have ambiguous semantics.\n'
+ '\n'
+ 'It is not possible to mix "except" and "except*" in the same "try".\n'
+ '"break", "continue" and "return" cannot appear in an "except*" '
+ 'clause.\n'
'\n'
'\n'
'"else" clause\n'
@@ -13653,7 +13717,7 @@ topics = {'assert': 'The "assert" statement\n'
'\n'
'* A sign is shown only when the number is negative.\n'
'\n'
- 'Python distinguishes between integers, floating point numbers, and\n'
+ 'Python distinguishes between integers, floating-point numbers, and\n'
'complex numbers:\n'
'\n'
'\n'
@@ -13698,28 +13762,28 @@ topics = {'assert': 'The "assert" statement\n'
'"numbers.Real" ("float")\n'
'------------------------\n'
'\n'
- 'These represent machine-level double precision floating point '
+ 'These represent machine-level double precision floating-point '
'numbers.\n'
'You are at the mercy of the underlying machine architecture (and C '
'or\n'
'Java implementation) for the accepted range and handling of '
'overflow.\n'
- 'Python does not support single-precision floating point numbers; '
+ 'Python does not support single-precision floating-point numbers; '
'the\n'
'savings in processor and memory usage that are usually the reason '
'for\n'
'using these are dwarfed by the overhead of using objects in Python, '
'so\n'
'there is no reason to complicate the language with two kinds of\n'
- 'floating point numbers.\n'
+ 'floating-point numbers.\n'
'\n'
'\n'
'"numbers.Complex" ("complex")\n'
'-----------------------------\n'
'\n'
'These represent complex numbers as a pair of machine-level double\n'
- 'precision floating point numbers. The same caveats apply as for\n'
- 'floating point numbers. The real and imaginary parts of a complex\n'
+ 'precision floating-point numbers. The same caveats apply as for\n'
+ 'floating-point numbers. The real and imaginary parts of a complex\n'
'number "z" can be retrieved through the read-only attributes '
'"z.real"\n'
'and "z.imag".\n'
@@ -14134,21 +14198,10 @@ topics = {'assert': 'The "assert" statement\n'
'to\n'
'calling "f(C,1)" where "f" is the underlying function.\n'
'\n'
- 'Note that the transformation from function object to instance '
- 'method\n'
- 'object happens each time the attribute is retrieved from the '
- 'instance.\n'
- 'In some cases, a fruitful optimization is to assign the attribute '
- 'to a\n'
- 'local variable and call that local variable. Also notice that this\n'
- 'transformation only happens for user-defined functions; other '
- 'callable\n'
- 'objects (and all non-callable objects) are retrieved without\n'
- 'transformation. It is also important to note that user-defined\n'
- 'functions which are attributes of a class instance are not '
- 'converted\n'
- 'to bound methods; this *only* happens when the function is an\n'
- 'attribute of the class.\n'
+ 'It is important to note that user-defined functions which are\n'
+ 'attributes of a class instance are not converted to bound methods;\n'
+ 'this *only* happens when the function is an attribute of the '
+ 'class.\n'
'\n'
'\n'
'Generator functions\n'
@@ -15155,7 +15208,7 @@ topics = {'assert': 'The "assert" statement\n'
'\n'
' Return a shallow copy of the dictionary.\n'
'\n'
- ' classmethod fromkeys(iterable, value=None)\n'
+ ' classmethod fromkeys(iterable, value=None, /)\n'
'\n'
' Create a new dictionary with keys from *iterable* and '
'values set\n'
@@ -15923,7 +15976,9 @@ topics = {'assert': 'The "assert" statement\n'
'\n'
'Notes:\n'
'\n'
- '1. *t* must have the same length as the slice it is replacing.\n'
+ '1. If *k* is not equal to "1", *t* must have the same length as '
+ 'the\n'
+ ' slice it is replacing.\n'
'\n'
'2. The optional argument *i* defaults to "-1", so that by '
'default the\n'
@@ -16280,7 +16335,7 @@ topics = {'assert': 'The "assert" statement\n'
'\n'
' * The linspace recipe shows how to implement a lazy version of '
'range\n'
- ' suitable for floating point applications.\n',
+ ' suitable for floating-point applications.\n',
'typesseq-mutable': 'Mutable Sequence Types\n'
'**********************\n'
'\n'
@@ -16387,8 +16442,9 @@ topics = {'assert': 'The "assert" statement\n'
'\n'
'Notes:\n'
'\n'
- '1. *t* must have the same length as the slice it is '
- 'replacing.\n'
+ '1. If *k* is not equal to "1", *t* must have the same '
+ 'length as the\n'
+ ' slice it is replacing.\n'
'\n'
'2. The optional argument *i* defaults to "-1", so that '
'by default the\n'
diff --git a/contrib/tools/python3/Lib/re/_casefix.py b/contrib/tools/python3/Lib/re/_casefix.py
index 06507d08bee..fed2d84fc01 100644
--- a/contrib/tools/python3/Lib/re/_casefix.py
+++ b/contrib/tools/python3/Lib/re/_casefix.py
@@ -1,4 +1,4 @@
-# Auto-generated by Tools/scripts/generate_re_casefix.py.
+# Auto-generated by Tools/build/generate_re_casefix.py.
# Maps the code of lowercased character to codes of different lowercased
# characters which have the same uppercase.
diff --git a/contrib/tools/python3/Lib/sched.py b/contrib/tools/python3/Lib/sched.py
index 14613cf2987..fb20639d459 100644
--- a/contrib/tools/python3/Lib/sched.py
+++ b/contrib/tools/python3/Lib/sched.py
@@ -11,7 +11,7 @@ substituting time and sleep from built-in module time, or you can
implement simulated time by writing your own functions. This can
also be used to integrate scheduling with STDWIN events; the delay
function is allowed to modify the queue. Time can be expressed as
-integers or floating point numbers, as long as it is consistent.
+integers or floating-point numbers, as long as it is consistent.
Events are specified by tuples (time, priority, action, argument, kwargs).
As in UNIX, lower priority numbers mean higher priority; in this
diff --git a/contrib/tools/python3/Lib/socket.py b/contrib/tools/python3/Lib/socket.py
index d796082e054..c1880c4ea51 100644
--- a/contrib/tools/python3/Lib/socket.py
+++ b/contrib/tools/python3/Lib/socket.py
@@ -592,16 +592,65 @@ if hasattr(_socket.socket, "share"):
return socket(0, 0, 0, info)
__all__.append("fromshare")
-if hasattr(_socket, "socketpair"):
+# Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
+# This is used if _socket doesn't natively provide socketpair. It's
+# always defined so that it can be patched in for testing purposes.
+def _fallback_socketpair(family=AF_INET, type=SOCK_STREAM, proto=0):
+ if family == AF_INET:
+ host = _LOCALHOST
+ elif family == AF_INET6:
+ host = _LOCALHOST_V6
+ else:
+ raise ValueError("Only AF_INET and AF_INET6 socket address families "
+ "are supported")
+ if type != SOCK_STREAM:
+ raise ValueError("Only SOCK_STREAM socket type is supported")
+ if proto != 0:
+ raise ValueError("Only protocol zero is supported")
+
+ # We create a connected TCP socket. Note the trick with
+ # setblocking(False) that prevents us from having to create a thread.
+ lsock = socket(family, type, proto)
+ try:
+ lsock.bind((host, 0))
+ lsock.listen()
+ # On IPv6, ignore flow_info and scope_id
+ addr, port = lsock.getsockname()[:2]
+ csock = socket(family, type, proto)
+ try:
+ csock.setblocking(False)
+ try:
+ csock.connect((addr, port))
+ except (BlockingIOError, InterruptedError):
+ pass
+ csock.setblocking(True)
+ ssock, _ = lsock.accept()
+ except:
+ csock.close()
+ raise
+ finally:
+ lsock.close()
- def socketpair(family=None, type=SOCK_STREAM, proto=0):
- """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
+ # Authenticating avoids using a connection from something else
+ # able to connect to {host}:{port} instead of us.
+ # We expect only AF_INET and AF_INET6 families.
+ try:
+ if (
+ ssock.getsockname() != csock.getpeername()
+ or csock.getsockname() != ssock.getpeername()
+ ):
+ raise ConnectionError("Unexpected peer connection")
+ except:
+ # getsockname() and getpeername() can fail
+ # if either socket isn't connected.
+ ssock.close()
+ csock.close()
+ raise
- Create a pair of socket objects from the sockets returned by the platform
- socketpair() function.
- The arguments are the same as for socket() except the default family is
- AF_UNIX if defined on the platform; otherwise, the default is AF_INET.
- """
+ return (ssock, csock)
+
+if hasattr(_socket, "socketpair"):
+ def socketpair(family=None, type=SOCK_STREAM, proto=0):
if family is None:
try:
family = AF_UNIX
@@ -613,44 +662,7 @@ if hasattr(_socket, "socketpair"):
return a, b
else:
-
- # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
- def socketpair(family=AF_INET, type=SOCK_STREAM, proto=0):
- if family == AF_INET:
- host = _LOCALHOST
- elif family == AF_INET6:
- host = _LOCALHOST_V6
- else:
- raise ValueError("Only AF_INET and AF_INET6 socket address families "
- "are supported")
- if type != SOCK_STREAM:
- raise ValueError("Only SOCK_STREAM socket type is supported")
- if proto != 0:
- raise ValueError("Only protocol zero is supported")
-
- # We create a connected TCP socket. Note the trick with
- # setblocking(False) that prevents us from having to create a thread.
- lsock = socket(family, type, proto)
- try:
- lsock.bind((host, 0))
- lsock.listen()
- # On IPv6, ignore flow_info and scope_id
- addr, port = lsock.getsockname()[:2]
- csock = socket(family, type, proto)
- try:
- csock.setblocking(False)
- try:
- csock.connect((addr, port))
- except (BlockingIOError, InterruptedError):
- pass
- csock.setblocking(True)
- ssock, _ = lsock.accept()
- except:
- csock.close()
- raise
- finally:
- lsock.close()
- return (ssock, csock)
+ socketpair = _fallback_socketpair
__all__.append("socketpair")
socketpair.__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
diff --git a/contrib/tools/python3/Lib/statistics.py b/contrib/tools/python3/Lib/statistics.py
index 6bd214bbfe2..db108b3e2c8 100644
--- a/contrib/tools/python3/Lib/statistics.py
+++ b/contrib/tools/python3/Lib/statistics.py
@@ -11,7 +11,7 @@ Calculating averages
Function Description
================== ==================================================
mean Arithmetic mean (average) of data.
-fmean Fast, floating point arithmetic mean.
+fmean Fast, floating-point arithmetic mean.
geometric_mean Geometric mean of data.
harmonic_mean Harmonic mean of data.
median Median (middle value) of data.
diff --git a/contrib/tools/python3/Lib/symtable.py b/contrib/tools/python3/Lib/symtable.py
index 4b0bc6f497a..f95639bee3a 100644
--- a/contrib/tools/python3/Lib/symtable.py
+++ b/contrib/tools/python3/Lib/symtable.py
@@ -217,8 +217,37 @@ class Class(SymbolTable):
"""
if self.__methods is None:
d = {}
+
+ def is_local_symbol(ident):
+ flags = self._table.symbols.get(ident, 0)
+ return ((flags >> SCOPE_OFF) & SCOPE_MASK) == LOCAL
+
for st in self._table.children:
- d[st.name] = 1
+ # pick the function-like symbols that are local identifiers
+ if is_local_symbol(st.name):
+ match st.type:
+ case _symtable.TYPE_FUNCTION:
+ # generators are of type TYPE_FUNCTION with a ".0"
+ # parameter as a first parameter (which makes them
+ # distinguishable from a function named 'genexpr')
+ if st.name == 'genexpr' and '.0' in st.varnames:
+ continue
+ d[st.name] = 1
+ case _symtable.TYPE_TYPE_PARAM:
+ # Get the function-def block in the annotation
+ # scope 'st' with the same identifier, if any.
+ scope_name = st.name
+ for c in st.children:
+ if c.name == scope_name and c.type == _symtable.TYPE_FUNCTION:
+ # A generic generator of type TYPE_FUNCTION
+ # cannot be a direct child of 'st' (but it
+ # can be a descendant), e.g.:
+ #
+ # class A:
+ # type genexpr[genexpr] = (x for x in [])
+ assert scope_name != 'genexpr' or '.0' not in c.varnames
+ d[scope_name] = 1
+ break
self.__methods = tuple(d)
return self.__methods
diff --git a/contrib/tools/python3/Lib/tabnanny.py b/contrib/tools/python3/Lib/tabnanny.py
index e2ac6837f15..d06c4c221e9 100755
--- a/contrib/tools/python3/Lib/tabnanny.py
+++ b/contrib/tools/python3/Lib/tabnanny.py
@@ -107,14 +107,14 @@ def check(file):
errprint("%r: Token Error: %s" % (file, msg))
return
- except SyntaxError as msg:
- errprint("%r: Token Error: %s" % (file, msg))
- return
-
except IndentationError as msg:
errprint("%r: Indentation Error: %s" % (file, msg))
return
+ except SyntaxError as msg:
+ errprint("%r: Syntax Error: %s" % (file, msg))
+ return
+
except NannyNag as nag:
badline = nag.get_lineno()
line = nag.get_line()
diff --git a/contrib/tools/python3/Lib/threading.py b/contrib/tools/python3/Lib/threading.py
index 98cb43c6972..0bba85d08a0 100644
--- a/contrib/tools/python3/Lib/threading.py
+++ b/contrib/tools/python3/Lib/threading.py
@@ -332,7 +332,7 @@ class Condition:
awakened or timed out, it re-acquires the lock and returns.
When the timeout argument is present and not None, it should be a
- floating point number specifying a timeout for the operation in seconds
+ floating-point number specifying a timeout for the operation in seconds
(or fractions thereof).
When the underlying lock is an RLock, it is not released using its
@@ -642,7 +642,7 @@ class Event:
the optional timeout occurs.
When the timeout argument is present and not None, it should be a
- floating point number specifying a timeout for the operation in seconds
+ floating-point number specifying a timeout for the operation in seconds
(or fractions thereof).
This method returns the internal flag on exit, so it will always return
@@ -685,6 +685,8 @@ class Barrier:
default for all subsequent 'wait()' calls.
"""
+ if parties < 1:
+ raise ValueError("parties must be > 0")
self._cond = Condition(Lock())
self._action = action
self._timeout = timeout
@@ -1120,7 +1122,7 @@ class Thread:
or until the optional timeout occurs.
When the timeout argument is present and not None, it should be a
- floating point number specifying a timeout for the operation in seconds
+ floating-point number specifying a timeout for the operation in seconds
(or fractions thereof). As join() always returns None, you must call
is_alive() after join() to decide whether a timeout happened -- if the
thread is still alive, the join() call timed out.
diff --git a/contrib/tools/python3/Lib/typing.py b/contrib/tools/python3/Lib/typing.py
index 882dc4da58e..94c211292ec 100644
--- a/contrib/tools/python3/Lib/typing.py
+++ b/contrib/tools/python3/Lib/typing.py
@@ -927,15 +927,24 @@ class ForwardRef(_Final, _root=True):
globalns = getattr(
sys.modules.get(self.__forward_module__, None), '__dict__', globalns
)
+
+ # type parameters require some special handling,
+ # as they exist in their own scope
+ # but `eval()` does not have a dedicated parameter for that scope.
+ # For classes, names in type parameter scopes should override
+ # names in the global scope (which here are called `localns`!),
+ # but should in turn be overridden by names in the class scope
+ # (which here are called `globalns`!)
if type_params:
- # "Inject" type parameters into the local namespace
- # (unless they are shadowed by assignments *in* the local namespace),
- # as a way of emulating annotation scopes when calling `eval()`
- locals_to_pass = {param.__name__: param for param in type_params} | localns
- else:
- locals_to_pass = localns
+ globalns, localns = dict(globalns), dict(localns)
+ for param in type_params:
+ param_name = param.__name__
+ if not self.__forward_is_class__ or param_name not in globalns:
+ globalns[param_name] = param
+ localns.pop(param_name, None)
+
type_ = _type_check(
- eval(self.__forward_code__, globalns, locals_to_pass),
+ eval(self.__forward_code__, globalns, localns),
"Forward references must evaluate to types.",
is_argument=self.__forward_is_argument__,
allow_special_forms=self.__forward_is_class__,
diff --git a/contrib/tools/python3/Lib/unittest/mock.py b/contrib/tools/python3/Lib/unittest/mock.py
index 486e0c634b8..9398f56506b 100644
--- a/contrib/tools/python3/Lib/unittest/mock.py
+++ b/contrib/tools/python3/Lib/unittest/mock.py
@@ -800,6 +800,9 @@ class NonCallableMock(Base):
mock_name = f'{self._extract_mock_name()}.{name}'
raise AttributeError(f'Cannot set {mock_name}')
+ if isinstance(value, PropertyMock):
+ self.__dict__[name] = value
+ return
return object.__setattr__(self, name, value)
@@ -1478,13 +1481,12 @@ class _patch(object):
if isinstance(original, type):
# If we're patching out a class and there is a spec
inherit = True
- if spec is None and _is_async_obj(original):
- Klass = AsyncMock
- else:
- Klass = MagicMock
- _kwargs = {}
+
+ # Determine the Klass to use
if new_callable is not None:
Klass = new_callable
+ elif spec is None and _is_async_obj(original):
+ Klass = AsyncMock
elif spec is not None or spec_set is not None:
this_spec = spec
if spec_set is not None:
@@ -1497,7 +1499,12 @@ class _patch(object):
Klass = AsyncMock
elif not_callable:
Klass = NonCallableMagicMock
+ else:
+ Klass = MagicMock
+ else:
+ Klass = MagicMock
+ _kwargs = {}
if spec is not None:
_kwargs['spec'] = spec
if spec_set is not None:
@@ -2718,6 +2725,12 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
if not unsafe:
_check_spec_arg_typos(kwargs)
+ _name = kwargs.pop('name', _name)
+ _new_name = _name
+ if _parent is None:
+ # for a top level object no _new_name should be set
+ _new_name = ''
+
_kwargs.update(kwargs)
Klass = MagicMock
@@ -2735,13 +2748,6 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
elif is_type and instance and not _instance_callable(spec):
Klass = NonCallableMagicMock
- _name = _kwargs.pop('name', _name)
-
- _new_name = _name
- if _parent is None:
- # for a top level object no _new_name should be set
- _new_name = ''
-
mock = Klass(parent=_parent, _new_parent=_parent, _new_name=_new_name,
name=_name, **_kwargs)
diff --git a/contrib/tools/python3/Lib/xml/etree/ElementTree.py b/contrib/tools/python3/Lib/xml/etree/ElementTree.py
index fd2cc8704e1..c657b52d12b 100644
--- a/contrib/tools/python3/Lib/xml/etree/ElementTree.py
+++ b/contrib/tools/python3/Lib/xml/etree/ElementTree.py
@@ -201,7 +201,7 @@ class Element:
def __bool__(self):
warnings.warn(
- "Testing an element's truth value will raise an exception in "
+ "Testing an element's truth value will always return True in "
"future versions. "
"Use specific 'len(elem)' or 'elem is not None' test instead.",
DeprecationWarning, stacklevel=2
diff --git a/contrib/tools/python3/Lib/ya.make b/contrib/tools/python3/Lib/ya.make
index a21fe71ade8..d6607786ff6 100644
--- a/contrib/tools/python3/Lib/ya.make
+++ b/contrib/tools/python3/Lib/ya.make
@@ -4,9 +4,9 @@ ENABLE(PYBUILD_NO_PY)
PY3_LIBRARY()
-VERSION(3.12.4)
+VERSION(3.12.5)
-ORIGINAL_SOURCE(https://github.com/python/cpython/archive/v3.12.4.tar.gz)
+ORIGINAL_SOURCE(https://github.com/python/cpython/archive/v3.12.5.tar.gz)
LICENSE(Python-2.0)