Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-82012: Deprecate bitwise inversion (~) of bool#103487

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
hauntsaninja merged 5 commits intopython:mainfromtimhoffm:deprecate-bool-invert
May 3, 2023
Merged
Show file tree
Hide file tree
Changes fromall 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
2 changes: 1 addition & 1 deletionDoc/library/functions.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -147,7 +147,7 @@ are always available. They are listed here in alphabetical order.
or omitted, this returns ``False``; otherwise, it returns ``True``. The
:class:`bool` class is a subclass of :class:`int` (see :ref:`typesnumeric`).
It cannot be subclassed further. Its only instances are ``False`` and
``True`` (see :ref:`bltin-boolean-values`).
``True`` (see :ref:`typebool`).

.. index:: pair: Boolean; type

Expand Down
54 changes: 33 additions & 21 deletionsDoc/library/stdtypes.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -802,6 +802,39 @@ number, :class:`float`, or :class:`complex`::
hash_value = -2
return hash_value

.. _typebool:

Boolean Type - :class:`bool`
============================

Booleans represent truth values. The :class:`bool` type has exactly two
constant instances: ``True`` and ``False``.

.. index::
single: False
single: True
pair: Boolean; values

The built-in function :func:`bool` converts any value to a boolean, if the
value can be interpreted as a truth value (see section :ref:`truth` above).

For logical operations, use the :ref:`boolean operators <boolean>` ``and``,
``or`` and ``not``.
When applying the bitwise operators ``&``, ``|``, ``^`` to two booleans, they
return a bool equivalent to the logical operations "and", "or", "xor". However,
the logical operators ``and``, ``or`` and ``!=`` should be preferred
over ``&``, ``|`` and ``^``.

.. deprecated:: 3.12

The use of the bitwise inversion operator ``~`` is deprecated and will
raise an error in Python 3.14.

:class:`bool` is a subclass of :class:`int` (see :ref:`typesnumeric`). In
many numeric contexts, ``False`` and ``True`` behave like the integers 0 and 1, respectively.
However, relying on this is discouraged; explicitly convert using :func:`int`
instead.

.. _typeiter:

Iterator Types
Expand DownExpand Up@@ -5394,27 +5427,6 @@ information. There is exactly one ``NotImplemented`` object.
It is written as ``NotImplemented``.


.. _bltin-boolean-values:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Hello. The removal of thisref tag broke intersphinx downstream. I have not tracked down yet which middleware is calling this tag when API docstring has a "bool" mentioned. I suspect it is numpydoc. Is it not possible to reuse this tag for your new section above?

xrefastropy/astropy#15428

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

If you open a PR, I can backport it to the 3.12 branch

JelleZijlstra reacted with thumbs up emoji
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Sure. Please see#110371 . Thank you for your consideration!


Boolean Values
--------------

Boolean values are the two constant objects ``False`` and ``True``. They are
used to represent truth values (although other values can also be considered
false or true). In numeric contexts (for example when used as the argument to
an arithmetic operator), they behave like the integers 0 and 1, respectively.
The built-in function :func:`bool` can be used to convert any value to a
Boolean, if the value can be interpreted as a truth value (see section
:ref:`truth` above).

.. index::
single: False
single: True
pair: Boolean; values

They are written as ``False`` and ``True``, respectively.


.. _typesinternal:

Internal Objects
Expand Down
6 changes: 6 additions & 0 deletionsDoc/whatsnew/3.12.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -705,6 +705,12 @@ Deprecated
replaced by :data:`calendar.Month.JANUARY` and :data:`calendar.Month.FEBRUARY`.
(Contributed by Prince Roshan in :gh:`103636`.)

* The bitwise inversion operator (``~``) on bool is deprecated. It will throw an
error in Python 3.14. Use ``not`` for logical negation of bools instead.
In the rare case that you really need the bitwise inversion of the underlying
``int``, convert to int explicitly with ``~int(x)``. (Contributed by Tim Hoffmann
in :gh:`103487`.)

Pending Removal in Python 3.13
------------------------------

Expand Down
18 changes: 16 additions & 2 deletionsLib/test/test_bool.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,8 +58,22 @@ def test_math(self):
self.assertEqual(-True, -1)
self.assertEqual(abs(True), 1)
self.assertIsNot(abs(True), True)
self.assertEqual(~False, -1)
self.assertEqual(~True, -2)
with self.assertWarns(DeprecationWarning):
# We need to put the bool in a variable, because the constant
# ~False is evaluated at compile time due to constant folding;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

We should test this behavior separately (doing something likewith assertWarns(DeprecationWarning): exec("~False")).

Copy link
ContributorAuthor

@timhoffmtimhoffmApr 29, 2023
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Do you mean instead of or in addition to the current test? We originally hadeval("~True") but I figured it's clearer to have the warning context only around the operation and not around a comparably complexeval() orexec(). I'm happy to change if there's a benefit of these though.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

We should have both. The existing tests check that the deprecation warning is emitted correctly at runtime. The new tests would ensure that if the operation occurs at compile time, we still emit the DeprecationWarning.

timhoffm reacted with thumbs up emoji
# consequently the DeprecationWarning would be issued during
# module loading and not during test execution.
false = False
self.assertEqual(~false, -1)
with self.assertWarns(DeprecationWarning):
# also check that the warning is issued in case of constant
# folding at compile time
self.assertEqual(eval("~False"), -1)
with self.assertWarns(DeprecationWarning):
true = True
self.assertEqual(~true, -2)
with self.assertWarns(DeprecationWarning):
self.assertEqual(eval("~True"), -2)

self.assertEqual(False+2, 2)
self.assertEqual(True+2, 3)
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
The bitwise inversion operator (``~``) on bool is deprecated.
It returns the bitwise inversion of the underlying ``int`` representation such that
``bool(~True) == True``, which can be confusing. Use ``not`` for logical negation
of bools. In the rare case that you really need the bitwise inversion of the underlying ``int``,
convert to int explicitly ``~int(x)``.
18 changes: 17 additions & 1 deletionObjects/boolobject.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,6 +73,22 @@ bool_vectorcall(PyObject *type, PyObject * const*args,

/* Arithmetic operations redefined to return bool if both args are bool. */

static PyObject *
bool_invert(PyObject *v)
{
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"Bitwise inversion '~' on bool is deprecated. This "
"returns the bitwise inversion of the underlying int "
"object and is usually not what you expect from negating "
"a bool. Use the 'not' operator for boolean negation or "
"~int(x) if you really want the bitwise inversion of the "
"underlying int.",
1) < 0) {
return NULL;
}
return PyLong_Type.tp_as_number->nb_invert(v);
}

static PyObject *
bool_and(PyObject *a, PyObject *b)
{
Expand DownExpand Up@@ -119,7 +135,7 @@ static PyNumberMethods bool_as_number = {
0, /* nb_positive */
0, /* nb_absolute */
0, /* nb_bool */
0, /* nb_invert */
(unaryfunc)bool_invert, /* nb_invert */
0, /* nb_lshift */
0, /* nb_rshift */
bool_and, /* nb_and */
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp