Skip to content

Commit 348a26f

Browse files
committed
Merge branch 'main' of https://github.com/python/cpython
2 parents 983c8db + 07e617e commit 348a26f

File tree

10 files changed

+264
-36
lines changed

10 files changed

+264
-36
lines changed

Doc/library/stdtypes.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,6 +2157,19 @@ expression support in the :mod:`re` module).
21572157
character, for example uppercase characters may only follow uncased characters
21582158
and lowercase characters only cased ones. Return ``False`` otherwise.
21592159

2160+
For example:
2161+
2162+
.. doctest::
2163+
2164+
>>> 'Spam, Spam, Spam'.istitle()
2165+
True
2166+
>>> 'spam, spam, spam'.istitle()
2167+
False
2168+
>>> 'SPAM, SPAM, SPAM'.istitle()
2169+
False
2170+
2171+
See also :meth:`title`.
2172+
21602173

21612174
.. method:: str.isupper()
21622175

@@ -2534,6 +2547,8 @@ expression support in the :mod:`re` module).
25342547
>>> titlecase("they're bill's friends.")
25352548
"They're Bill's Friends."
25362549

2550+
See also :meth:`istitle`.
2551+
25372552

25382553
.. method:: str.translate(table, /)
25392554

Lib/_pydecimal.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3340,7 +3340,10 @@ def _fill_logical(self, context, opa, opb):
33403340
return opa, opb
33413341

33423342
def logical_and(self, other, context=None):
3343-
"""Applies an 'and' operation between self and other's digits."""
3343+
"""Applies an 'and' operation between self and other's digits.
3344+
3345+
Both self and other must be logical numbers.
3346+
"""
33443347
if context is None:
33453348
context = getcontext()
33463349

@@ -3357,14 +3360,20 @@ def logical_and(self, other, context=None):
33573360
return _dec_from_triple(0, result.lstrip('0') or '0', 0)
33583361

33593362
def logical_invert(self, context=None):
3360-
"""Invert all its digits."""
3363+
"""Invert all its digits.
3364+
3365+
The self must be logical number.
3366+
"""
33613367
if context is None:
33623368
context = getcontext()
33633369
return self.logical_xor(_dec_from_triple(0,'1'*context.prec,0),
33643370
context)
33653371

33663372
def logical_or(self, other, context=None):
3367-
"""Applies an 'or' operation between self and other's digits."""
3373+
"""Applies an 'or' operation between self and other's digits.
3374+
3375+
Both self and other must be logical numbers.
3376+
"""
33683377
if context is None:
33693378
context = getcontext()
33703379

@@ -3381,7 +3390,10 @@ def logical_or(self, other, context=None):
33813390
return _dec_from_triple(0, result.lstrip('0') or '0', 0)
33823391

33833392
def logical_xor(self, other, context=None):
3384-
"""Applies an 'xor' operation between self and other's digits."""
3393+
"""Applies an 'xor' operation between self and other's digits.
3394+
3395+
Both self and other must be logical numbers.
3396+
"""
33853397
if context is None:
33863398
context = getcontext()
33873399

Lib/test/multibytecodec_support.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,23 @@ def test_incrementalencoder_del_segfault(self):
282282
with self.assertRaises(AttributeError):
283283
del e.errors
284284

285+
def test_null_terminator(self):
286+
# see gh-101828
287+
text = "フルーツ"
288+
try:
289+
text.encode(self.encoding)
290+
except UnicodeEncodeError:
291+
text = "Python is cool"
292+
encode_w_null = (text + "\0").encode(self.encoding)
293+
encode_plus_null = text.encode(self.encoding) + "\0".encode(self.encoding)
294+
self.assertTrue(encode_w_null.endswith(b'\x00'))
295+
self.assertEqual(encode_w_null, encode_plus_null)
296+
297+
encode_w_null_2 = (text + "\0" + text + "\0").encode(self.encoding)
298+
encode_plus_null_2 = encode_plus_null + encode_plus_null
299+
self.assertEqual(encode_w_null_2.count(b'\x00'), 2)
300+
self.assertEqual(encode_w_null_2, encode_plus_null_2)
301+
285302

286303
class TestBase_Mapping(unittest.TestCase):
287304
pass_enctest = []
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Clarify constraints for "logical" arguments in methods of
2+
:class:`decimal.Context`.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix ``'shift_jisx0213'``, ``'shift_jis_2004'``, ``'euc_jisx0213'`` and
2+
``'euc_jis_2004'`` codecs truncating null chars
3+
as they were treated as part of multi-character sequences.

Modules/_decimal/_decimal.c

Lines changed: 100 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5235,13 +5235,15 @@ _decimal_Decimal_copy_negate_impl(PyObject *self, PyTypeObject *cls)
52355235
/*[clinic input]
52365236
_decimal.Decimal.logical_invert = _decimal.Decimal.exp
52375237
5238-
Return the digit-wise inversion of the (logical) operand.
5238+
Invert all its digits.
5239+
5240+
The self must be logical number.
52395241
[clinic start generated code]*/
52405242

