-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
negative Fraction ** negative int not normalized #71726
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
I already wrote http://bugs.python.org/msg270548, but can't seem to reopen the issue, so I think the best thing is to report the bug separately. So, in issue http://bugs.python.org/issue21136, performance enhancement https://hg.python.org/cpython/rev/91d7fadac271/ enabled a shortcut for some operations (pow among them) to avoid reducing the result to lowest terms if it can be concluded it's already reduced. However, the logic has a corner case that was handled incorrectly. If a negative Fraction is raised to a negative integer, the result is a Fraction with a negative denominator, which is not normalized and in fact breaks many other operations (which rightly assume their operands to be normalized). >>> import fractions
>>> fractions.Fraction(-1, 2) ** -1
Fraction(2, -1)
>>> _ == -2
False Of course, the easy fix would be to change line 52 of fractions.py to _normalize=True - but that would reintroduce the slowness talked about in http://bugs.python.org/issue21136#msg215409. Alternative fix is to branch depending on the sign of the base, which might be messy if we intend to be completely general -- for example, in finite quotient rings, fractions don't have well-defined signs. [BTW I'm not quite sure why the code in fractions.py is so general, with many weird cases trying to support every imaginable construction - maybe someone really wanted such a level of generality. I don't, so I'd be fine with this working only on ordinary int/int Fractions.] |
Oops, that's an embarrassing bug. Branching depending on the sign sounds fine to me. There's no point worrying about supporting strange Fraction-like things without a concrete idea of exactly which such things we want to support. Are you interested in writing a patch? |
Unfortunately, until now I was just a happy user of Python. I suppose some day I would have to give something back, and now is as good a day as any:-), but I have studied https://docs.python.org/devguide/ for a while and it seems really scary. It means I have to install and get acquainted with Mercurial [BTW I thought Python was on git since this year, it seems PEP-481 was just wishful thinking:(], and probably with Visual Studio since I use Windows - and I have never successfully installed that (I have some weird academic Windows licence it doesn't like, and it seems really hard to install for a single non-admin user, which is a must since this is actually not my machine:). So, let's put the cards on the table: if the idea of your post was to initiate me in the process of becoming a good open-source citizen, then I'll bite the bullet and try to do everything in my power to actually get my equipment into a state where I can contribute to Python - but it will take time. On the other hand, if the idea was to just fix the bug in time for 3.6b1, it would be a great deal simpler if you wrote the patch. :-/ |
If it is of any help, here is the patch I wrote online: http://www.mergely.com/TwCVpiFp/ (also in attachment). I also took the liberty of properly isolating the _normalize argument by requiring it to be keyword-only (starting its name with underscore doesn't mean much if people could just call e.g. |
Vedran: The migration to git and GitHub is in progress. The devguide is being moved today. CPython itself should be done by the end of the year, but after 3.6.0 is released in Sept. I am on Windows and yes, setting up on Windows can be a nuisance. Learning VS is not needed, as one can just run PCBuild/build.bat to compile. But installing 9 GB of even the free version, to use the compiler, is. TortoiseHG makes minimal use of hg pretty easy. I had never used any source control system before. But this will be unnecessary soon. I let Mark decide if he can use the diff as is. Are the line numbers those of fractions.py, or do they need to be translated? |
The .diff format of patch for fractions.py is at The line numbers in it are the newest I could get (from I would also add the test I was talking about (Fraction(-1, 2) ** -1), if I knew where to do it. |
Tests for fractions are in Lib/test/test_fractions.py. In necessary, post the new code in a message. |
Here is the code for the patch: 84c84
459,466c459,466
I tried to add the test to test_fractions.py, but unfortunately unittest reports 3 unrelated failures due to mismatch in error messages (why does it check exact messages of exceptions anyway?). But it should just be adding
after line 408. _Please_, can this go in before 15th? |
Note that this is a bugfix, not a new feature, so it can still go in after the 15th. |
Here's a patch (against the 3.5 tip). I've dropped the keyword-only |
Fair enough. Two questions: How/when does this appear in 3.6 line? I guess there is a standard timeline of how bugfixes are "forwardported", but I don't know what it is. How do I make the _normalize "kwonlyfication"? Do I report a new issue and refer to this one? I really think that accepting |
Sure, that would work. A patch that included the change and a test that checks that |
After allowing a couple of days for review, I'll commit the issue_27539_fix patch to the 3.5 branch, then immediately merge it to the 3.6 "default" branch. So that fix should appear in the upcoming 3.6 beta1. |
LGTM. |
New changeset 7eea5b87f5fa by Mark Dickinson in branch '3.5': New changeset 902e82f71880 by Mark Dickinson in branch 'default': |
Thanks, all. Closing as fixed. |
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:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: