[Python-3000] enhanced descriptors

tomer filiba tomerfiliba at gmail.com
Sat Jun 10 10:55:17 CEST 2006


disclaimer: i'm not sure this suggestion is feasible to
implement, because of the way descriptors work, but
it's something we should consider adding.
----

as you may remember, in iostack, we said the position
property should act like the following:

f.position = <non-negative int> # absolute seek
f.position = <negative int> # relative-to-end seek
f.position += <int> # relative-to-current seek

so i wrote a data descriptor. implementing the first two is
easy, but the third version is tricky.
doing x.y += z on a data descriptor translates to
x.__set__(y, x.__get__(y) + z)

in my case, it means first tell()ing, adding the offset, and
then seek()ing to the new position. this works, of course,
but it requires two system calls instead of one. what i
wished i had was x.__iadd__(y, z)

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).

therefore, i suggest adding __set_iadd__, or something in
that spirit, to solve the ambiguity.

for example, my position descriptor would look like:

class PositionDesc(object):
    def __get__(self, obj, cls):
        if obj is None:
            return self
        return obj.tell()

    def __set__(self, obj, value):
        if value >= 0:
            obj.seek(value, "start")
        else:
            obj.seek(value, "end")

    def __set_iadd__(self, obj, value):
         obj.seek(value, "curr")

...

p = f.position      # calls __get__
f.position = 5      # calls __set__
f.position = -5     # calls __set__
f.position += 10    # calls __set_iadd__

now there are two issues:
* is it even possible to implement (without overcomplicating the
descriptors mechanism)?
* is it generally useful?

i can't answer the first question, but it would surely be useful
in iostack; and besides, for symmetry's sake, if x += y calls
x.__iadd__(y), it should be optimized for descriptors as well.
i'd hate having to do two system calls for something that can
be done with one using seek().


-tomer


More information about the Python-3000 mailing list