I've just improving test coverage for a library that has to support slices and I've noticed that slices can contain non-integral types:
>>> slice(1, "2", 3.0)
slice(1, '2', 3.0)
>>> sl = slice(1, "2", 3.0)
>>> [1,2,3][sl]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: slice indices must be integers or None or have an __index__ method
This might just be my static-typing background but it seems strange to me that the builtin types without __index__
can be passed in here without a TypeError
. Why is this so? Would I be right in assuming that arbitrary types are allowed in order to support duck typing for types that implement __index__
? Is the lack of a type check due to performance reasons for the most commonly used cases?
Prior to PEP 357 was the slice in the example invalid?
Third-party libraries may want to implement slicing for their own objects, and there's no reason for the core language to restrict those third-party libraries to only using integers or integer-like objects (i.e., objects whose type provides the __index__
method) in their slices. Here are two notable examples of packages using non-integers in slicing: in NumPy, some objects accept a complex step, for example:
>>> import numpy
>>> numpy.mgrid[0:2:5j]
array([ 0. , 0.5, 1. , 1.5, 2. ])
And in Pandas, you can slice a Series
or Dataframe
object by label. That label could be a string, or a datetime
object (for example).
>>> import pandas
>>> s = pandas.Series(range(4), index=['a', 'b', 'c', 'd'])
>>> s['b':'d']
b 1
c 2
d 3
dtype: int64
So it wouldn't make sense for the core language to raise an exception when constructing a slice containing non-integers; that would break the above libraries. Instead, the actual slicing operation should raise an exception if the slice components (start, stop, step) are not of the appropriate type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With