-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
bpo-39350: Fix regression introduced when fractions.gcd was removed #18309
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -13,6 +13,12 @@ | |||||
| __all__ = ['Fraction'] | ||||||
|
|
||||||
|
|
||||||
| def _gcd(a, b): | ||||||
| # Supports non-integers for backward compatibility. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My main worry with this PR is this comment. I don't think that we should keep it back "backward compatibility". Either we remove _gcd() or we keep it on deliberate purpose, to return the same type than inputs (a and b arguments). I understand that @mdickinson wants to return the same type, and I'm fine with that. But in this case, the comment should be something like:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe also add a comment in Fraction constructor to explain why we test type() == int: explain that we want to get g as the same type than numerator and denominator types. Or something like that ;-)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @vstinner This comment wasn't introduced in this PR; it's from the previously working code.
No. I simply want to undo the breakage that #18021 introduced, in the simplest way possible, and with a regression test. I'm open to discussing any sort of behaviour change after that, but the first priority should be to get back to a working state, and the simplest path is to get back to the working state that existed in 3.9.0a2. Another way to address the breakage would be to revert #18021 in its entirety, and then re-do it more carefully.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The statistics module tries to keep input types for the output type. I think that it's good thing for generic modules like fractions and statistics. The documentation seems to say that it keeps the input type, but it's not very explicit: https://docs.python.org/dev/library/fractions.html I'm fine with keeping Python 3.8 behavior (so use your PR). If someone wants to change it, it can be done later. My first intent was only to remove the public deprecated fractions.gcd() function. I don't care about private functions like fractions._gcd(). |
||||||
| while b: | ||||||
| a, b = b, a%b | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| return a | ||||||
|
|
||||||
| # Constants related to the hash implementation; hash(x) is based | ||||||
| # on the reduction of x modulo the prime _PyHASH_MODULUS. | ||||||
| _PyHASH_MODULUS = sys.hash_info.modulus | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -666,6 +666,24 @@ def test_slots(self): | |||||
| r = F(13, 7) | ||||||
| self.assertRaises(AttributeError, setattr, r, 'a', 10) | ||||||
|
|
||||||
| def test_gcd_compatibility_branch(self): | ||||||
| # Regression test for bugs.python.org/issue39350 | ||||||
|
|
||||||
| class myint(int): | ||||||
| def __mul__(self, other): | ||||||
| return myint(int(self)*int(other)) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can please add: |
||||||
| @property | ||||||
| def numerator(self): | ||||||
| return self | ||||||
|
|
||||||
| @property | ||||||
| def denominator(self): | ||||||
| return myint(1) | ||||||
|
|
||||||
| myhalf = F(myint(1), myint(2)) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer to see GCD being computed and used, so I propose:
Suggested change
|
||||||
| self.assertEqual(myhalf, F(1, 2)) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can please add the following tests? |
||||||
|
|
||||||
|
|
||||||
| if __name__ == '__main__': | ||||||
| unittest.main() | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| Revert removal of ``fractions._gcd``. That removal caused breakage when | ||
| using ``fractions.Fraction`` with integer-like values (for example NumPy | ||
| integers). | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You may reuse my NEWS entry to avoid mentioning the private _gcd() method, I don't think that it matters here: |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, what about declared this function as the nested function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, we can skip the news :)
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to revert to as close as possible to the previous code, which had
_gcdas a module-level function.I think we do need a news entry, because this is fixing a bug that was already made available in a release. If the bug had been introduced and then fixed without any intermediate release, then we could have skipped the news entry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it :)