You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2022-02-03.09:44:44.771>created_at=<Date2021-08-22.09:17:57.051>labels= ['interpreter-core', '3.11']
title='Deprecate delegation of int to __trunc__'updated_at=<Date2022-02-03.09:44:44.770>user='https://github.com/mdickinson'
The int constructor, when applied to a general Python object obj, first looks for an int method, then for an index method, and then finally for a trunc method.
The delegation to __trunc__ used to be useful: it meant that users could write a custom class SomeNumber with the property that:
SomeNumber instances supported 'int' calls, returning a truncated value, but
SomeNumber instances weren't usable in indexing, chr() calls, and all the various other calls that implicitly invoked __int__.
However, with Python >= 3.10, we no longer use __int__ implicitly for argument conversion in internal code. So the second point above is no longer a concern, and SomeNumber can now simply be written as
This decouples int from __trunc__ and leaves __trunc__ as simply the support for the math.trunc function.
Argh; copy and paste fail - I left out the crucial line.
I propose deprecating the delegation of int to __trunc__: calls to int(a) where type(a) implements __trunc__ but not __int__ or __index__ would raise a DeprecationWarning, and at some point in the future int(a) would become a TypeError.
I think the needs are sufficiently different that __trunc__ still has value as its own thing, and it's a natural counterpart to __floor__ and __ceil__ (out of all the directed rounding modes, rounding towards zero probably turns up more often than rounding towards +inf or -inf).
__int__ has the disadvantage that it must return an int, so it's not useful for other Python-based numeric systems with their own rational number / integer pairing. For example, with gmpy2, truncating an mpq instance returns an mpz instance, which is what I'd expect and want - if I'm working with huge values then it would be annoying for math.trunc to do the inefficient thing and return a plain int.
>>> from gmpy2 import mpq
>>> math.trunc(mpq(22, 7))
mpz(3)
SymPy behaves similarly:
>>> from sympy import Rational
>>> type(math.trunc(Rational(22, 7)))
<class 'sympy.core.numbers.Integer'>
On the other side, there are conversions to integer that it doesn't make sense to think of as truncation. It would be odd for a UUID to be a valid input to math.trunc, for example:
Activity
mdickinson commentedon Aug 22, 2021
The int constructor, when applied to a general Python object
obj, first looks for an int method, then for an index method, and then finally for a trunc method.The delegation to __trunc__ used to be useful: it meant that users could write a custom class SomeNumber with the property that:
However, with Python >= 3.10, we no longer use __int__ implicitly for argument conversion in internal code. So the second point above is no longer a concern, and SomeNumber can now simply be written as
This decouples int from __trunc__ and leaves __trunc__ as simply the support for the math.trunc function.
mdickinson commentedon Aug 22, 2021
Argh; copy and paste fail - I left out the crucial line.
I propose deprecating the delegation of int to __trunc__: calls to int(a) where type(a) implements __trunc__ but not __int__ or __index__ would raise a DeprecationWarning, and at some point in the future int(a) would become a TypeError.
serhiy-storchaka commentedon Aug 22, 2021
Completely agree.
rhettinger commentedon Aug 22, 2021
Afterwards, do __trunc__ and math.trunc() still need to exist?
They were mostly unused. Now they would also be unnecessary. Just having them around would be a point of confusion.
mdickinson commentedon Aug 22, 2021
A GitHub code search shows a substantial number of uses of math.trunc out in the wild:
https://github.com/search?q=math.trunc+extension%3Apy&type=Code
So unfortunately, getting rid of math.trunc and __trunc__ looks a bit too much as though it would cause gratuitous breakage.
rhettinger commentedon Aug 22, 2021
Possibly, we could have math.trunc() call __int__, letting us deprecate __trunc__.
That would let users avoid gratuitous aliasing such as that in _pydecimal.py:
serhiy-storchaka commentedon Aug 22, 2021
I do not think that math.trunc() for UUID or IP4Address makes sense.
mdickinson commentedon Aug 22, 2021
I think the needs are sufficiently different that __trunc__ still has value as its own thing, and it's a natural counterpart to __floor__ and __ceil__ (out of all the directed rounding modes, rounding towards zero probably turns up more often than rounding towards +inf or -inf).
__int__ has the disadvantage that it must return an int, so it's not useful for other Python-based numeric systems with their own rational number / integer pairing. For example, with gmpy2, truncating an mpq instance returns an mpz instance, which is what I'd expect and want - if I'm working with huge values then it would be annoying for math.trunc to do the inefficient thing and return a plain int.
SymPy behaves similarly:
On the other side, there are conversions to integer that it doesn't make sense to think of as truncation. It would be odd for a UUID to be a valid input to math.trunc, for example:
>>> int(uuid.uuid4()) 43341414945793370480422623795805641537rhettinger commentedon Aug 22, 2021
I retract the suggestion to deprecate __trunc__.
[-]Deprecate delegation of int to __trunc__?[/-][+]Deprecate delegation of int to __trunc__[/+][-]Deprecate delegation of int to __trunc__?[/-][+]Deprecate delegation of int to __trunc__[/+]ZackerySpytz commentedon Jan 31, 2022
I have created a patch for this issue. Please consider having a look.
serhiy-storchaka commentedon Feb 3, 2022
New changeset b4bd1e1 by Zackery Spytz in branch 'main':
bpo-44977: Deprecate delegation of int to __trunc__ (GH-31031)
b4bd1e1
serhiy-storchaka commentedon Feb 3, 2022
Thanks Zackery.