STINNER Victor added the comment:

If __eq__() raise an exception, _PyDict_GetItem_KnownHash() currently returns 
NULL and pass through the exception. To me, it looks like the correct behaviour.

With your patch, it looks like the _PyDict_GetItem_KnownHash() clears the 
__eq__() exception: return NULL with no exception set, as if the key is simply 

PyDict_GetItem() ignores *almost* all exceptions, but for bad reasons:

/* Note that, for historical reasons, PyDict_GetItem() suppresses all errors
 * that may occur (originally dicts supported only string keys, and exceptions
 * weren't possible).  (...) */

I would prefer to not ignore __eq__ exceptions, but pass them through.

To be clear: this is a behaviour change compared to Python 3.5 which works as 
PyDict_GetItem(), ignore *all* exceptions:

        ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr);
        if (ep == NULL) {
            return NULL;

I consider that it's ok to change _PyDict_GetItem_KnownHash() behaviour because 
this function is private and only used 4 times in 250k lines of C code.

Would you be interested to write a different patch to pass through the 

Note: It seems like _count_elements() (Modules/_collectionsmodule.c) doesn't 
handle correctly such error.


Python tracker <>
Python-bugs-list mailing list

Reply via email to