classification
Title: dictobject dictviews don't return NotImplemented for unrecognized types.
Type: behavior Stage: test needed
Components: Versions: Python 3.9, Python 3.8, Python 3.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: mdk, methane
Priority: normal Keywords:

Created on 2019-10-20 15:32 by mdk, last changed 2019-11-22 20:58 by mdk.

Messages (5)
msg355007 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2019-10-20 15:32
In the following snippet:

    >>> class Ror:
    ...     def __ror__(self, other):
    ...         return set()
    ...
    >>> {}.keys() | Ror()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'Ror' object is not iterable

I expect the __or__ implementation of dict_keys to return NotImplemented when given a non-interesting thing, so my __ror__ can run and get an empty set instead of a TypeError.

Strangely enough, it worked in Python 2.7, I'm not fluent enough en 2.7 object nor C implementation to know why, the dictviews_or looks the same for me.

It looks easy to fix without breaking the tests in dictobject.c like:

    --- a/Objects/dictobject.c
    +++ b/Objects/dictobject.c
    @@ -4284,7 +4284,8 @@ dictviews_or(PyObject* self, PyObject *other)
         tmp = _PyObject_CallMethodIdOneArg(result, &PyId_update, other);
         if (tmp == NULL) {
             Py_DECREF(result);
    -        return NULL;
    +        PyErr_Clear();
    +        Py_RETURN_NOTIMPLEMENTED;
         }

the question is more: should we? I think so but am I missing something?
msg355032 - (view) Author: Inada Naoki (methane) * (Python committer) Date: 2019-10-21 09:11
> Strangely enough, it worked in Python 2.7

It is not strange since dict.keys() in Python 2.7 returns list.

>>> {}.viewkeys() | Ror()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: iteration over non-sequence
msg355155 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2019-10-22 20:47
> It is not strange since dict.keys() in Python 2.7 returns list.

Oh, ok thanks :)

Do you think that it should be fixed? As it works with sets, I think so:

>>> set() | Ror()
set()

but it's not that simple as the __or__ of dictviews is less strict that the __or__ of set: __or__ of dictview accept any iterable, __or__ of set only accepts sets.
msg355517 - (view) Author: Inada Naoki (methane) * (Python committer) Date: 2019-10-28 08:29
> but it's not that simple as the __or__ of dictviews is less strict that the __or__ of set: __or__ of dictview accept any iterable, __or__ of set only accepts sets.

I want to make it same to set.
But it is a backward incompatible...
msg357322 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2019-11-22 20:58
Let's start slowly by warning when a non-set is given to the __or__ of dictview?

I think it is just a side effect of the current implementation, not a feature.
History
Date User Action Args
2019-11-22 20:58:55mdksetmessages: + msg357322
2019-10-28 08:29:38methanesetmessages: + msg355517
2019-10-25 19:38:13terry.reedysetstage: test needed
versions: - Python 3.5, Python 3.6
2019-10-22 20:47:29mdksetmessages: + msg355155
2019-10-21 09:11:04methanesetmessages: + msg355032
2019-10-20 15:51:51xtreaksetnosy: + methane
2019-10-20 15:32:28mdkcreate