-
-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect __text_signature__ for sorted #70916
Comments
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:
|
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. |
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. |
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. |
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. |
See bpo-26282. |
+1 for Serhiy's suggestion of enhancing the C API to specifically handle these cases. |
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)) |
Patch 3 looks okay to me. |
Serhiy, do you want to apply this? |
New changeset c0a9fb3e19b9 by Serhiy Storchaka in branch '3.5': New changeset fcb19fb42058 by Serhiy Storchaka in branch '3.6': New changeset 4ad195d9e184 by Serhiy Storchaka in branch 'default': |
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
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: