Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
assignee=Noneclosed_at=<Date2017-10-21.17:18:52.387>created_at=<Date2016-09-26.18:13:46.369>labels= ['interpreter-core', 'type-feature', '3.7']
title='Always return a list from PyMapping_Keys/PyMapping_Values/PyMapping_Items'updated_at=<Date2017-10-21.17:18:52.386>user='https://github.com/serhiy-storchaka'
PyMapping_Keys(), PyMapping_Values() and PyMapping_Items() can return a list or tuple (because they use PySequence_Fast). But end users of this API often work only with lists and raise an exception if corresponding mapping methods return an instance of other type (actually only for tuples). See Modules/posixmodule.c, Modules/_winapi.c, Modules/_sre.c. The type is even not checked in the latter file.
Old documentation said that PyMapping_Keys(o) is equivalent to the Python expression list(o.keys()). Maybe it is worth to make this true. Make PyMapping_Keys(o) etc always returning a list. This could simplify the code that uses this C API. Since keys() etc usually return a dict view, a list or a generator, but not a tuple, this unlikely will cause performance regression.
I would be happy to write a PR that implements that.
However, i am not sure which way is better to construct a list from the return
value (an iterable, hopefully) of keys() etc.:
Call PyList_Type() (in each of PyMapping_Keys() etc.) on the iterable, and
overwrite the error message in case it is a TypeError.
Write a helper function iterable_as_list(), which uses PyObject_GetIter() and
PySequence_List(), and call it in each of PyMapping_Keys() etc..
(iterable_as_list() would receive "keys" etc., so that it would raise the
appropriate error message, in case of a TypeError.)
ISTM that the first one is simpler, but I am not sure about the performance
difference between them.