Skip to content

Commit 1c55b91

Browse files
authored
[3.14] pythongh-102431: Clarify constraints on operands of Decimal logical operations (pythonGH-102836) (python#140105)
* [3.14] pythongh-102431: Clarify constraints on operands of Decimal logical operations (pythonGH-102836) Sync C/Python implementation of the decimal: logical_ops for contexts. (cherry picked from commit 6ecf77d) Co-authored-by: Sergey B Kirpichev <[email protected]>
1 parent 2142f4e commit 1c55b91

File tree

3 files changed

+98
-12
lines changed

3 files changed

+98
-12
lines changed

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

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`.

Modules/_decimal/docstrings.h

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -292,22 +292,26 @@ an infinity then Decimal('Infinity') is returned.\n\
292292

293293
PyDoc_STRVAR(doc_logical_and,
294294
"logical_and($self, /, other, context=None)\n--\n\n\
295-
Return the digit-wise 'and' of the two (logical) operands.\n\
295+
Applies an 'and' operation between self and other's digits.\n\n\
296+
Both self and other must be logical numbers.\n\
296297
\n");
297298

298299
PyDoc_STRVAR(doc_logical_invert,
299300
"logical_invert($self, /, context=None)\n--\n\n\
300-
Return the digit-wise inversion of the (logical) operand.\n\
301+
Invert all its digits.\n\n\
302+
The self must be logical number.\n\
301303
\n");
302304

303305
PyDoc_STRVAR(doc_logical_or,
304306
"logical_or($self, /, other, context=None)\n--\n\n\
305-
Return the digit-wise 'or' of the two (logical) operands.\n\
307+
Applies an 'or' operation between self and other's digits.\n\n\
308+
Both self and other must be logical numbers. \n\
306309
\n");
307310

308311
PyDoc_STRVAR(doc_logical_xor,
309312
"logical_xor($self, /, other, context=None)\n--\n\n\
310-
Return the digit-wise 'exclusive or' of the two (logical) operands.\n\
313+
Applies an 'xor' operation between self and other's digits.\n\n\
314+
Both self and other must be logical numbers.\n\
311315
\n");
312316

313317
PyDoc_STRVAR(doc_max,
@@ -712,22 +716,90 @@ Return the exponent of the magnitude of the operand's MSD.\n\
712716

713717
PyDoc_STRVAR(doc_ctx_logical_and,
714718
"logical_and($self, x, y, /)\n--\n\n\
715-
Digit-wise and of x and y.\n\
719+
Applies the logical operation 'and' between each operand's digits.\n\n\
720+
The operands must be both logical numbers.\n\n\
721+
>>> ExtendedContext.logical_and(Decimal('0'), Decimal('0'))\n\
722+
Decimal('0')\n\
723+
>>> ExtendedContext.logical_and(Decimal('0'), Decimal('1'))\n\
724+
Decimal('0')\n\
725+
>>> ExtendedContext.logical_and(Decimal('1'), Decimal('0'))\n\
726+
Decimal('0')\n\
727+
>>> ExtendedContext.logical_and(Decimal('1'), Decimal('1'))\n\
728+
Decimal('1')\n\
729+
>>> ExtendedContext.logical_and(Decimal('1100'), Decimal('1010'))\n\
730+
Decimal('1000')\n\
731+
>>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10'))\n\
732+
Decimal('10')\n\
733+
>>> ExtendedContext.logical_and(110, 1101)\n\
734+
Decimal('100')\n\
735+
>>> ExtendedContext.logical_and(Decimal(110), 1101)\n\
736+
Decimal('100')\n\
737+
>>> ExtendedContext.logical_and(110, Decimal(1101))\n\
738+
Decimal('100')\n\
716739
\n");
717740

718741
PyDoc_STRVAR(doc_ctx_logical_invert,
719742
"logical_invert($self, x, /)\n--\n\n\
720-
Invert all digits of x.\n\
743+
Invert all the digits in the operand.\n\n\
744+
The operand must be a logical number.\n\n\
745+
>>> ExtendedContext.logical_invert(Decimal('0'))\n\
746+
Decimal('111111111')\n\
747+
>>> ExtendedContext.logical_invert(Decimal('1'))\n\
748+
Decimal('111111110')\n\
749+
>>> ExtendedContext.logical_invert(Decimal('111111111'))\n\
750+
Decimal('0')\n\
751+
>>> ExtendedContext.logical_invert(Decimal('101010101'))\n\
752+
Decimal('10101010')\n\
753+
>>> ExtendedContext.logical_invert(1101)\n\
754+
Decimal('111110010')\n\
721755
\n");
722756

723757
PyDoc_STRVAR(doc_ctx_logical_or,
724758
"logical_or($self, x, y, /)\n--\n\n\
725-
Digit-wise or of x and y.\n\
759+
Applies the logical operation 'or' between each operand's digits.\n\n\
760+
The operands must be both logical numbers.\n\n\
761+
>>> ExtendedContext.logical_or(Decimal('0'), Decimal('0'))\n\
762+
Decimal('0')\n\
763+
>>> ExtendedContext.logical_or(Decimal('0'), Decimal('1'))\n\
764+
Decimal('1')\n\
765+
>>> ExtendedContext.logical_or(Decimal('1'), Decimal('0'))\n\
766+
Decimal('1')\n\
767+
>>> ExtendedContext.logical_or(Decimal('1'), Decimal('1'))\n\
768+
Decimal('1')\n\
769+
>>> ExtendedContext.logical_or(Decimal('1100'), Decimal('1010'))\n\
770+
Decimal('1110')\n\
771+
>>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10'))\n\
772+
Decimal('1110')\n\
773+
>>> ExtendedContext.logical_or(110, 1101)\n\
774+
Decimal('1111')\n\
775+
>>> ExtendedContext.logical_or(Decimal(110), 1101)\n\
776+
Decimal('1111')\n\
777+
>>> ExtendedContext.logical_or(110, Decimal(1101))\n\
778+
Decimal('1111')\n\
726779
\n");
727780

728781
PyDoc_STRVAR(doc_ctx_logical_xor,
729782
"logical_xor($self, x, y, /)\n--\n\n\
730-
Digit-wise xor of x and y.\n\
783+
Applies the logical operation 'xor' between each operand's digits.\n\n\
784+
The operands must be both logical numbers.\n\n\
785+
>>> ExtendedContext.logical_xor(Decimal('0'), Decimal('0'))\n\
786+
Decimal('0')\n\
787+
>>> ExtendedContext.logical_xor(Decimal('0'), Decimal('1'))\n\
788+
Decimal('1')\n\
789+
>>> ExtendedContext.logical_xor(Decimal('1'), Decimal('0'))\n\
790+
Decimal('1')\n\
791+
>>> ExtendedContext.logical_xor(Decimal('1'), Decimal('1'))\n\
792+
Decimal('0')\n\
793+
>>> ExtendedContext.logical_xor(Decimal('1100'), Decimal('1010'))\n\
794+
Decimal('110')\n\
795+
>>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10'))\n\
796+
Decimal('1101')\n\
797+
>>> ExtendedContext.logical_xor(110, 1101)\n\
798+
Decimal('1011')\n\
799+
>>> ExtendedContext.logical_xor(Decimal(110), 1101)\n\
800+
Decimal('1011')\n\
801+
>>> ExtendedContext.logical_xor(110, Decimal(1101))\n\
802+
Decimal('1011')\n\
731803
\n");
732804

733805
PyDoc_STRVAR(doc_ctx_max,

0 commit comments

Comments
 (0)