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
isinstance(cls_with_metaclass, non_type) raises KeyError #84361
Comments
Consider class Object defined as follows: import types
class Type(type):
__class__ = property({}.__getitem__, {}.__setitem__)
class Object(metaclass=Type):
__slots__ = '__class__' isinstance(Object, ob) is true for type and Type and false for anything else. But for the examples of the latter that I tried, (list, int, types.CodeType, types.MethodType, see attached tem3.py), it incorrectly raises I cannot find the C source for isinstance. In Python/bltinmodule.c, function builtin_isinstance_impl wraps |
What would you expect in this case? Objects/abstract.c:2429 is where the isinstance code. If only returning False would be enough, something like this (untested) would be enough --- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -2436,6 +2436,10 @@ object_isinstance(PyObject *inst, PyObject *cls)
retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
if (retval == 0) {
retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls);
+ if (retval == NULL && PyErr_Occurred()) {
+ PyErr_Clear();
+ retval = 0;
+ } |
All works as expected to me. Your __class__ attribute raise an arbitrary exception, and it is expected, that the code which uses it passes it to you. I am against silencing all exceptions. It may hide bugs. It is even documented. See What's New in Python 3.8:
|
(Serhiy posted while I wrote this.) My knowledge of the C codebase is insufficient to review, let alone write, non-trivial changes. But I was curious where and why Object itself was being used as a key. I presume Issue background. The example is from Dan Snider, OP of bpo-38689. When he typed 'Object(' into IDLE, IDLE tried to pop up a calltip. But inspect.signature(Object) failed with the (unexpected and undocumented) KeyError when it called isinstance(Object, types.MethodTypes), and IDLE froze. Given Python's flexibility, it can be hard to write code that works with any user code thrown at it. |
You take it too literally. It does not mean that the function always returns a value. It can also raise an exception. If you press Ctrl-C it may raise an exception. If there is no memory to create some temporary objects, it may raise an exception. If you turn of the computer, it may neither return a value nor raise an exception. You created a class whose __class__ attribute always raises an exception. What do you expect to get when you use this attribute? {}.__getitem__ always raise a KeyError, because an empty dict does not contain any key. |
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: