Author zzzeek
Recipients zzzeek
Date 2015-04-09.14:34:45
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1428590086.18.0.0932223784087.issue23898@psf.upfronthosting.co.za>
In-reply-to
Content
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"
History
Date User Action Args
2015-04-09 14:34:46zzzeeksetrecipients: + zzzeek
2015-04-09 14:34:46zzzeeksetmessageid: <1428590086.18.0.0932223784087.issue23898@psf.upfronthosting.co.za>
2015-04-09 14:34:46zzzeeklinkissue23898 messages
2015-04-09 14:34:45zzzeekcreate