-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
Interpret decimal.Decimal
s as integers if no precision would be lost
#102791
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
…ted as integers Prior to pythongh-11952, several standard library functions that expected integer arguments would nevertheless silently accept (and truncate) non-integer arguments. This behaviour was deprecated in pythongh-11952, and removed in pythongh-15636. However, it may be possible to interpret some non-integer numeric types (such as `decimal.Decimal`s) as integers if they contain no fractional part. Implement `__index__` for `decimal.Decimal`, returning an integer representation of the value if it does not contain a fractional part or raising a `TypeError` if it does.
Care to elaborate why you need this, or is it a secret? 😉 (For brevity in typing, I'm going to use float rather than Decimal.) In the absence of any obvious or clear reason for this, it seems to me that this would just lay hidden land-mines in peoples code. E.g. they do something like |
I think this idea goes against the spirit of what Also, this would make it harder for static type checkers to validate that code is correct. And, as Steven points out, types with fractional components tend to had round-off errors that would make this a fragile and error-prone feature. |
I agree it would be fragile and a bad idea to have |
Right now Basically, we would need to use |
Agreed with other commenters that |
I also agree that this is a bad idea, for the same reasons that others have already listed. |
Sounds like there are multiple good reasons not to do this - thanks for the input, everyone. |
Feature or enhancement
It should be possible for
decimal.Decimal
s (and potentially other non-integer numeric types) to be interpreted as integers if doing so would not cause a loss of precision.Pitch
As of GH-15636 (part of Python from 3.10.0 onwards), it's no longer possible to use certain numeric types as arguments to standard library functions when an integer is expected due to the removal of type coercion logic. This is, of course, quite sensible:
datetime.datetime(year=2023, month=3, day=17.5)
is meaningless, and should result in aTypeError
rather than adatetime
object representing 2023-03-17 00:00:00. However, there are situations where certain numeric types might be coercible to integers - one example is adecimal.Decimal
with no fractional part. In these situations, I think it makes sense for the standard library functions whose behaviour changed following GH-15636 to behave as they did before.In the
Decimal
case, this would involve implementing__index__
in a way that returns an integer representation of the value if the number has no fractional part, or raising aTypeError
if it does. I believe this complies with the general understanding of how__index__
is supposed to work - from the What's New entry discussing PEP 357:I've implemented this in both
_decimal
and_pydecimal
, with the following results:I have a particular need for this to work with
Decimal
, but perhaps the same could be done for other types in the standard library if there's enough interest.Previous discussion
In issue36048, Serhiy discusses the rationale for this behaviour being deprecated in the first place (in Python 3.8) - the comment identifies the problem with "dropping the fractional part if the object is not [an] integral number", but doesn't address the corollary of that (i.e. permitting type coercion if the object is an integral number), which is the purpose of this issue.
Linked PRs
The text was updated successfully, but these errors were encountered: