[Python-checkins] bpo-44977: Deprecate delegation of int to __trunc__ (GH-31031)
serhiy-storchaka
webhook-mailer at python.org
Thu Feb 3 04:43:46 EST 2022
https://github.com/python/cpython/commit/b4bd1e1422997de61faf506b4916e83013bc7d21
commit: b4bd1e1422997de61faf506b4916e83013bc7d21
branch: main
author: Zackery Spytz <zspytz at gmail.com>
committer: serhiy-storchaka <storchaka at gmail.com>
date: 2022-02-03T11:43:25+02:00
summary:
bpo-44977: Deprecate delegation of int to __trunc__ (GH-31031)
Calling int(a) when type(a) implements __trunc__ but not __int__
or __index__ now raises a DeprecationWarning.
files:
A Misc/NEWS.d/next/Core and Builtins/2022-01-30-18-23-08.bpo-44977.BQV_zS.rst
M Doc/library/functions.rst
M Doc/reference/datamodel.rst
M Doc/whatsnew/3.11.rst
M Lib/test/test_descr.py
M Lib/test/test_int.py
M Lib/test/test_long.py
M Objects/abstract.c
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 9c061bcd8252a..eaa4d482ce3fc 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -891,6 +891,9 @@ are always available. They are listed here in alphabetical order.
.. versionchanged:: 3.8
Falls back to :meth:`__index__` if :meth:`__int__` is not defined.
+ .. versionchanged:: 3.11
+ The delegation to :meth:`__trunc__` is deprecated.
+
.. function:: isinstance(object, classinfo)
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index 48c54d729424c..a773b73ce3243 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -2760,6 +2760,9 @@ left undefined.
The built-in function :func:`int` falls back to :meth:`__trunc__` if neither
:meth:`__int__` nor :meth:`__index__` is defined.
+ .. versionchanged:: 3.11
+ The delegation of :func:`int` to :meth:`__trunc__` is deprecated.
+
.. _context-managers:
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index acb21d3ccaf17..18d4652fb4293 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -458,6 +458,11 @@ Deprecated
as deprecated, its docstring is now corrected).
(Contributed by Hugo van Kemenade in :issue:`45837`.)
+* The delegation of :func:`int` to :meth:`__trunc__` is now deprecated. Calling
+ ``int(a)`` when ``type(a)`` implements :meth:`__trunc__` but not
+ :meth:`__int__` or :meth:`__index__` now raises a :exc:`DeprecationWarning`.
+ (Contributed by Zackery Spytz in :issue:`44977`.)
+
* The following have been deprecated in :mod:`configparser` since Python 3.2.
Their deprecation warnings have now been updated to note they will removed in
Python 3.12:
@@ -468,6 +473,7 @@ Deprecated
(Contributed by Hugo van Kemenade in :issue:`45173`.)
+
Removed
=======
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 791cf714d46a3..a0942d6a85b81 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -2061,7 +2061,6 @@ def format_impl(self, spec):
("__format__", format, format_impl, set(), {}),
("__floor__", math.floor, zero, set(), {}),
("__trunc__", math.trunc, zero, set(), {}),
- ("__trunc__", int, zero, set(), {}),
("__ceil__", math.ceil, zero, set(), {}),
("__dir__", dir, empty_seq, set(), {}),
("__round__", round, zero, set(), {}),
diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py
index d6be64e7c18a0..a72699cc7506a 100644
--- a/Lib/test/test_int.py
+++ b/Lib/test/test_int.py
@@ -369,12 +369,14 @@ def __trunc__(self):
class JustTrunc(base):
def __trunc__(self):
return 42
- self.assertEqual(int(JustTrunc()), 42)
+ with self.assertWarns(DeprecationWarning):
+ self.assertEqual(int(JustTrunc()), 42)
class ExceptionalTrunc(base):
def __trunc__(self):
1 / 0
- with self.assertRaises(ZeroDivisionError):
+ with self.assertRaises(ZeroDivisionError), \
+ self.assertWarns(DeprecationWarning):
int(ExceptionalTrunc())
for trunc_result_base in (object, Classic):
@@ -385,7 +387,8 @@ def __index__(self):
class TruncReturnsNonInt(base):
def __trunc__(self):
return Index()
- self.assertEqual(int(TruncReturnsNonInt()), 42)
+ with self.assertWarns(DeprecationWarning):
+ self.assertEqual(int(TruncReturnsNonInt()), 42)
class Intable(trunc_result_base):
def __int__(self):
@@ -394,7 +397,8 @@ def __int__(self):
class TruncReturnsNonIndex(base):
def __trunc__(self):
return Intable()
- self.assertEqual(int(TruncReturnsNonInt()), 42)
+ with self.assertWarns(DeprecationWarning):
+ self.assertEqual(int(TruncReturnsNonInt()), 42)
class NonIntegral(trunc_result_base):
def __trunc__(self):
@@ -405,7 +409,8 @@ class TruncReturnsNonIntegral(base):
def __trunc__(self):
return NonIntegral()
try:
- int(TruncReturnsNonIntegral())
+ with self.assertWarns(DeprecationWarning):
+ int(TruncReturnsNonIntegral())
except TypeError as e:
self.assertEqual(str(e),
"__trunc__ returned non-Integral"
@@ -423,7 +428,8 @@ class TruncReturnsBadInt(base):
def __trunc__(self):
return BadInt()
- with self.assertRaises(TypeError):
+ with self.assertRaises(TypeError), \
+ self.assertWarns(DeprecationWarning):
int(TruncReturnsBadInt())
def test_int_subclass_with_index(self):
@@ -517,13 +523,16 @@ def __trunc__(self):
self.assertIs(type(n), int)
bad_int = TruncReturnsBadInt()
- self.assertRaises(TypeError, int, bad_int)
+ with self.assertWarns(DeprecationWarning):
+ self.assertRaises(TypeError, int, bad_int)
good_int = TruncReturnsIntSubclass()
- n = int(good_int)
+ with self.assertWarns(DeprecationWarning):
+ n = int(good_int)
self.assertEqual(n, 1)
self.assertIs(type(n), int)
- n = IntSubclass(good_int)
+ with self.assertWarns(DeprecationWarning):
+ n = IntSubclass(good_int)
self.assertEqual(n, 1)
self.assertIs(type(n), IntSubclass)
diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py
index c7dd0b274d1e3..e68dfb4c542ea 100644
--- a/Lib/test/test_long.py
+++ b/Lib/test/test_long.py
@@ -392,7 +392,8 @@ def __long__(self):
return 42
def __trunc__(self):
return 1729
- self.assertEqual(int(LongTrunc()), 1729)
+ with self.assertWarns(DeprecationWarning):
+ self.assertEqual(int(LongTrunc()), 1729)
def check_float_conversion(self, n):
# Check that int -> float conversion behaviour matches
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-30-18-23-08.bpo-44977.BQV_zS.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-30-18-23-08.bpo-44977.BQV_zS.rst
new file mode 100644
index 0000000000000..84c1191bdbd31
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-01-30-18-23-08.bpo-44977.BQV_zS.rst
@@ -0,0 +1,3 @@
+The delegation of :func:`int` to :meth:`__trunc__` is now deprecated.
+Calling ``int(a)`` when ``type(a)`` implements :meth:`__trunc__` but not
+:meth:`__int__` or :meth:`__index__` now raises a :exc:`DeprecationWarning`.
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 6a2d5eda14079..ed99fd6c5aafb 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -1564,6 +1564,11 @@ PyNumber_Long(PyObject *o)
}
trunc_func = _PyObject_LookupSpecial(o, &PyId___trunc__);
if (trunc_func) {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "The delegation of int() to __trunc__ is deprecated.", 1)) {
+ Py_DECREF(trunc_func);
+ return NULL;
+ }
result = _PyObject_CallNoArgs(trunc_func);
Py_DECREF(trunc_func);
if (result == NULL || PyLong_CheckExact(result)) {
More information about the Python-checkins
mailing list