52415243
static PyObject *
52425244
_decimal_Decimal_logical_invert_impl(PyObject *self, PyTypeObject *cls,
52435245
PyObject *context)
5244-
/*[clinic end generated code: output=c626ed4b104a97b7 input=3531dac8b9548dad]*/
5246+
/*[clinic end generated code: output=c626ed4b104a97b7 input=7158d5b525417955]*/
52455247
Dec_UnaryFuncVA(mpd_qinvert)
52465248

52475249
/*[clinic input]
@@ -5471,37 +5473,43 @@ _decimal_Decimal_same_quantum_impl(PyObject *self, PyTypeObject *cls,
54715473
/*[clinic input]
54725474
_decimal.Decimal.logical_and = _decimal.Decimal.compare
54735475
5474-
Return the digit-wise 'and' of the two (logical) operands.
5476+
Applies an 'and' operation between self and other's digits.
5477+
5478+
Both self and other must be logical numbers.
54755479
[clinic start generated code]*/
54765480

54775481
static PyObject *
54785482
_decimal_Decimal_logical_and_impl(PyObject *self, PyTypeObject *cls,
54795483
PyObject *other, PyObject *context)
5480-
/*[clinic end generated code: output=9a4cbb74c180b0bb input=2b319baee8970929]*/
5484+
/*[clinic end generated code: output=9a4cbb74c180b0bb input=f22460f1285782d2]*/
54815485
Dec_BinaryFuncVA(mpd_qand)
54825486

54835487
/*[clinic input]
54845488
_decimal.Decimal.logical_or = _decimal.Decimal.compare
54855489
5486-
Return the digit-wise 'or' of the two (logical) operands.
5490+
Applies an 'or' operation between self and other's digits.
5491+
5492+
Both self and other must be logical numbers.
54875493
[clinic start generated code]*/
54885494

54895495
static PyObject *
54905496
_decimal_Decimal_logical_or_impl(PyObject *self, PyTypeObject *cls,
54915497
PyObject *other, PyObject *context)
5492-
/*[clinic end generated code: output=063c4de18dc41ecb input=75e0e1d4dd373b90]*/
5498+
/*[clinic end generated code: output=063c4de18dc41ecb input=b5afa1e1fdebdfce]*/
54935499
Dec_BinaryFuncVA(mpd_qor)
54945500

54955501
/*[clinic input]
54965502
_decimal.Decimal.logical_xor = _decimal.Decimal.compare
54975503
5498-
Return the digit-wise 'xor' of the two (logical) operands.
5504+
Applies an 'xor' operation between self and other's digits.
5505+
5506+
Both self and other must be logical numbers.
54995507
[clinic start generated code]*/
55005508

55015509
static PyObject *
55025510
_decimal_Decimal_logical_xor_impl(PyObject *self, PyTypeObject *cls,
55035511
PyObject *other, PyObject *context)
5504-
/*[clinic end generated code: output=829b09cb49926ad7 input=a1ed8d6ac38c1c9e]*/
5512+
/*[clinic end generated code: output=829b09cb49926ad7 input=84d722ada08a2da7]*/
55055513
Dec_BinaryFuncVA(mpd_qxor)
55065514

55075515
/*[clinic input]
@@ -7099,13 +7107,26 @@ DecCtx_UnaryFunc(mpd_qlogb)
70997107
/*[clinic input]
71007108
_decimal.Context.logical_invert = _decimal.Context.abs
71017109
7102-
Invert all digits of x.
7110+
Invert all the digits in the operand.
7111+
7112+
The operand must be a logical number.
7113+
7114+
>>> ExtendedContext.logical_invert(Decimal('0'))
7115+
Decimal('111111111')
7116+
>>> ExtendedContext.logical_invert(Decimal('1'))
7117+
Decimal('111111110')
7118+
>>> ExtendedContext.logical_invert(Decimal('111111111'))
7119+
Decimal('0')
7120+
>>> ExtendedContext.logical_invert(Decimal('101010101'))
7121+
Decimal('10101010')
7122+
>>> ExtendedContext.logical_invert(1101)
7123+
Decimal('111110010')
71037124
[clinic start generated code]*/
71047125

71057126
static PyObject *
71067127
_decimal_Context_logical_invert_impl(PyObject *context, PyTypeObject *cls,
71077128
PyObject *x)
7108-
/*[clinic end generated code: output=97760277a958e2b0 input=1fa8dcc59c557fcc]*/
7129+
/*[clinic end generated code: output=97760277a958e2b0 input=8e568f4c745ab596]*/
71097130
DecCtx_UnaryFunc(mpd_qinvert)
71107131

