Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions Doc/library/uuid.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ which relays any information about the UUID's safety, using this enumeration:

.. class:: UUID(hex=None, bytes=None, bytes_le=None, fields=None, int=None, version=None, *, is_safe=SafeUUID.unknown)

Create a UUID from either a string of 32 hexadecimal digits, a string of 16
bytes in big-endian order as the *bytes* argument, a string of 16 bytes in
little-endian order as the *bytes_le* argument, a tuple of six integers
Create a UUID from either a string of 32 hexadecimal digits, a 16-byte
:class:`bytes` object in big-endian order as the *bytes* argument, a
16-byte :class:`bytes` object in little-endian order as the *bytes_le*
argument, a tuple of six integers
(32-bit *time_low*, 16-bit *time_mid*, 16-bit *time_hi_version*,
8-bit *clock_seq_hi_variant*, 8-bit *clock_seq_low*, 48-bit *node*) as the
*fields* argument, or a single 128-bit integer as the *int* argument.
Expand Down Expand Up @@ -80,14 +81,14 @@ which relays any information about the UUID's safety, using this enumeration:

.. attribute:: UUID.bytes

The UUID as a 16-byte string (containing the six integer fields in big-endian
byte order).
The UUID as a 16-byte :class:`bytes` object (containing the six integer
fields in big-endian byte order).


.. attribute:: UUID.bytes_le

The UUID as a 16-byte string (with *time_low*, *time_mid*, and *time_hi_version*
in little-endian byte order).
The UUID as a 16-byte :class:`bytes` object (with *time_low*, *time_mid*,
and *time_hi_version* in little-endian byte order).


.. attribute:: UUID.fields
Expand Down Expand Up @@ -435,7 +436,7 @@ Here are some examples of typical usage of the :mod:`!uuid` module::
>>> x.bytes
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'

>>> # make a UUID from a 16-byte string
>>> # make a UUID from a 16-byte bytes object
>>> uuid.UUID(bytes=x.bytes)
UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')

Expand Down
2 changes: 1 addition & 1 deletion Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3555,7 +3555,7 @@ def inject_memory_error(start=0, stop=0):


