[Python-bugs-list] [ python-Bugs-576990 ] inheriting from property and docstrings
noreply@sourceforge.net
noreply@sourceforge.net
Tue, 09 Jul 2002 04:52:36 -0700
Bugs item #576990, was opened at 2002-07-03 14:42
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=576990&group_id=5470
Category: Python Interpreter Core
Group: Python 2.2.1
Status: Open
Resolution: None
Priority: 5
Submitted By: Roeland Rengelink (rengelink)
Assigned to: Nobody/Anonymous (nobody)
Summary: inheriting from property and docstrings
Initial Comment:
If I inherit from property, and try to initialize a derived
property object, the doc string doesn't get set. This bug
was introduced in 2.2.1, and is present in 2.3a0:
Compare:
Python 2.2 (#1, Mar 26 2002, 15:46:04)
[GCC 2.95.3 20010315 (SuSE)] on linux2
Type "help", "copyright", "credits" or "license" for more
information.
>>> class myprop(property):pass
...
>>> a = myprop(None, None, None, 'hi')
>>> print a.__doc__
hi
and,
Python 2.2.1 (#1, Jun 16 2002, 16:19:48)
[GCC 2.95.3 20010315 (SuSE)] on linux2
Type "help", "copyright", "credits" or "license" for more
information.
>>> class myprop(property):pass
...
>>> a = myprop(None, None, None, 'hi')
>>> print a.__doc__
None
There is no problem with the getter/setter functions
passed to the constructor. i.e.: myprop(f,g,h,None) works
identical in 2.2 and 2.2.1
Good luck,
Roeland Rengelink
----------------------------------------------------------------------
>Comment By: Roeland Rengelink (rengelink)
Date: 2002-07-09 11:52
Message:
Logged In: YES
user_id=302601
I think I found the problem,
Compare:
>>> property.__doc__
'property(fget=None,.... # the doc string
and
>>> property.__dict__['__doc__']
<member '__doc__' of 'property' objects>
Note that property.__doc__ and property.__dict__['__doc__']
are not the same. Python will go out of its way to prevent this
weird situation in user derived classes.,
1. type_new(name, bases, attrs) will copy attrs to
new_tp.tp_dict, and will also copy attrs['__doc__'] to tp.tp_doc
2. PyType_Ready(tp) will copy tp.tp_doc to
tp.tp_dict['__doc__'] if tp.tp_dict['__doc__'] is undefined
This guarantees that tp.tp_dict['__doc__'] will exist, usually
copying tp.tp_doc, and shadowing property.tp_dict['__doc__']
if tp is derived from property
The solution seems to be:
1. In type_new():
if possible copy attr['__doc__'] to tp.tp_doc, and delete
__doc__ from attr (to prevent ending up in tp_dict)
2. in PyType_Ready():
don't copy tp.tp_doc to tp_dict['__doc__']
These two steps make sure that, tp_dict['__doc__'] no longer
shadows properties.tp_dict['__doc__']. Unfortunately, this
means that tp.__doc__ doesn't generally return the docstrings
for user-defined types. Therefore:
3. in type_get_doc():
return tp.tp_doc also for heap types.
The result of this will be:
1. properties will be subclassable again. (good)
2. __doc__ string become read-only attributes (bad??)
3. test cases in test_descr that assume that
instance.__dict__['__doc__'] exists, will fail
4. a weird test_failure in test_module.py
Patches for this modification are attached, except for
(test_module.py), which I don't understand.
----------------------------------------------------------------------
Comment By: Roeland Rengelink (rengelink)
Date: 2002-07-08 12:23
Message:
Logged In: YES
user_id=302601
Some more details:
In fact 2.2.1 is consistently wrong, whereas 2.2 is
inconsistently right ;), compare:
Python 2.2.1 (#20, Jul 8 2002, 13:25:14)
[GCC 3.1] on linux2
Type "help", "copyright", "credits" or "license" for more
information.
>>> class myprop(property):pass
...
>>> class yourprop(property):
... "A doc string"
...
>>> print myprop(None, None, None, 'Hi there').__doc__
None
>>> print yourprop(None, None, None, 'Hi there').__doc__
A doc string
and
Python 2.2 (#4, Jan 7 2002, 11:59:25)
[GCC 2.95.2 19991024 (release)] on linux2
Type "help", "copyright", "credits" or "license" for more
information.
>>> class myprop(property):pass
...
>>> class yourprop(property):
... "A doc string"
...
>>> print myprop(None, None, None, 'Hi there').__doc__
Hi there
>>> print yourprop(None, None, None, 'Hi there').__doc__
A doc string
So, in 2.2.1 myprop(...).__doc__ will allways return
myprop.__doc__. In 2.2 myprop.__doc__ will return the
instance's
__doc__, iff myprop.__doc__ is None.
For the record: I was expecting 'Hi there' (i.e.
obj->prop_doc), as in:
>>> property(None, None, None, 'Hi there').__doc__
'Hi there'
Hope this helps,
Roeland
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=576990&group_id=5470