[Python-Dev] Symmetry arguments for API expansion
Steven D'Aprano
steve at pearwood.info
Tue Mar 13 07:53:07 EDT 2018
On Mon, Mar 12, 2018 at 09:49:27AM -0700, Raymond Hettinger wrote:
> * We already have a simple, traditional, portable, and readable way to
> make the test: int(x) == x
Alas, the simple way is not always the correct way:
py> x = float('inf')
py> x == int(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: cannot convert float infinity to integer
So to be correct, you need to catch OverflowError, ValueError (in case
of NANs), and TypeError (in case of complex numbers).
Or guard against them with isinstance() and math.isfinite() tests. But
doing so has its own problems:
py> x = Decimal('snan')
py> math.isfinite(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: cannot convert signaling NaN to float
> * In the context of ints, the test x.is_integer() always returns True.
> This isn't very useful.
It is if you don't know what type x is ahead of time.
if x.is_integer():
versus:
if isinstance(x, int) or isinstance(x, float) and x.is_integer()
> Does it cost us anything?
> * Yes, adding a method to the numeric tower makes it a requirement for
> every class that ever has or ever will register or inherit from the
> tower ABCs.
Could the numeric tower offer a default implementation that should work
for most numeric types? The default could possibly even be
int(self) == self
Then you only have to implement your own if you have special cases to
consider, like floats, or can optimise the test. Many numbers ought to
know if they are integer valued, without bothering to do a full
conversion to int. For example, Fractions could return
self.denominator == 1
as a cheap test for integerness.
> * Adding methods to a core object such as int() increases the
> cognitive load for everyday users who look at dir(), call help(), or
> read the main docs.
This is a good point, but not an overwhelming one.
> What does "API Parsimony" mean?
> * Avoidance of feature creep.
> * Preference for only one obvious way to do things.
> * Practicality (not craving things you don't really need) beats purity (symmetry and foolish consistency).
> * YAGNI suggests holding off in the absence of clear need.
> * Recognition that smaller APIs are generally better for users.
A very nice list! Thank you for that!
But the last one is true only to a point. It is possible to be too
small. (The Python 1.5 API is *much* smaller than Python 3.6. I don't
think that it was better.) And consider that a *consistent* API is often
more important than a *minimalist* API.
--
Steve
More information about the Python-Dev
mailing list