@contextlib.contextmanager
def memory_error_cm(start=0, stop=0):
def inject_memory_error_cm(start=0, stop=0):
"""
Similar to inject_memory_error() but can be used as a context manager.

Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_bytes.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def __index__(self):
@contextlib.contextmanager
def inject_memory_error(testcase, start=0):
with testcase.assertRaises(MemoryError):
with support.memory_error_cm(start):
with support.inject_memory_error_cm(start):
yield


Expand Down
14 changes: 4 additions & 10 deletions Lib/test/test_capi/test_bytes.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,12 +511,9 @@ def test_resize_error(self):
writer = self.create_writer(len(init))
writer.write(0, init)
size = len(init) + 100
try:
with self.assertRaises(MemoryError):
_testcapi.set_nomemory(0)
with self.assertRaises(MemoryError):
with support.inject_memory_error_cm():
writer.resize(size)
finally:
_testcapi.remove_mem_hooks()
suffix = b'still working'
writer.write_bytes(suffix, -1)
self.assertEqual(writer.finish(), init + suffix)
Expand Down Expand Up @@ -590,12 +587,9 @@ def test_grow_error(self):
init = b'x' * self.LARGE_BUFFER
writer = self.create_writer(len(init))
writer.write(0, init)
try:
with self.assertRaises(MemoryError):
_testcapi.set_nomemory(0)
with self.assertRaises(MemoryError):
with support.inject_memory_error_cm():
writer.grow(100)
finally:
_testcapi.remove_mem_hooks()
suffix = b'still working'
writer.write_bytes(suffix, -1)
self.assertEqual(writer.finish(), init + suffix)
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,7 @@ def __init__(self):
d = a.__dict__
try:
with support.catch_unraisable_exception() as ex:
with support.memory_error_cm(n, n + 1):
with support.inject_memory_error_cm(n, n + 1):
del a
exc_type = ex.unraisable and ex.unraisable.exc_type
except MemoryError:
Expand Down
17 changes: 17 additions & 0 deletions Lib/test/test_external_inspection.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import unittest
import os
import textwrap
Expand Down Expand Up @@ -440,6 +441,22 @@ def _extract_coroutine_stacks_lineno_only(self, stack_trace):

@requires_remote_subprocess_debugging()
class TestSelfStackTrace(RemoteInspectionTestBase):
@skip_if_not_supported
def test_long_task_name_is_truncated(self):
# gh-157788
async def main():
asyncio.create_task(asyncio.sleep(10_000), name="x" * 300)
await asyncio.sleep(0)
return [
task.task_name
for info in RemoteUnwinder(os.getpid()).get_all_awaited_by()
for task in info.awaited_by
]

names = asyncio.run(main())
self.assertIn("Task-1", names)
self.assertEqual([len(n) for n in names if n.startswith("x")], [255])

@skip_if_not_supported
@unittest.skipIf(
sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,
Expand Down
28 changes: 28 additions & 0 deletions Lib/test/test_fstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,18 @@ def build_fstr(n, extra=''):
s = "f'{1}' 'x' 'y'" * 1024
self.assertEqual(eval(s), '1xy' * 1024)

@support.requires_resource('cpu')
def test_many_fstrings_in_module(self):
fields = ''.join(f'{{x{i}}}' for i in range(100))
source = ''.join(
f"value_{i} = f'{fields}'\n" for i in range(1_000)
)
namespace = {f'x{i}': str(i) for i in range(100)}
expected = ''.join(str(i) for i in range(100))
exec(source, namespace)
self.assertEqual(namespace['value_0'], expected)
self.assertEqual(namespace['value_999'], expected)

def test_format_specifier_expressions(self):
width = 10
precision = 4
Expand Down Expand Up @@ -1348,6 +1360,9 @@ def test_not_equal(self):
self.assertEqual(f'{3!=4:}', 'True')
self.assertEqual(f'{3!=4!s}', 'True')
self.assertEqual(f'{3!=4!s:.3}', 'Tru')
a = 3
b = 4
self.assertEqual(f'{a!=b=:>10}', 'a!=b= 1')

def test_equal_equal(self):
# Because an expression ending in = has special meaning,
Expand Down Expand Up @@ -1819,6 +1834,19 @@ def test_debug_in_file(self):
self.assertEqual(stdout.decode('utf-8').strip().replace('\r\n', '\n').replace('\r', '\n'),
"3\n=3")

def test_debug_in_file_after_buffer_resize(self):
expression = "(\n" + (" " * 64 + "\n") * 256 + "1\n)"
expected = expression + "=1"
with temp_cwd():
script = 'script.py'
source = (
f"result = f'''{{{expression}=}}'''\n"
f"assert result == {expected!r}\n"
)
with open(script, 'w') as f:
f.write(source)
assert_python_ok(script)

def test_syntax_warning_infinite_recursion_in_file(self):
with temp_cwd():
script = 'script.py'
Expand Down
10 changes: 2 additions & 8 deletions Lib/test/test_interpreters/test_stress.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,9 @@ def run():

@support.nomemtest
def test_create_interpreter_no_memory(self):
import _testcapi

assertion = self.assertRaises(InterpreterError)
try:
_testcapi.set_nomemory(0, 1)
with assertion:
with self.assertRaises(InterpreterError):
with support.inject_memory_error_cm(0, 1):
_interpreters.create()
finally:
_testcapi.remove_mem_hooks()


if __name__ == '__main__':
Expand Down
14 changes: 3 additions & 11 deletions Lib/test/test_io/test_memoryio.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import unittest
from test import support
from test.support import import_helper

import gc
import io
Expand Down Expand Up @@ -757,18 +756,14 @@ def __buffer__(self, flags):
@support.nomemtest
def test_memory_error(self):
# gh-157242: io.BytesIO() must not close the file on MemoryError
_testcapi = import_helper.import_module('_testcapi')

# write()
stream = self.ioclass()
stream.write(self.buftype('abc'))
data = self.buftype('def')
with self.assertRaises(MemoryError):
try:
data = self.buftype('def')
_testcapi.set_nomemory(0)
with support.inject_memory_error_cm():
stream.write(data)
finally:
_testcapi.remove_mem_hooks()
stream.write(self.buftype('123'))
self.assertEqual(stream.getvalue(), self.buftype('abc123'))

Expand All @@ -777,11 +772,8 @@ def test_memory_error(self):
stream = self.ioclass()
stream.write(data)
with self.assertRaises(MemoryError):
try:
_testcapi.set_nomemory(0)
with support.inject_memory_error_cm():
stream.truncate(5)
finally:
_testcapi.remove_mem_hooks()
self.assertEqual(stream.getvalue(), data)


Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_pyexpat.py
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,7 @@ def test_error_path_no_crash(self):
rc_before = sys.getrefcount(parser)

with self.assertRaises(MemoryError):
with support.memory_error_cm(1, 10):
with support.inject_memory_error_cm(1, 10):
parser.ExternalEntityParserCreate(None)

rc_after = sys.getrefcount(parser)
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_str.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ def test_replace_oom(self):
s2 = "&"
s3 = "&"
with self.assertRaises(MemoryError):
with support.memory_error_cm():
with support.inject_memory_error_cm():
s1.replace(s2, s3) # this line used to crash before

def test_repeat_id_preserving(self):
Expand Down
36 changes: 36 additions & 0 deletions Lib/test/test_tstring.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import unittest

from test import support
from test.support.os_helper import temp_cwd
from test.support.script_helper import assert_python_ok
from test.test_string._support import TStringBaseCase, fstring


Expand Down Expand Up @@ -79,6 +82,31 @@ def upper(self):
)
self.assertEqual(fstring(t), "Name: Bob, Age: 30")

def test_interpolation_expression_in_file_after_buffer_resize(self):
expression = "(\n" + (" " * 64 + "\n") * 256 + "1\n)"
with temp_cwd():
script = 'script.py'
source = (
f"template = t'''{{{expression}}}'''\n"
"interpolation = template.interpolations[0]\n"
f"assert interpolation.expression == {expression!r}\n"
)
with open(script, 'w') as f:
f.write(source)
assert_python_ok(script)

@support.requires_resource('cpu')
def test_many_tstrings_in_module(self):
fields = ''.join(f'{{x{i}}}' for i in range(100))
source = ''.join(
f"value_{i} = t'{fields}'\n" for i in range(1_000)
)
namespace = {f'x{i}': str(i) for i in range(100)}
expected = ''.join(str(i) for i in range(100))
exec(source, namespace)
self.assertEqual(fstring(namespace['value_0']), expected)
self.assertEqual(fstring(namespace['value_999']), expected)

def test_format_specifiers(self):
# Test basic format specifiers
value = 3.14159
Expand All @@ -88,6 +116,14 @@ def test_format_specifiers(self):
)
self.assertEqual(fstring(t), "Pi: 3.14")

a = 3
b = 4
t = t"{a!=b:>10}"
self.assertTStringEqual(
t, ("", ""), [(a != b, "a!=b", None, ">10")]
)
self.assertEqual(fstring(t), " 1")

def test_conversions(self):
# Test !s conversion (str)
obj = object()
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_ttk/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,13 @@ class LabelTest(AbstractLabelTest, unittest.TestCase):
def create(self, **kwargs):
return ttk.Label(self.root, **kwargs)

def test_configure_anchor(self):
widget = self.create()
values = ('n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center')
if get_tk_patchlevel(self.root) >= (9, 0, 5):
values += ('',)
self.checkEnumParam(widget, 'anchor', *values)

test_configure_justify = StandardOptionsTests.test_configure_justify


Expand Down Expand Up @@ -347,6 +354,7 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase):
def setUp(self):
super().setUp()
self.entry = self.create()
self._allow_empty_justify = get_tk_patchlevel(self.root) >= (9, 0, 5)

def create(self, **kwargs):
return ttk.Entry(self.root, **kwargs)
Expand Down
26 changes: 13 additions & 13 deletions Lib/uuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
>>> x.bytes
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'

# make a UUID from a 16-byte string
# make a UUID from a 16-byte bytes object
>>> uuid.UUID(bytes=x.bytes)
UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')

Expand Down Expand Up @@ -118,19 +118,19 @@ class UUID:
'12345678-1234-1234-1234-123456789abc'. The UUID constructor accepts
five possible forms: a similar string of hexadecimal digits, or a tuple
of six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and
48-bit values respectively) as an argument named 'fields', or a string
of 16 bytes (with all the integer fields in big-endian order) as an
argument named 'bytes', or a string of 16 bytes (with the first three
fields in little-endian order) as an argument named 'bytes_le', or a
single 128-bit integer as an argument named 'int'.
48-bit values respectively) as an argument named 'fields', or a 16-byte
bytes object (with all the integer fields in big-endian order) as an
argument named 'bytes', or a 16-byte bytes object (with the first three
fields in little-endian order) as an argument named 'bytes_le', or a single
128-bit integer as an argument named 'int'.

UUIDs have these read-only attributes:

bytes the UUID as a 16-byte string (containing the six
bytes the UUID as a 16-byte bytes object (containing the six
integer fields in big-endian byte order)

bytes_le the UUID as a 16-byte string (with time_low, time_mid,
and time_hi_version in little-endian byte order)
bytes_le the UUID as a 16-byte bytes object (with time_low,
time_mid, and time_hi_version in little-endian byte order)

fields a tuple of the six integer fields of the UUID,
which are also available as six individual attributes
Expand Down Expand Up @@ -179,7 +179,7 @@ def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,
int=None, version=None,
*, is_safe=SafeUUID.unknown):
r"""Create a UUID from either a string of 32 hexadecimal digits,
a string of 16 bytes as the 'bytes' argument, a string of 16 bytes
a 16-byte bytes object as the 'bytes' argument, a 16-byte bytes object
in little-endian order as the 'bytes_le' argument, a tuple of six
integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version,
8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as
Expand All @@ -191,9 +191,9 @@ def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,
UUID('{12345678-1234-5678-1234-567812345678}')
UUID('12345678123456781234567812345678')
UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
UUID(bytes='\x12\x34\x56\x78'*4)
UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
'\x12\x34\x56\x78\x12\x34\x56\x78')
UUID(bytes=b'\x12\x34\x56\x78'*4)
UUID(bytes_le=b'\x78\x56\x34\x12\x34\x12\x78\x56' +
b'\x12\x34\x56\x78\x12\x34\x56\x78')
UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
UUID(int=0x12345678123456781234567812345678)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix quadratic-time tokenization of modules containing many f-strings or
t-strings.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix ``python -m asyncio ps`` failing on a process that has a task with a
name longer than 255 characters.
Loading
Loading