SageMath (an open source Python-based mathematics program) can’t fully
implement PEP 3141 (numbers ABC) because thenumbers.Rational
ABC
requires adenominator
property while SageMath uses a
denominator()
method. Note that you can’t blame SageMath for this,
since it predates PEP 3141.
Does denominator need to be a method in SageMath? Why couldn’t they have
used a property?
(Python has had properties since 2.2, which came out in 2001. SageMath’s
initial release was 2005.)
Does the same problem apply to numerator?
Unless there is a solid reason why SageMath has to make the denominator
API a method call instead of a property, they should just deprecate the
current behaviour and use a property.
One way out would be to change PEP 3141 to use dunder names like
__denominator__
instead (this could be a property or method, it
doesn’t really matter).
Of course it matters. In one case the API becomes:
number.__denominator__
and in the other it becomes:
number.__denominator__()
neither of which is the slightest bit Pythonic.
This would be more Pythonic since Python
typically uses dunder names for special attributes. For example,
next
was replaced by__next__
.
Not quite. We replaced calling iterator.next() method with calling a
builtin function next(iterator). That follows the standard pattern in
Python where dunders are typically used for the implementation of
special features, not the public API of those features:
-
we say len(x), not x.len
-
we say x + y, not x.add(y) or y.radd(x)
-
we say next(it), not it.next
Unless you are planning to add a pair of builtins denominator() and
numerator(), I don’t think we should change the API to use dunders
instead of regular attributes.
Of course, the change that I proposed requires some backwards
compatibility measures, but that’s a solvable problem.
To me, it seems that it would seriously break backwards compatibility
for everyone who has implemented the Rational API. Why break everyone
else’s Rationals to save SageMath from having to deprecate their code?
How would you solve changing the Rational API without breaking people’s
code?