Overriding tp_getset attribute in subclasses

T

Thomas Heller

I have a subclassable type implemented in C, which has a 'value'
attribute implemented in the tp_getset slot. The type is named c_long.
The value attribute accepts and returns integers.

Now I want to derive a subclass 'BOOL' (in Python) from it, where the
'value' attribute should accept and return bool instances:

from ctypes import c_long

class BOOL(c_long):
def _get_value(self):
return bool(c_long.value.__get__(self))
# this also works:
# return bool(super(BOOL, self).value)

def _set_value(self, val):
c_long.value.__set__(self, val)
# this does not work:
# super(BOOL, self).value = val

value = property(_get_value, _set_value)

I had expected the commented out super() calls to also do the work, but
at least in the _set_value method it does not work:

File "c:\sf\ctypes\win32\wintypes.py", line 37, in _set_value
super(BOOL, self).value = val
TypeError: 'super' object has only read-only attributes (assign to .value)

The c_long.value.__get__ and c_long.value.__set__ variants work, but
they look strange - is there a better way?

Thanks,


Thomas
 
M

Michael Hudson

Thomas Heller said:
I have a subclassable type implemented in C, which has a 'value'
attribute implemented in the tp_getset slot. The type is named c_long.
The value attribute accepts and returns integers.

Now I want to derive a subclass 'BOOL' (in Python) from it, where the
'value' attribute should accept and return bool instances:

from ctypes import c_long

class BOOL(c_long):
def _get_value(self):
return bool(c_long.value.__get__(self))
# this also works:
# return bool(super(BOOL, self).value)

def _set_value(self, val):
c_long.value.__set__(self, val)
# this does not work:
# super(BOOL, self).value = val

value = property(_get_value, _set_value)

I had expected the commented out super() calls to also do the work, but
at least in the _set_value method it does not work:

File "c:\sf\ctypes\win32\wintypes.py", line 37, in _set_value
super(BOOL, self).value = val
TypeError: 'super' object has only read-only attributes (assign to .value)

A bug on SF just like this just got closed, and this text added to the
documentation:

Note that \function{super} is implemented as part of the binding
process for explicit dotted attribute lookups such as \samp{super(C,
self).__getitem__(name)}. Accordingly, \function{super} is
undefined for implicit lookups using statements or operators such as
\samp{super(C, self)[name]}.

So you should write

super(BOOL, self).__setattr__('value', val)

or similar.
The c_long.value.__get__ and c_long.value.__set__ variants work, but
they look strange - is there a better way?

I guess super(BOOL, BOOL).value.__set__() might work too... haven't
tried it, though.

I also note that the documentation for super() starts off with

Return the superclass of \var{type}.

which is wrong, and that super() is documented in libfuncs.tex, which
is also wrong. Some bug reports are coming up!

Cheers,
mwh
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,139
Latest member
JamaalCald
Top