New submission from Vedran Čačić:

During the discussion about http://bugs.python.org/issue27539, we found the 
following weird behavior:

    >>> from fractions import Fraction as F
    >>> F(2, 3, 4)
    Fraction(2, 3)

It looks like the third argument is simply disregarded, but it's not so: if 
it's false, the fraction is not normalized, and it breaks a lot of arithmetic 
assumptions.

    >>> F(4, 2, 0)
    Fraction(4, 2)
    >>> _ == 2
    False

The secret is additional argument "_normalize" to Fraction.__new__, which was 
added for optimization in various cases (where we know that numerator and 
denominator are relatively prime, so the gcd needn't be computed). That 
argument was obviously meant for internal use only (its name starts with '_'), 
so accepting the above forms can be viewed as a bug. Although cases can be made 
for being able to set that argument from the outside, surely in most cases 
people passing 3 arguments are doing it by accident, not on purpose.

That bug is easily fixed, by declaring the argument as keyword only. The line 
84 in lib/fractions.py should be changed from

-     def __new__(cls, numerator=0, denominator=None, _normalize=True):

to

+     def __new__(cls, numerator=0, denominator=None, *, _normalize=True):

That way, those who know what they are doing, can still pass the _normalize 
argument, but it's much harder to accidentally pass it for people who don't 
know nor care about it.

Of course, all the code from that file already passes _normalize by keyword, so 
no other code should be changed.

----------
messages: 273422
nosy: veky
priority: normal
severity: normal
status: open
title: fractions.Fraction with 3 arguments: error passes silently

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue27832>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to