On 4/4/2013 10:04 PM, Steven D'Aprano wrote:

When I call int(), I'm expecting an int.

We agree so far...,

> That includes well-behaved subclasses of int that continue to behave
> like ints in all the ways that matter.

but not here. I currently expect an actual int instance for 3 reasons.

1. As I read the doc, that is the currently documented 'should'.

2. I believe class constructors should, generally, return an instance of the class, in the narrow sense, and that factory functions should, generally, be used to return instances of multiple classes. The multiple classes would typically, or at least often, all be subclasses of some baseclass.

3. Most apropos to your next paragraph: *because* Python is duck-typed, I would not replace a function arg that might be an int subclass with int(arg) unless (I thought) the difference would make a difference.

Lets consider cases:

1. int(non-scalar-number): this is usually an error, except for bytes or unicode strings that represents a number in standard base-[2-32] notation. int has builtin knowledge of these two builtin classes. One can add an __int__ method to string subclasses that represent integers with non-standard notation.

A common use is int(input(prompt)) or int(other-external-input).

2. int(rational): for floats, Fractions, and Decimals, this returns the integral part, truncating toward 0. Decimal and float have __int__ methods. Fractions, to my surprise, does not, so int must use __floor__ or __round__ as a backup.

I believe we have no disagreement that int() should return an int for these cases. Here is a possible use for input checking.

def fib(n):
  "return fibonnaci(integral input); return type == input type"
  if int(n) != n or n < 0:
     raise TypeError('fib input must be a count')
  # let int() or < exception propagate
  # the input check is needed to prevent infinite looping
  <calculate with input n>
  return fib-of-n

Because of duck-typing, there is no need to replace n with int(n). The return type will be the input type.

3. int(int-subclass-instance): If the int subclass instances behave like an int in all ways that matter in the context, there is no reason to specifically do. In other words, this use should be very rare, such as wanting the int repr. I am also not sure, without checking the doc for the definition of the bit operations, if all int subclasses would dependably substitute in bit manipulations. So unless you can give a good reason otherwise, I think the subclass .__int__ class should assume that the programmer might actually specifically want an int instance.

In the example above, int() is part of a general case 2 input check that non-negative subclass instances should pass whether they return themselves or an int.

It's curious to see the (d)evolution of thinking on type checking in
Python circles. Once upon a time, type checking was discouraged,
duck-typing was encouraged, and the philosophy was that an int is
anything that behaves like an int.

I always differentiated 'int' as a type/class int object from 'integer' as anything that behaves like an 'int'. For me, and the function outlined above, that includes integer-values rationals along with int subclass instances.

Now type-checking is tolerated or
even encouraged, provided that you use isinstance,

I seem to have missed the encouragement.

> and an int is anything that inherits from the builtin (or the ABC).
And this proposed change in behaviour

To conform to how come read the doc..

> continues the move away from Python's former emphasis on duck-typing.

For the reason explained above, I do not see this issue in such apocalyptic terms ;-)

--
Terry Jan Reedy



_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to