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
13 changes: 13 additions & 0 deletions Doc/library/stdtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2562,6 +2562,19 @@ expression support in the :mod:`re` module).
after the separator. If the separator is not found, return a 3-tuple containing
two empty strings, followed by the string itself.

For example:

.. doctest::

>>> 'Monty Python'.rpartition(' ')
('Monty', ' ', 'Python')
>>> "Monty Python's Flying Circus".rpartition(' ')
("Monty Python's Flying", ' ', 'Circus')
>>> 'Monty Python'.rpartition('-')
('', '', 'Monty Python')

See also :meth:`partition`.


.. method:: str.rsplit(sep=None, maxsplit=-1)

Expand Down
26 changes: 13 additions & 13 deletions Doc/library/tkinter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,12 @@ the modern themed widget set and API::
.. attribute:: master

The widget object that contains this widget. For :class:`Tk`, the
*master* is :const:`None` because it is the main window. The terms
:attr:`!master` is :const:`None` because it is the main window. The terms
*master* and *parent* are similar and sometimes used interchangeably
as argument names; however, calling :meth:`winfo_parent` returns a
string of the widget name whereas :attr:`master` returns the object.
string of the widget name whereas :attr:`!master` returns the object.
*parent*/*child* reflects the tree-like relationship while
*master*/*slave* reflects the container structure.
*master* (or *container*)/*content* reflects the container structure.

.. attribute:: children

Expand Down Expand Up @@ -638,15 +638,15 @@ The Packer
.. index:: single: packing (widgets)

The packer is one of Tk's geometry-management mechanisms. Geometry managers
are used to specify the relative positioning of widgets within their container -
their mutual *master*. In contrast to the more cumbersome *placer* (which is
are used to specify the relative positioning of widgets within their container.
In contrast to the more cumbersome *placer* (which is
used less commonly, and we do not cover here), the packer takes qualitative
relationship specification - *above*, *to the left of*, *filling*, etc - and
works everything out to determine the exact placement coordinates for you.

The size of any *master* widget is determined by the size of the "slave widgets"
inside. The packer is used to control where slave widgets appear inside the
master into which they are packed. You can pack widgets into frames, and frames
The size of any container widget is determined by the size of the "content widgets"
inside. The packer is used to control where content widgets appear inside the
container into which they are packed. You can pack widgets into frames, and frames
into other frames, in order to achieve the kind of layout you desire.
Additionally, the arrangement is dynamically adjusted to accommodate incremental
changes to the configuration, once it is packed.
Expand All @@ -673,7 +673,7 @@ For more extensive information on the packer and the options that it can take,
see the man pages and page 183 of John Ousterhout's book.

anchor
Anchor type. Denotes where the packer is to place each slave in its parcel.
Anchor type. Denotes where the packer is to place each content in its parcel.

expand
Boolean, ``0`` or ``1``.
Expand All @@ -682,10 +682,10 @@ fill
Legal values: ``'x'``, ``'y'``, ``'both'``, ``'none'``.

ipadx and ipady
A distance - designating internal padding on each side of the slave widget.
A distance - designating internal padding on each side of the content.

padx and pady
A distance - designating external padding on each side of the slave widget.
A distance - designating external padding on each side of the content.

side
Legal values are: ``'left'``, ``'right'``, ``'top'``, ``'bottom'``.
Expand Down Expand Up @@ -758,8 +758,8 @@ subclassed from the :class:`Wm` class, and so can call the :class:`Wm` methods
directly.

To get at the toplevel window that contains a given widget, you can often just
refer to the widget's master. Of course if the widget has been packed inside of
a frame, the master won't represent a toplevel window. To get at the toplevel
refer to the widget's :attr:`master`. Of course if the widget has been packed inside of
a frame, the :attr:`!master` won't represent a toplevel window. To get at the toplevel
window that contains an arbitrary widget, you can call the :meth:`_root` method.
This method begins with an underscore to denote the fact that this function is
part of the implementation, and not an interface to Tk functionality.
Expand Down
15 changes: 14 additions & 1 deletion Lib/email/_header_value_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ def make_quoted_pairs(value):
return str(value).replace('\\', '\\\\').replace('"', '\\"')


def make_parenthesis_pairs(value):
"""Escape parenthesis and backslash for use within a comment."""
return str(value).replace('\\', '\\\\') \
.replace('(', '\\(').replace(')', '\\)')


def quote_string(value):
escaped = make_quoted_pairs(value)
return f'"{escaped}"'
Expand Down Expand Up @@ -943,7 +949,7 @@ def value(self):
return ' '

def startswith_fws(self):
return True
return self and self[0] in WSP


class ValueTerminal(Terminal):
Expand Down Expand Up @@ -2963,6 +2969,13 @@ def _refold_parse_tree(parse_tree, *, policy):
[ValueTerminal(make_quoted_pairs(p), 'ptext')
for p in newparts] +
[ValueTerminal('"', 'ptext')])
if part.token_type == 'comment':
newparts = (
[ValueTerminal('(', 'ptext')] +
[ValueTerminal(make_parenthesis_pairs(p), 'ptext')
if p.token_type == 'ptext' else p
for p in newparts] +
[ValueTerminal(')', 'ptext')])
if not part.as_ew_allowed:
wrap_as_ew_blocked += 1
newparts.append(end_ew_not_allowed)
Expand Down
23 changes: 23 additions & 0 deletions Lib/test/test_email/test__header_value_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3294,6 +3294,29 @@ def test_address_list_with_specials_in_long_quoted_string(self):
with self.subTest(to=to):
self._test(parser.get_address_list(to)[0], folded, policy=policy)

def test_address_list_with_long_unwrapable_comment(self):
policy = self.policy.clone(max_line_length=40)
cases = [
# (to, folded)
('(loremipsumdolorsitametconsecteturadipi)<spy@example.org>',
'(loremipsumdolorsitametconsecteturadipi)<spy@example.org>\n'),
('<spy@example.org>(loremipsumdolorsitametconsecteturadipi)',
'<spy@example.org>(loremipsumdolorsitametconsecteturadipi)\n'),
('(loremipsum dolorsitametconsecteturadipi)<spy@example.org>',
'(loremipsum dolorsitametconsecteturadipi)<spy@example.org>\n'),
('<spy@example.org>(loremipsum dolorsitametconsecteturadipi)',
'<spy@example.org>(loremipsum\n dolorsitametconsecteturadipi)\n'),
('(Escaped \\( \\) chars \\\\ in comments stay escaped)<spy@example.org>',
'(Escaped \\( \\) chars \\\\ in comments stay\n escaped)<spy@example.org>\n'),
('((loremipsum)(loremipsum)(loremipsum)(loremipsum))<spy@example.org>',
'((loremipsum)(loremipsum)(loremipsum)(loremipsum))<spy@example.org>\n'),
('((loremipsum)(loremipsum)(loremipsum) (loremipsum))<spy@example.org>',
'((loremipsum)(loremipsum)(loremipsum)\n (loremipsum))<spy@example.org>\n'),
]
for (to, folded) in cases:
with self.subTest(to=to):
self._test(parser.get_address_list(to)[0], folded, policy=policy)

# XXX Need tests with comments on various sides of a unicode token,
# and with unicode tokens in the comments. Spaces inside the quotes
# currently don't do the right thing.
Expand Down
21 changes: 20 additions & 1 deletion Lib/test/test_io/test_bufferedio.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from collections import deque, UserList
from itertools import cycle, count
from test import support
from test.support import os_helper, threading_helper
from test.support import check_sanitizer, os_helper, threading_helper
from .utils import byteslike, CTestCase, PyTestCase


Expand Down Expand Up @@ -623,6 +623,25 @@ def test_bad_readinto_type(self):
bufio.readline()
self.assertIsInstance(cm.exception.__cause__, TypeError)

@unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
@unittest.skipIf(check_sanitizer(thread=True),
'ThreadSanitizer aborts on huge allocations (exit code 66).')
def test_read1_error_does_not_cause_reentrant_failure(self):
self.addCleanup(os_helper.unlink, os_helper.TESTFN)
with self.open(os_helper.TESTFN, "wb") as f:
f.write(b"hello")

with self.open(os_helper.TESTFN, "rb", buffering=0) as raw:
bufio = self.tp(raw, buffer_size=8)
# To request a size that is far too huge to ever be satisfied,
# so that the internal buffer allocation reliably fails with MemoryError.
huge = sys.maxsize // 2 + 1
with self.assertRaises(MemoryError):
bufio.read1(huge)

# Used to crash before gh-143689:
self.assertEqual(bufio.read1(1), b"h")


class PyBufferedReaderTest(BufferedReaderTest, PyTestCase):
tp = pyio.BufferedReader
Expand Down
27 changes: 12 additions & 15 deletions Lib/test/test_unicodedata.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,7 @@ def test_method_checksum(self):
self.assertEqual(result, self.expectedchecksum)


class UnicodeFunctionsTest(unittest.TestCase):
db = unicodedata
old = False

# Update this if the database changes. Make sure to do a full rebuild
# (e.g. 'make distclean && make') to get the correct checksum.
expectedchecksum = ('83cc43a2fbb779185832b4c049217d80b05bf349'
if quicktest else
'65670ae03a324c5f9e826a4de3e25bae4d73c9b7')
class BaseUnicodeFunctionsTest:

def test_function_checksum(self):
db = self.db
Expand Down Expand Up @@ -589,6 +581,16 @@ def test_east_asian_width_unassigned(self):
self.assertEqual(eaw(char), 'A')
self.assertIs(self.db.name(char, None), None)

class UnicodeFunctionsTest(unittest.TestCase, BaseUnicodeFunctionsTest):
db = unicodedata
old = False

# Update this if the database changes. Make sure to do a full rebuild
# (e.g. 'make distclean && make') to get the correct checksum.
expectedchecksum = ('83cc43a2fbb779185832b4c049217d80b05bf349'
if quicktest else
'65670ae03a324c5f9e826a4de3e25bae4d73c9b7')

def test_isxidstart(self):
self.assertTrue(self.db.isxidstart('S'))
self.assertTrue(self.db.isxidstart('\u0AD0')) # GUJARATI OM
Expand Down Expand Up @@ -832,18 +834,13 @@ def graphemes(*args):
['a', '\U0001F1FA\U0001F1E6', '\U0001F1FA\U0001F1F3'])


class Unicode_3_2_0_FunctionsTest(UnicodeFunctionsTest):
class Unicode_3_2_0_FunctionsTest(unittest.TestCase, BaseUnicodeFunctionsTest):
db = unicodedata.ucd_3_2_0
old = True
expectedchecksum = ('f4526159891a4b766dd48045646547178737ba09'
if quicktest else
'f217b8688d7bdff31db4207e078a96702f091597')

test_grapheme_cluster_break = None
test_indic_conjunct_break = None
test_extended_pictographic = None
test_grapheme_break = None


class UnicodeMiscTest(unittest.TestCase):
db = unicodedata
Expand Down
Loading
Loading