Andy Maier added the comment:
Using Ethan's sample code (Thanks!!), I was pointed in the right direction and
was able to produce a simple piece of code that reproduces the behavior without
depending on enum34, as well as a proposal for a fix in pydoc.py.
The problem can be reproduced with a class that specifies a metaclass that has
class attributes and includes these class attributes in its __dir__() result,
which causes them to "propagate" as class attributes to the class using that
metaclass, at least for the purposes of pydoc.
In the course of the processing within pydoc.py, the tuple returned by
inspect.classify_class_attrs() for such class attributes then has None for its
class item, which triggers the issue I originally reported (pydoc traps and
produces just a dummy help description).
In my original problem with the enum34 module, the same thing happens, just
here the "propagated" class attributes include the __members__ list, which is
defined as a property. So I do believe that my simple code represents the same
error situation as the original enum34 issue.
Because pydoc.py already has its own classify_class_attrs() function that
wrappers inspect.classify_class_attrs() for the purpose of treating data
descriptors correctly, I think it would be acceptable to continue down the path
of fixing it up, just this case for class attributes propagated by the
metaclass. That's what my proposed fix does.
Unfortunately, it seems one can attach only one file, so I paste the
reproduction code in here, and attach the fixed pydoc.py.
Here is the code that reproduces the issue:
---------------- bug2.py
# Boolean test switches that control whether a class variable of the metaclass
# is added to the dir() result.
# If the fix is not present, then enabling each one triggers the error
# behavior; If none of them is enabled, the error behavior is not triggered.
with_food = True # Add the 'normal' class attribute 'food'
with_drink = True # Add the property-based class attribute 'drink'
class FoodMeta(type):
"""Metaclass that adds its class attributes to dir() of classes using it."""
food = 'ham' # 'normal' class attribute
@property
def drink(cls): # property-based class attribute
return 'beer'
def __dir__(cls):
ret = [name for name in cls.__dict__] # the normal list
if with_food:
ret += ['food']
if with_drink:
ret += ['drink']
print "bug2.FoodMeta.__dir__(): return=%s" % (repr(ret),)
return ret
class Food(object):
"""docstring for Food class"""
__metaclass__ = FoodMeta
def diet(self):
return "no!"
if __name__ == '__main__':
print "bug2: Calling help(Food):"
help(Food)
----------------
-> Please review the reproduction code and the fix and let me know how to
proceed.
Andy
----------
Added file: http://bugs.python.org/file35501/pydoc_fix2.py
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue21561>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com