https://github.com/python/cpython/commit/1c55b9163bd048f14db4f3c7e55df801ee760ac8
commit: 1c55b9163bd048f14db4f3c7e55df801ee760ac8
branch: 3.14
author: Sergey B Kirpichev <[email protected]>
committer: vstinner <[email protected]>
date: 2025-10-14T15:44:30+02:00
summary:

[3.14] gh-102431: Clarify constraints on operands of Decimal logical operations 
(GH-102836) (#140105)

* [3.14] 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 6ecf77dbdec7838e9ce2298cb8d16e8c2250da81)

Co-authored-by: Sergey B Kirpichev <[email protected]>

files:
A Misc/NEWS.d/next/Library/2023-03-21-10-59-40.gh-issue-102431.eUDnf4.rst
M Lib/_pydecimal.py
M Modules/_decimal/docstrings.h

diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py
index 9b8e42a2342536..97a629fe92ccec 100644
--- a/Lib/_pydecimal.py
+++ b/Lib/_pydecimal.py
@@ -3340,7 +3340,10 @@ def _fill_logical(self, context, opa, opb):
         return opa, opb
 
     def logical_and(self, other, context=None):
-        """Applies an 'and' operation between self and other's digits."""
+        """Applies an 'and' operation between self and other's digits.
+
+        Both self and other must be logical numbers.
+        """
         if context is None:
             context = getcontext()
 
@@ -3357,14 +3360,20 @@ def logical_and(self, other, context=None):
         return _dec_from_triple(0, result.lstrip('0') or '0', 0)
 
     def logical_invert(self, context=None):
-        """Invert all its digits."""
+        """Invert all its digits.
+
+        The self must be logical number.
+        """
         if context is None:
             context = getcontext()
         return self.logical_xor(_dec_from_triple(0,'1'*context.prec,0),
                                 context)
 
     def logical_or(self, other, context=None):
-        """Applies an 'or' operation between self and other's digits."""
+        """Applies an 'or' operation between self and other's digits.
+
+        Both self and other must be logical numbers.
+        """
         if context is None:
             context = getcontext()
 
@@ -3381,7 +3390,10 @@ def logical_or(self, other, context=None):
         return _dec_from_triple(0, result.lstrip('0') or '0', 0)
 
     def logical_xor(self, other, context=None):
-        """Applies an 'xor' operation between self and other's digits."""
+        """Applies an 'xor' operation between self and other's digits.
+
+        Both self and other must be logical numbers.
+        """
         if context is None:
             context = getcontext()
 
