-
Notifications
You must be signed in to change notification settings - Fork 311
last() fails if __reversed__ is None, which is the case for the Mapping abc #1001
Copy link
Copy link
Closed
Closed
Copy link
Labels
pr-welcomeWe are open to PRs that fix this issue - leave a note if you're working on it!We are open to PRs that fix this issue - leave a note if you're working on it!
Description
Using last() on this class:
from collections.abc import Mapping
from more_itertools import last
class MyMapping(Mapping):
def __getitem__(self, key):
return 1
def __iter__(self):
return iter([1])
def __len__(self):
return 1
print(last(iter(MyMapping())))
last(MyMapping())
fails with:
Traceback (most recent call last):
File "/nix/store/q3zqcqwmybfda7895g91d75pzbaqj6s5-python3-3.9.20-env/lib/python3.9/site-packages/more_itertools/more.py", line 271, in last
return next(reversed(iterable))
TypeError: 'MyMapping' object is not reversible
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/ibriquem/ws/pyshl/repro.py", line 12, in <module>
last(MyMapping())
File "/nix/store/q3zqcqwmybfda7895g91d75pzbaqj6s5-python3-3.9.20-env/lib/python3.9/site-packages/more_itertools/more.py", line 275, in last
raise ValueError(
ValueError: last() was called on an empty iterable, and no default value was provided.
While it works if you first call iter() on the object.
This is because __reversed__ is set to None by the Mapping base class:
https://github.com/python/cpython/blob/4f28afe5456d8ed4a6fe0099337487043e29c912/Lib/_collections_abc.py#L792
I'd expect it to work.
Maybe this code could be changed from:
if hasattr(iterable, '__reversed__'):
to:
if getattr(iterable, '__reversed__', None) is not None:
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
pr-welcomeWe are open to PRs that fix this issue - leave a note if you're working on it!We are open to PRs that fix this issue - leave a note if you're working on it!