bpo-44115: improve duck-typing of fractions by tecki · Pull Request #26064 · python/cpython
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
allow any object that has an as_integer_ratio method to be
converted to fractions.
This is helpful especially for numpy types, which have said method
but do not inherit from the classes that can currently be converted
to fractions.
allow any object that has an as_integer_ratio method to be converted to fractions. This is helpful especially for numpy types, which have said method but do not inherit from the classes that can currently be converted to fractions.
Even though I like the idea I see a problem with relying on getattr(numerator, "as_integer_ratio", None).
This assumes that all objects with as_integer_ratio will behave exactly like float and Decimal. If they don't we'll get inconsistent Fractions, or even errors. At least float and Decimal are "within Python's control" and we can guarantee the behavior.
Also, I don't see too much overhead in converting those objects to float and use them to create a Fraction. This would be a stronger assumption, IHMO. Especially if we consider objects that implement the same functionality but with a different method name, we'd have to convert them to float anyways.
Well, whether we rely on the method by the same name doing the same thing is mostly a philosophical question. Traditionally, in the Python community, the response was clear: if it quacks like a duck, it is a duck.
Especially in this case I do not see problems: the method name is very specific. If it was a rather generic name, say start, that would be a different question, but as_integer_ratio is pretty concise.
Just converting to float is simply not an option: fractions simply are much more precise than floats, as in exact. If you convert 1/3 to floats, you lose precision. Same happens for converting Decimals, or numpy's float128.
After reading a lot on this topic on bpo, I realized that it could be a good idea to simply add as_integer_ratio to numbers.Rational. This makes everything very systematic, and also kindof baptises as_integer_ratio as the way to go.
How do you like it?
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks ok
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR has merge conflicts now.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.
Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.
Accepting any object with as_integer_ratio was rejected in #82017.
tecki
mannequin
mentioned this pull request