diff --git 
a/Misc/NEWS.d/next/Library/2023-03-21-10-59-40.gh-issue-102431.eUDnf4.rst 
b/Misc/NEWS.d/next/Library/2023-03-21-10-59-40.gh-issue-102431.eUDnf4.rst
new file mode 100644
index 00000000000000..e82ddb6e1011ad
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-03-21-10-59-40.gh-issue-102431.eUDnf4.rst
@@ -0,0 +1,2 @@
+Clarify constraints for "logical" arguments in methods of
+:class:`decimal.Context`.
diff --git a/Modules/_decimal/docstrings.h b/Modules/_decimal/docstrings.h
index 77017a92252cb8..9c2da5e35f919a 100644
--- a/Modules/_decimal/docstrings.h
+++ b/Modules/_decimal/docstrings.h
@@ -292,22 +292,26 @@ an infinity then Decimal('Infinity') is returned.\n\
 
 PyDoc_STRVAR(doc_logical_and,
 "logical_and($self, /, other, context=None)\n--\n\n\
-Return the digit-wise 'and' of the two (logical) operands.\n\
+Applies an 'and' operation between self and other's digits.\n\n\
+Both self and other must be logical numbers.\n\
 \n");
 
 PyDoc_STRVAR(doc_logical_invert,
 "logical_invert($self, /, context=None)\n--\n\n\
-Return the digit-wise inversion of the (logical) operand.\n\
+Invert all its digits.\n\n\
+The self must be logical number.\n\
 \n");
 
 PyDoc_STRVAR(doc_logical_or,
 "logical_or($self, /, other, context=None)\n--\n\n\
-Return the digit-wise 'or' of the two (logical) operands.\n\
+Applies an 'or' operation between self and other's digits.\n\n\
+Both self and other must be logical numbers. \n\
 \n");
 
 PyDoc_STRVAR(doc_logical_xor,
 "logical_xor($self, /, other, context=None)\n--\n\n\
-Return the digit-wise 'exclusive or' of the two (logical) operands.\n\
+Applies an 'xor' operation between self and other's digits.\n\n\
+Both self and other must be logical numbers.\n\
 \n");
 
 PyDoc_STRVAR(doc_max,
@@ -712,22 +716,90 @@ Return the exponent of the magnitude of the operand's 
MSD.\n\
 
 PyDoc_STRVAR(doc_ctx_logical_and,
 "logical_and($self, x, y, /)\n--\n\n\
-Digit-wise and of x and y.\n\
+Applies the logical operation 'and' between each operand's digits.\n\n\
+The operands must be both logical numbers.\n\n\
+    >>> ExtendedContext.logical_and(Decimal('0'), Decimal('0'))\n\
+    Decimal('0')\n\
+    >>> ExtendedContext.logical_and(Decimal('0'), Decimal('1'))\n\
+    Decimal('0')\n\
+    >>> ExtendedContext.logical_and(Decimal('1'), Decimal('0'))\n\
+    Decimal('0')\n\
+    >>> ExtendedContext.logical_and(Decimal('1'), Decimal('1'))\n\
+    Decimal('1')\n\
+    >>> ExtendedContext.logical_and(Decimal('1100'), Decimal('1010'))\n\
+    Decimal('1000')\n\
+    >>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10'))\n\
+    Decimal('10')\n\
+    >>> ExtendedContext.logical_and(110, 1101)\n\
+    Decimal('100')\n\
+    >>> ExtendedContext.logical_and(Decimal(110), 1101)\n\
+    Decimal('100')\n\
+    >>> ExtendedContext.logical_and(110, Decimal(1101))\n\
+    Decimal('100')\n\
 \n");
 
 PyDoc_STRVAR(doc_ctx_logical_invert,
 "logical_invert($self, x, /)\n--\n\n\
-Invert all digits of x.\n\
+Invert all the digits in the operand.\n\n\
+The operand must be a logical number.\n\n\
+    >>> ExtendedContext.logical_invert(Decimal('0'))\n\
+    Decimal('111111111')\n\
+    >>> ExtendedContext.logical_invert(Decimal('1'))\n\
+    Decimal('111111110')\n\
+    >>> ExtendedContext.logical_invert(Decimal('111111111'))\n\
+    Decimal('0')\n\
+    >>> ExtendedContext.logical_invert(Decimal('101010101'))\n\
+    Decimal('10101010')\n\
+    >>> ExtendedContext.logical_invert(1101)\n\
+    Decimal('111110010')\n\
 \n");
 
 PyDoc_STRVAR(doc_ctx_logical_or,
 "logical_or($self, x, y, /)\n--\n\n\
-Digit-wise or of x and y.\n\
+Applies the logical operation 'or' between each operand's digits.\n\n\
+The operands must be both logical numbers.\n\n\
+    >>> ExtendedContext.logical_or(Decimal('0'), Decimal('0'))\n\
+    Decimal('0')\n\
+    >>> ExtendedContext.logical_or(Decimal('0'), Decimal('1'))\n\
+    Decimal('1')\n\
+    >>> ExtendedContext.logical_or(Decimal('1'), Decimal('0'))\n\
+    Decimal('1')\n\
+    >>> ExtendedContext.logical_or(Decimal('1'), Decimal('1'))\n\
+    Decimal('1')\n\
+    >>> ExtendedContext.logical_or(Decimal('1100'), Decimal('1010'))\n\
+    Decimal('1110')\n\
+    >>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10'))\n\
+    Decimal('1110')\n\
+    >>> ExtendedContext.logical_or(110, 1101)\n\
+    Decimal('1111')\n\
+    >>> ExtendedContext.logical_or(Decimal(110), 1101)\n\
+    Decimal('1111')\n\
+    >>> ExtendedContext.logical_or(110, Decimal(1101))\n\
+    Decimal('1111')\n\
 \n");
 
 PyDoc_STRVAR(doc_ctx_logical_xor,
 "logical_xor($self, x, y, /)\n--\n\n\
-Digit-wise xor of x and y.\n\
+Applies the logical operation 'xor' between each operand's digits.\n\n\
+The operands must be both logical numbers.\n\n\
+    >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('0'))\n\
+    Decimal('0')\n\
+    >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('1'))\n\
+    Decimal('1')\n\
+    >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('0'))\n\
+    Decimal('1')\n\
+    >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('1'))\n\
+    Decimal('0')\n\
+    >>> ExtendedContext.logical_xor(Decimal('1100'), Decimal('1010'))\n\
+    Decimal('110')\n\
+    >>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10'))\n\
+    Decimal('1101')\n\
+    >>> ExtendedContext.logical_xor(110, 1101)\n\
+    Decimal('1011')\n\
+    >>> ExtendedContext.logical_xor(Decimal(110), 1101)\n\
+    Decimal('1011')\n\
+    >>> ExtendedContext.logical_xor(110, Decimal(1101))\n\
+    Decimal('1011')\n\
 \n");
 
 PyDoc_STRVAR(doc_ctx_max,

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to