bpo-44115: improve duck-typing of fractions by tecki · Pull Request #26064 · python/cpython

tecki

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.

https://bugs.python.org/issue44115

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.

@blurb-it

JelleZijlstra

@miguendes

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.

@tecki

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.

@tecki

@rhettinger

This all looks good. Please update the docs as well (including a versionchanged note).

@tecki

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?

@tecki

@github-actions

This PR is stale because it has been open for 30 days with no activity.

MaxwellDupre

Choose a reason for hiding this comment

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

Looks ok

iritkatriel

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.

@bedevere-bot

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.

@encukou

Accepting any object with as_integer_ratio was rejected in #82017.

@tecki tecki mannequin mentioned this pull request

Mar 18, 2024