[Python-3000] enhanced descriptors

Greg Ewing greg.ewing at canterbury.ac.nz
Sat Jun 10 13:25:50 CEST 2006

tomer filiba wrote:

> so my suggestion is as follows:
> data descriptors must define __get__ and __set__. if they
> also define one of the inplace-operators (__iadd___, etc),
> it will be called instead of first __get__()ing and then
> __set__()ing.
> however, the inplace operators would have to use a different
> signature than the normal operators -- instead of
> __iadd__(self, other)
> they would be defined as
> __iadd__(self, obj, value).

This could be done, although it would require some large
changes to the way things work. Currently the attribute
access and inplace operation are done by separate bytecodes,
so by the time the += gets processed, the whole descriptor
business is finished with.

What would be needed is to combine the attribute access
and += operator into a single "add to attribute" operation.
So there would be an ADD_TO_ATTRIBUTE bytecode, and a
corresponding __iaddattr__ method or some such implementing

Then of course you'd want corresponding methods for all
the other inplace operators applied to attributes. And
probably a third set for obj[index] += value etc.

That's getting to be a ridiculously large set of methods.
It could be cut down considerably by having just one
in-place method of each kind, parameterised by a code
indicating the arithmetic operation (like __richcmp__):

    Syntax                Method
    obj.attr OP= value    obj.__iattr__(op, value)
    obj[index] OP= value  obj.__iitem__(op, value)

It might be worth writing a PEP about this.

Getting back to the problem at hand, there's another way
it might be handled using current Python. Instead of a
normal int, the position descriptor could return an
instance of an int subclass with an __iadd__ method that
manipulates the file position.

There's one further problem with all of this, though.
Afterwards, the result of the += is going get assigned
back to the position property. If you want to avoid
making another redundant system call, you'll somehow
have to detect when the value being assigned is the
result of a += and ignore it.


More information about the Python-3000 mailing list