homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Incorrect __text_signature__ for sorted
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.7, Python 3.6, Python 3.5
process
Status: closed Resolution: fixed
Dependencies: 26282 Superseder:
Assigned To: serhiy.storchaka Nosy List: eriknw, martin.panter, ncoghlan, python-dev, rhettinger, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2016年04月10日 17:54 by eriknw, last changed 2022年04月11日 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
sorted_1.diff eriknw, 2016年04月10日 17:54 Update the docstring of sorted builtin review
sorted_2.patch eriknw, 2016年04月12日 05:37 flexible call signature; sorted matches original __text_signature__ review
sorted_3.patch eriknw, 2016年04月12日 13:16 Correct __text_signature__ for sorted. Behavior unchanged. review
Messages (13)
msg263145 - (view) Author: Erik Welch (eriknw) * Date: 2016年04月10日 17:54
The first argument to sorted is positional-only, so the text signature should be:
sorted($module, iterable, /, key=None, reverse=False)
instead of
sorted($module, iterable, key=None, reverse=False)
To reproduce the issue, attempt to use "iterable" as a keyword argument:
>>> import inspect
>>> sig = inspect.signature(sorted)
>>> sig.bind(iterable=[]) # should raise, but doesn't
>>> sorted(iterable=[]) # raises TypeError
msg263155 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016年04月10日 22:46
This is a strange case. It looks like "iterable" is half-supported as a keyword argument. So Silent Ghost’s patch fixes the signature, but the code still tries to accept keyword arguments:
>>> sorted(iterable=None)
TypeError: 'NoneType' object is not iterable
>>> sorted(iterable=())
TypeError: 'iterable' is an invalid keyword argument for this function
The problem is that sorted() blindly passes the keyword arguments to list.sort(). I guess we could delete "iterable" from them, but maybe it is not worth the trouble.
msg263222 - (view) Author: Erik Welch (eriknw) * Date: 2016年04月12日 05:36
Interesting observation, Martin.
Upon further consideration, the call signature for sorted really is quite odd. It doesn't behave like any other builtin function. Currently, "iterable" is positional-only, and "key=" and "reverse=" are keyword only. I would only expect such behavior for functions with variadic *args.
I uploaded a new patch so that the call signature matches the original __text_signature__. This means "iterable" may be given as a keyword argument, and "key" and "reverse" may be given as positional arguments.
I added tests for the new behavior, and all tests pass for me.
msg263227 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2016年04月12日 05:50
I don't think we should start down the path of changing APIs just to accommodate weakness in the generation of the text signature.
We don't want to encourage unreadable oddities like sorted(reverse=False, iterable=source). Best readability comes from the required positional argument for the iterable. Please don't create a new and unnecessary keyword argument. The current API is intentional.
msg263230 - (view) Author: Erik Welch (eriknw) * Date: 2016年04月12日 06:16
That's a fair and valid point, Raymond. "sorted_2.patch" was submitted for consideration. Either __text_signature__ is wrong, or the call argument handling is wrong. One should be fixed.
Having a flexible call signature as if sorted were a user-defined function, such as "def sorted(iterable, key=None, reverse=False):", does allow for programmatic use of the introspected signature. Here, using "iterable=" as a keyword can be convenient.
"sorted_1.diff" is wrong. To match the existing call signature, __text_signature__ should be:
sorted($module, iterable, /, *, key=None, reverse=False)
I don't know any other builtin with a signature like this. Such a signature may be a point of confusion for people learning Python ("what are those funny symbols?!"), who often encounter sorted early on.
msg263231 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016年04月12日 06:20
See issue26282.
msg263238 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2016年04月12日 08:42
+1 for Serhiy's suggestion of enhancing the C API to specifically handle these cases.
msg263244 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016年04月12日 12:37
I didn’t realize about the keyword-only parameters. This is inherited from list.sort(). The signature can be corrected in 3.5.
There is also Issue 21314 about documenting the slash notation for signatures (it comes from PEP 457).
msg263246 - (view) Author: Erik Welch (eriknw) * Date: 2016年04月12日 13:16
sorted_3.patch corrects the __text_signature__. Behavior of sorted is unchanged.
>>> def raises(err, lamda):
... try:
... lamda()
... return False
... except err:
... return True
...
>>> import inspect
>>> sig = inspect.signature(sorted) 
>>> # `iterable` is positional-only
>>> assert raises(TypeError, lambda: sorted(iterable=[]))
>>> assert raises(TypeError, lambda: sig.bind(iterable=[]))
>>> # `key` and `reverse` are keyword-only
>>> assert raises(TypeError, lambda: sorted([], lambda x: x))
>>> assert raises(TypeError, lambda: sig.bind([], lambda x: x))
msg263280 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016年04月12日 22:21
Patch 3 looks okay to me.
msg285923 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017年01月20日 21:10
See also issue29327 and issue29331.
sorted_3.patch LGTM.
msg286063 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017年01月23日 09:07
Serhiy, do you want to apply this?
msg286069 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2017年01月23日 10:31
New changeset c0a9fb3e19b9 by Serhiy Storchaka in branch '3.5':
Issue #26729: Fixed __text_signature__ for sorted().
https://hg.python.org/cpython/rev/c0a9fb3e19b9
New changeset fcb19fb42058 by Serhiy Storchaka in branch '3.6':
Issue #26729: Fixed __text_signature__ for sorted().
https://hg.python.org/cpython/rev/fcb19fb42058
New changeset 4ad195d9e184 by Serhiy Storchaka in branch 'default':
Issue #26729: Fixed __text_signature__ for sorted().
https://hg.python.org/cpython/rev/4ad195d9e184 
History
Date User Action Args
2022年04月11日 14:58:29adminsetgithub: 70916
2017年01月23日 10:31:57serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: commit review -> resolved
2017年01月23日 10:31:20python-devsetnosy: + python-dev
messages: + msg286069
2017年01月23日 09:07:48rhettingersetmessages: + msg286063
2017年01月23日 08:57:04rhettingersetassignee: rhettinger -> serhiy.storchaka
2017年01月20日 21:10:31serhiy.storchakasetstage: patch review -> commit review
messages: + msg285923
versions: + Python 3.7
2016年04月12日 22:21:38martin.pantersetmessages: + msg263280
2016年04月12日 13:16:17eriknwsetfiles: + sorted_3.patch

messages: + msg263246
2016年04月12日 12:37:07martin.pantersetmessages: + msg263244
2016年04月12日 08:42:18ncoghlansetdependencies: + Add support for partial keyword arguments in extension functions
messages: + msg263238
2016年04月12日 06:20:24serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg263231
2016年04月12日 06:16:37eriknwsetmessages: + msg263230
2016年04月12日 05:50:04rhettingersetassignee: rhettinger

messages: + msg263227
nosy: + rhettinger
2016年04月12日 05:37:01eriknwsetfiles: + sorted_2.patch

messages: + msg263222
2016年04月10日 22:46:59martin.pantersetnosy: + martin.panter
messages: + msg263155
2016年04月10日 18:49:01SilentGhostsetnosy: + ncoghlan
stage: patch review

components: + Interpreter Core, - Extension Modules, Library (Lib)
versions: + Python 3.6
2016年04月10日 17:54:40eriknwcreate

AltStyle によって変換されたページ (->オリジナル) /