Ned Batchelder wrote:

> On 3/15/18 9:57 AM, Vlastimil Brom wrote:
>> 2018-03-15 12:54 GMT+01:00 Arkadiusz Bulski <arek.bul...@gmail.com>:
>>> I have a custom class (a lazy list-like container) that needs to support
>>> slicing. The __getitem__ checks if index is of slice type, and does a
>>> list comprehension over individual integer indexes. The code works fine
>>> on Python 3 but fails on 2.7, both CPython and PyPy. The print inside
>>> __getitem__ doesnt even get executed when its a slice. Does 2.7 have
>>> different object model, where slices are handled by a different method
>>> than __getitem__?
>>>
>>> The implementation and error log
>>> 
https://github.com/construct/construct/blob/8839aac2b68c9e8240e9d9c041a196b0a7aa7d9b/construct/core.py#L4785-L4796
>>> 
https://github.com/construct/construct/blob/8839aac2b68c9e8240e9d9c041a196b0a7aa7d9b/tests/test_core.py#L1148
>>> https://travis-ci.org/construct/construct/jobs/353782126#L887
>>>
>>> --
>>> ~ Arkadiusz Bulski
>>> --
>>> https://mail.python.org/mailman/listinfo/python-list
>> Hi,
>> it looks like, the older method __getslice__ is still used in python 2.7
>> cf.:
>> https://docs.python.org/2/reference/datamodel.html#object.__getslice__
>>
>> You might need to implement this method in your class as well for
>> compatibility with python 2.
>>
>>
> 
> Python 2 will use __getitem__ for slices:
> 
>  $ python2.7
>  Python 2.7.10 (default, May 30 2015, 12:06:13)
>  [GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
>  Type "help", "copyright", "credits" or "license" for more information.
>  >>> class Sliceable(object):
>  ...     def __getitem__(self, thing):
>  ...         print type(thing)
>  ...         print thing
>  ...
>  >>> Sliceable()[1:5]
>  <type 'slice'>
>  slice(1, 5, None)
>  >>> Sliceable()[:]
>  <type 'slice'>
>  slice(None, None, None)
>  >>>

__getslice__() takes precedence, and the OP subclasses list:

$ python
Python 2.7.6 (default, Nov 23 2017, 15:49:48) 
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class A(list):
...     def __getitem__(self, index): return index
... 
>>> a = A()
>>> a[:]
[]
>>> a[::]
slice(None, None, None)
>>> A.__getslice__ = lambda self, *args: args
>>> a[:]
(0, 9223372036854775807)


-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to