71117132
/*[clinic input]
@@ -7262,37 +7283,100 @@ _decimal_Context_copy_sign_impl(PyObject *context, PyTypeObject *cls,
72627283
/*[clinic input]
72637284
_decimal.Context.logical_and = _decimal.Context.add
72647285
7265-
Digit-wise and of x and y.
7286+
Applies the logical operation 'and' between each operand's digits.
7287+
7288+
The operands must be both logical numbers.
7289+
7290+
>>> ExtendedContext.logical_and(Decimal('0'), Decimal('0'))
7291+
Decimal('0')
7292+
>>> ExtendedContext.logical_and(Decimal('0'), Decimal('1'))
7293+
Decimal('0')
7294+
>>> ExtendedContext.logical_and(Decimal('1'), Decimal('0'))
7295+
Decimal('0')
7296+
>>> ExtendedContext.logical_and(Decimal('1'), Decimal('1'))
7297+
Decimal('1')
7298+
>>> ExtendedContext.logical_and(Decimal('1100'), Decimal('1010'))
7299+
Decimal('1000')
7300+
>>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10'))
7301+
Decimal('10')
7302+
>>> ExtendedContext.logical_and(110, 1101)
7303+
Decimal('100')
7304+
>>> ExtendedContext.logical_and(Decimal(110), 1101)
7305+
Decimal('100')
7306+
>>> ExtendedContext.logical_and(110, Decimal(1101))
7307+
Decimal('100')
72667308
[clinic start generated code]*/
72677309

72687310
static PyObject *
72697311
_decimal_Context_logical_and_impl(PyObject *context, PyTypeObject *cls,
72707312
PyObject *x, PyObject *y)
7271-
/*[clinic end generated code: output=009dfa08ecaa2ac8 input=30ee33b5b365fd80]*/
7313+
/*[clinic end generated code: output=009dfa08ecaa2ac8 input=bcb7d3d6ab7530de]*/
72727314
DecCtx_BinaryFunc(mpd_qand)
72737315

72747316
/*[clinic input]
72757317
_decimal.Context.logical_or = _decimal.Context.add
72767318
7277-
Digit-wise or of x and y.
7319+
Applies the logical operation 'or' between each operand's digits.
7320+
7321+
The operands must be both logical numbers.
7322+
7323+
>>> ExtendedContext.logical_or(Decimal('0'), Decimal('0'))
7324+
Decimal('0')
7325+
>>> ExtendedContext.logical_or(Decimal('0'), Decimal('1'))
7326+
Decimal('1')
7327+
>>> ExtendedContext.logical_or(Decimal('1'), Decimal('0'))
7328+
Decimal('1')
7329+
>>> ExtendedContext.logical_or(Decimal('1'), Decimal('1'))
7330+
Decimal('1')
7331+
>>> ExtendedContext.logical_or(Decimal('1100'), Decimal('1010'))
7332+
Decimal('1110')
7333+
>>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10'))
7334+
Decimal('1110')
7335+
>>> ExtendedContext.logical_or(110, 1101)
7336+
Decimal('1111')
7337+
>>> ExtendedContext.logical_or(Decimal(110), 1101)
7338+
Decimal('1111')
7339+
>>> ExtendedContext.logical_or(110, Decimal(1101))
7340+
Decimal('1111')
72787341
[clinic start generated code]*/
72797342

72807343
static PyObject *
72817344
_decimal_Context_logical_or_impl(PyObject *context, PyTypeObject *cls,
72827345
PyObject *x, PyObject *y)
7283-
/*[clinic end generated code: output=eb38617e8d31bf12 input=3b1a6725d0262fb9]*/
7346+
/*[clinic end generated code: output=eb38617e8d31bf12 input=47b45d296fb90846]*/
72847347
DecCtx_BinaryFunc(mpd_qor)
72857348

72867349
/*[clinic input]
72877350
_decimal.Context.logical_xor = _decimal.Context.add
72887351
7289-
Digit-wise xor of x and y.
7352+
Applies the logical operation 'xor' between each operand's digits.
7353+
7354+
The operands must be both logical numbers.
7355+
7356+
>>> ExtendedContext.logical_xor(Decimal('0'), Decimal('0'))
7357+
Decimal('0')
7358+
>>> ExtendedContext.logical_xor(Decimal('0'), Decimal('1'))
7359+
Decimal('1')
7360+
>>> ExtendedContext.logical_xor(Decimal('1'), Decimal('0'))
7361+
Decimal('1')
7362+
>>> ExtendedContext.logical_xor(Decimal('1'), Decimal('1'))
7363+
Decimal('0')
7364+
>>> ExtendedContext.logical_xor(Decimal('1100'), Decimal('1010'))
7365+
Decimal('110')
7366+
>>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10'))
7367+
Decimal('1101')
7368+
>>> ExtendedContext.logical_xor(110, 1101)
7369+
Decimal('1011')
7370+
>>> ExtendedContext.logical_xor(Decimal(110), 1101)
7371+
Decimal('1011')
7372+
>>> ExtendedContext.logical_xor(110, Decimal(1101))
7373+
Decimal('1011')
72907374
[clinic start generated code]*/
72917375

72927376
static PyObject *
72937377
_decimal_Context_logical_xor_impl(PyObject *context, PyTypeObject *cls,
72947378
PyObject *x, PyObject *y)
7295-
/*[clinic end generated code: output=23cd81fdcd865d5a input=5ebbbe8bb35da380]*/
7379+
/*[clinic end generated code: output=23cd81fdcd865d5a input=fcaaf828c1d2d089]*/
72967380
DecCtx_BinaryFunc(mpd_qxor)
72977381

72987382
/*[clinic input]

0 commit comments

Comments
 (0)