classification
Title: Always return a list from PyMapping_Keys/PyMapping_Values/PyMapping_Items
Type: enhancement Stage: resolved
Components: Interpreter Core Versions: Python 3.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Oren Milman, rhettinger, serhiy.storchaka, xiang.zhang
Priority: normal Keywords: patch

Created on 2016-09-26 18:13 by serhiy.storchaka, last changed 2017-10-21 17:18 by serhiy.storchaka. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 3840 merged Oren Milman, 2017-09-30 21:19
Messages (5)
msg277443 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-09-26 18:13
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.
msg303340 - (view) Author: Oren Milman (Oren Milman) * Date: 2017-09-29 16:52
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.
msg303348 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-09-29 18:00
PySequence_List() is the simplest way in C. I don't know whether we need special error messages now. But for compatibility keep them.
msg303413 - (view) Author: Oren Milman (Oren Milman) * Date: 2017-09-30 14:48
(for knowledge preservation's sake)
Resolving this issue would also resolve #31486.
msg303902 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-10-08 08:17
New changeset 0ccc0f6c7495be9043300e22d8f38e6d65e8884f by Serhiy Storchaka (Oren Milman) in branch 'master':
bpo-28280: Make PyMapping_Keys(), PyMapping_Values() and PyMapping_Items() always return a list (#3840)
https://github.com/python/cpython/commit/0ccc0f6c7495be9043300e22d8f38e6d65e8884f
History
Date User Action Args
2017-10-21 17:18:52serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2017-10-08 08:17:49serhiy.storchakasetmessages: + msg303902
2017-09-30 21:19:48Oren Milmansetkeywords: + patch
stage: patch review
pull_requests: + pull_request3821
2017-09-30 14:48:29Oren Milmansetmessages: + msg303413
2017-09-29 18:00:34serhiy.storchakasetmessages: + msg303348
2017-09-29 16:52:28Oren Milmansetnosy: + Oren Milman
messages: + msg303340
2016-09-26 18:13:46serhiy.storchakacreate