[New-bugs-announce] [issue23898] inspect() changes in Python3.4 are not compatible with objects that implement special __bool__, __eq__

mike bayer report at bugs.python.org
Thu Apr 9 16:34:46 CEST 2015


New submission from mike bayer:

this bug appeared in Python 3.4.    The inspect.classify_class_attrs compares the identity objects of unknown type using the `==` operator unnecessarily and also evaluates objects of unknown type assuming they return `True` for a straight boolean evaluation.  This breaks among other things the ability to use the help() function with SQLAlchemy mapped objects.

Demo:

class MySpecialObject(object):

    def __eq__(self, other):
        return MySpecialObject()

    def __bool__(self):
        raise NotImplementedError(
            "This object does not specify a boolean value")


class MyClass(object):
    some_thing = MySpecialObject()

import inspect

print(inspect.classify_class_attrs(MyClass))

# ultimate goal:  help(MyClass)

A patch here would be to compare unknown objects for identity using the `is` operator as well as using `is not None` when asserting that an object of unknown type is non-None.   This patch resolves:

--- inspect_orig.py	2015-04-09 10:28:46.000000000 -0400
+++ inspect.py	2015-04-09 10:29:37.000000000 -0400
@@ -380,7 +380,7 @@
                     # first look in the classes
                     for srch_cls in class_bases:
                         srch_obj = getattr(srch_cls, name, None)
-                        if srch_obj == get_obj:
+                        if srch_obj is get_obj:
                             last_cls = srch_cls
                     # then check the metaclasses
                     for srch_cls in metamro:
@@ -388,7 +388,7 @@
                             srch_obj = srch_cls.__getattr__(cls, name)
                         except AttributeError:
                             continue
-                        if srch_obj == get_obj:
+                        if srch_obj is get_obj:
                             last_cls = srch_cls
                     if last_cls is not None:
                         homecls = last_cls
@@ -402,7 +402,7 @@
             # unable to locate the attribute anywhere, most likely due to
             # buggy custom __dir__; discard and move on
             continue
-        obj = get_obj or dict_obj
+        obj = get_obj if get_obj is not None else dict_obj
         # Classify the object or its descriptor.
         if isinstance(dict_obj, staticmethod):
             kind = "static method"

----------
components: Library (Lib)
messages: 240331
nosy: zzzeek
priority: normal
severity: normal
status: open
title: inspect() changes in Python3.4 are not compatible with objects that implement special __bool__, __eq__
versions: Python 3.4

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue23898>
_______________________________________


More information about the New-bugs-announce mailing list