You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fraction.__pow__ does not accept the third argument which pow tries to pass to it:
>>> pow(Fraction(1), 1, 1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Fraction.__pow__() takes 2 positional arguments but 3 were given
Other number types don't do that, they support it when they can and print an error message if they don't want to, e.g.
>>> pow(Decimal("1"), 1, 1)
Decimal('0')
>>> pow(Decimal('1'), 1.1, 1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: pow() 3rd argument not allowed unless all arguments are integers
I'm not sure what fraction should do, maybe it should just continue not to support it? Or just accept the argument, and then print a better error message if modulo is not None?
Not supporting a modulus was an intentional choice here.
It's hard to imagine real use-cases would be for supporting the modulus. If m is a positive integer, the collection of integers modulo m has nice arithmetic properties (it's a commutative unital ring), and exponentiation modulo m is a reasonably common operation (e.g., in cryptography). That's no longer true for the collection of fractions modulo m - that set doesn't have an associative multiplication operation, so a power operation is at best ill-defined.
If we want to change the error message (as @terryjreedy pointed out, the exception type is already the right one), the first thing to try would be to return NotImplemented if a third argument is given. That should work, but the special-casing for __pow__ is messy enough that it might not.
changed the title [-]fractions.Fraction.__pow__ can receive 3rd argument from builtin function pow[/-][+]Improve pow(fraction.Fraction(), b, modulo) error message[/+]on May 29, 2024
Activity
terryjreedy commentedon May 27, 2024
Fractions.__pow__should imitate float and Decimal__pow__.Since the exception type is correct, this should be considered an enhancement rather than bug.
PR was a bit premature without agreement of what fix should be.
mdickinson commentedon May 27, 2024
Not supporting a modulus was an intentional choice here.
It's hard to imagine real use-cases would be for supporting the modulus. If
mis a positive integer, the collection of integers modulomhas nice arithmetic properties (it's a commutative unital ring), and exponentiation modulomis a reasonably common operation (e.g., in cryptography). That's no longer true for the collection of fractions modulom- that set doesn't have an associative multiplication operation, so a power operation is at best ill-defined.If we want to change the error message (as @terryjreedy pointed out, the exception type is already the right one), the first thing to try would be to return
NotImplementedif a third argument is given. That should work, but the special-casing for__pow__is messy enough that it might not.mdickinson commentedon May 27, 2024
It does. Results of a quick test:
[-]fractions.Fraction.__pow__ can receive 3rd argument from builtin function pow[/-][+]Improve pow(fraction.Fraction(), b, modulo) error message[/+]gh-119594: Improve pow(fraction.Fraction(), b, modulo) error message (#…
pythongh-119594: Improve pow(fraction.Fraction(), b, modulo) error me…
pythongh-119594: Improve pow(fraction.Fraction(), b, modulo) error me…