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 <rep...@bugs.python.org>
<http://bugs.python.org/issue23898>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to