Skip to content

Commit bfb9639

Browse files
authored
[3.13] gh-102431: Clarify constraints on operands of Decimal logical operations (GH-102836) (#140106)
* [3.13] gh-102431: Clarify constraints on operands of Decimal logical operations (GH-102836) Sync C/Python implementation of the decimal: logical_ops for contexts. (cherry picked from commit 6ecf77d) Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
1 parent 7992a29 commit bfb9639

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
@@ -3302,7 +3302,10 @@ def _fill_logical(self, context, opa, opb):
33023302
return opa, opb
33033303

33043304
def logical_and(self, other, context=None):
3305-
"""Applies an 'and' operation between self and other's digits."""
3305+
"""Applies an 'and' operation between self and other's digits.
3306+
3307+
Both self and other must be logical numbers.
3308+
"""
33063309
if context is None:
33073310
context = getcontext()
33083311

@@ -3319,14 +3322,20 @@ def logical_and(self, other, context=None):
33193322
return _dec_from_triple(0, result.lstrip('0') or '0', 0)
33203323

33213324
def logical_invert(self, context=None):
3322-
"""Invert all its digits."""
3325+
"""Invert all its digits.
3326+
3327+
The self must be logical number.
3328+
"""
33233329
if context is None:
33243330
context = getcontext()
33253331
return self.logical_xor(_dec_from_triple(0,'1'*context.prec,0),
33263332
context)
33273333

33283334
def logical_or(self, other, context=None):
3329-
"""Applies an 'or' operation between self and other's digits."""
3335+
"""Applies an 'or' operation between self and other's digits.
3336+
3337+
Both self and other must be logical numbers.
3338+
"""
33303339
if context is None:
33313340
context = getcontext()
33323341

@@ -3343,7 +3352,10 @@ def logical_or(self, other, context=None):
33433352
return _dec_from_triple(0, result.lstrip('0') or '0', 0)
33443353

33453354
def logical_xor(self, other, context=None):
3346-
"""Applies an 'xor' operation between self and other's digits."""
3355+
"""Applies an 'xor' operation between self and other's digits.
3356+
3357+
Both self and other must be logical numbers.
3358+
"""
33473359
if context is None:
33483360
context = getcontext()
33493361

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
@@ -282,22 +282,26 @@ an infinity then Decimal('Infinity') is returned.\n\
282282

283283
PyDoc_STRVAR(doc_logical_and,
284284
"logical_and($self, /, other, context=None)\n--\n\n\
285-
Return the digit-wise 'and' of the two (logical) operands.\n\
285+
Applies an 'and' operation between self and other's digits.\n\n\
286+
Both self and other must be logical numbers.\n\
286287
\n");
287288

288289
PyDoc_STRVAR(doc_logical_invert,
289290
"logical_invert($self, /, context=None)\n--\n\n\
290-
Return the digit-wise inversion of the (logical) operand.\n\
291+
Invert all its digits.\n\n\
292+
The self must be logical number.\n\
291293
\n");
292294

293295
PyDoc_STRVAR(doc_logical_or,
294296
"logical_or($self, /, other, context=None)\n--\n\n\
295-
Return the digit-wise 'or' of the two (logical) operands.\n\
297+
Applies an 'or' operation between self and other's digits.\n\n\
298+
Both self and other must be logical numbers. \n\
296299
\n");
297300

298301
PyDoc_STRVAR(doc_logical_xor,
299302
"logical_xor($self, /, other, context=None)\n--\n\n\
300-
Return the digit-wise 'exclusive or' of the two (logical) operands.\n\
303+
Applies an 'xor' operation between self and other's digits.\n\n\
304+
Both self and other must be logical numbers.\n\
301305
\n");
302306

303307
PyDoc_STRVAR(doc_max,
@@ -702,22 +706,90 @@ Return the exponent of the magnitude of the operand's MSD.\n\
702706

703707
PyDoc_STRVAR(doc_ctx_logical_and,
704708
"logical_and($self, x, y, /)\n--\n\n\
705-
Digit-wise and of x and y.\n\
709+
Applies the logical operation 'and' between each operand's digits.\n\n\
710+
The operands must be both logical numbers.\n\n\
711+
>>> ExtendedContext.logical_and(Decimal('0'), Decimal('0'))\n\
712+
Decimal('0')\n\
713+
>>> ExtendedContext.logical_and(Decimal('0'), Decimal('1'))\n\
714+
Decimal('0')\n\
715+
>>> ExtendedContext.logical_and(Decimal('1'), Decimal('0'))\n\
716+
Decimal('0')\n\
717+
>>> ExtendedContext.logical_and(Decimal('1'), Decimal('1'))\n\
718+
Decimal('1')\n\
719+
>>> ExtendedContext.logical_and(Decimal('1100'), Decimal('1010'))\n\
720+
Decimal('1000')\n\
721+
>>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10'))\n\
722+
Decimal('10')\n\
723+
>>> ExtendedContext.logical_and(110, 1101)\n\
724+
Decimal('100')\n\
725+
>>> ExtendedContext.logical_and(Decimal(110), 1101)\n\
726+
Decimal('100')\n\
727+
>>> ExtendedContext.logical_and(110, Decimal(1101))\n\
728+
Decimal('100')\n\
706729
\n");
707730

708731
PyDoc_STRVAR(doc_ctx_logical_invert,
709732
"logical_invert($self, x, /)\n--\n\n\
710-
Invert all digits of x.\n\
733+
Invert all the digits in the operand.\n\n\
734+
The operand must be a logical number.\n\n\
735+
>>> ExtendedContext.logical_invert(Decimal('0'))\n\
736+
Decimal('111111111')\n\
737+
>>> ExtendedContext.logical_invert(Decimal('1'))\n\
738+
Decimal('111111110')\n\
739+
>>> ExtendedContext.logical_invert(Decimal('111111111'))\n\
740+
Decimal('0')\n\
741+
>>> ExtendedContext.logical_invert(Decimal('101010101'))\n\
742+
Decimal('10101010')\n\
743+
>>> ExtendedContext.logical_invert(1101)\n\
744+
Decimal('111110010')\n\
711745
\n");
712746

713747
PyDoc_STRVAR(doc_ctx_logical_or,
714748
"logical_or($self, x, y, /)\n--\n\n\
715-
Digit-wise or of x and y.\n\
749+
Applies the logical operation 'or' between each operand's digits.\n\n\
750+
The operands must be both logical numbers.\n\n\
751+
>>> ExtendedContext.logical_or(Decimal('0'), Decimal('0'))\n\
752+
Decimal('0')\n\
753+
>>> ExtendedContext.logical_or(Decimal('0'), Decimal('1'))\n\
754+
Decimal('1')\n\
755+
>>> ExtendedContext.logical_or(Decimal('1'), Decimal('0'))\n\
756+
Decimal('1')\n\
757+
>>> ExtendedContext.logical_or(Decimal('1'), Decimal('1'))\n\
758+
Decimal('1')\n\
759+
>>> ExtendedContext.logical_or(Decimal('1100'), Decimal('1010'))\n\
760+
Decimal('1110')\n\
761+
>>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10'))\n\
762+
Decimal('1110')\n\
763+
>>> ExtendedContext.logical_or(110, 1101)\n\
764+
Decimal('1111')\n\
765+
>>> ExtendedContext.logical_or(Decimal(110), 1101)\n\
766+
Decimal('1111')\n\
767+
>>> ExtendedContext.logical_or(110, Decimal(1101))\n\
768+
Decimal('1111')\n\
716769
\n");
717770

718771
PyDoc_STRVAR(doc_ctx_logical_xor,
719772
"logical_xor($self, x, y, /)\n--\n\n\
720-
Digit-wise xor of x and y.\n\
773+
Applies the logical operation 'xor' between each operand's digits.\n\n\
774+
The operands must be both logical numbers.\n\n\
775+
>>> ExtendedContext.logical_xor(Decimal('0'), Decimal('0'))\n\
776+
Decimal('0')\n\
777+
>>> ExtendedContext.logical_xor(Decimal('0'), Decimal('1'))\n\
778+
Decimal('1')\n\
779+
>>> ExtendedContext.logical_xor(Decimal('1'), Decimal('0'))\n\
780+
Decimal('1')\n\
781+
>>> ExtendedContext.logical_xor(Decimal('1'), Decimal('1'))\n\
782+
Decimal('0')\n\
783+
>>> ExtendedContext.logical_xor(Decimal('1100'), Decimal('1010'))\n\
784+
Decimal('110')\n\
785+
>>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10'))\n\
786+
Decimal('1101')\n\
787+
>>> ExtendedContext.logical_xor(110, 1101)\n\
788+
Decimal('1011')\n\
789+
>>> ExtendedContext.logical_xor(Decimal(110), 1101)\n\
790+
Decimal('1011')\n\
791+
>>> ExtendedContext.logical_xor(110, Decimal(1101))\n\
792+
Decimal('1011')\n\
721793
\n");
722794

723795
PyDoc_STRVAR(doc_ctx_max,

0 commit comments

Comments
 (0)