Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: properties + types, implementing meta-class desciptors elegantly?

Reply
Thread Tools

Re: properties + types, implementing meta-class desciptors elegantly?

 
 
Michele Simionato
Guest
Posts: n/a
 
      07-19-2003
http://www.velocityreviews.com/forums/(E-Mail Removed) (Bengt Richter) wrote in message news:<bfa97g$s5j$0@216.39.172.122>...
> Not sure exactly what you are doing, but what does
>
> object.__setattr__(client, self.name, value)
>
> do in your context in place of
>
> client.__dict__[ self.name ] = value
>
> ?
>
> Regards,
> Bengt Richter


I agree with Bengt, from your traceback it seems you are assigning directly
to client.__dict__, but you cannot do that (I think because client.__dict__
is a dictproxy object and not a real dictionary). The right way to
go is via object.__setattr__ , or type.__setattr__ in the case of
metaclasses.

I guess you are aware of the metaclass+properties recipes in the
on-line cookbook, but just in case ...

HTH,


Michele
 
Reply With Quote
 
 
 
 
Mike C. Fletcher
Guest
Posts: n/a
 
      07-19-2003
Michele Simionato wrote:
....

>I agree with Bengt, from your traceback it seems you are assigning directly
>to client.__dict__, but you cannot do that (I think because client.__dict__
>is a dictproxy object and not a real dictionary). The right way to
>go is via object.__setattr__ , or type.__setattr__ in the case of
>metaclasses.
>

Try this to see what I'm getting at:

>>> class o(object):

.... class p( object ):
.... def __set__( self, client, value, *args, **named ):
.... print '__set__', self, client, value, args, named
.... # now what do you do here to set without triggering
ourselves
.... # (without having to code diff versions of the
descriptor class
.... # for each possible type of client object (and for that
matter, just
.... # making it possible for (meta-)types with properties
w/out requiring
.... # e.g. a new dict object in each such serviced type))?.
.... return object.__setattr__( client, "v", value)
.... v = p()
....
>>> s = o()
>>> s.v = 3


You'll notice you go into an infinite loop. What I'm looking for
(really a thinly veiled attempt to get other people to demand it from
Guido so he doesn't think I'm a lone crackpot ) is a function/method
that provides the default implementation of the get/set functionality
*below* the level of the descriptor hooks, but high enough that it can
deal with the differences between classes, types, instances, and
instances-with-__slots__ (I realise that last one probably isn't going
to work, BTW).

Thought of another way, it's asking for a superclass of descriptors
which provides this logic in such a way that, by sub-classing from them,
you can readily gain access to this descriptor-building functionality
without needing to always use it, and without introducing unwanted
restrictions (such as requiring a property-class initialisation).

Thought of another way, it's asking for a further rationalisation of the
get/set hooks so that there's a lower level at which you can either
insert storage code *or* use the default storage code.

>I guess you are aware of the metaclass+properties recipes in the
>on-line cookbook, but just in case ...
>

Hadn't looked at them, have now, there's nothing which addresses this
particular issue that I can see with a search for metaclass. Willing to
be proved wrong .

Have fun,
Mike

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/




 
Reply With Quote
 
 
 
 
Bengt Richter
Guest
Posts: n/a
 
      07-19-2003
On Sat, 19 Jul 2003 11:49:25 -0400, "Mike C. Fletcher" <(E-Mail Removed)> wrote:

>Michele Simionato wrote:
>...
>
>>I agree with Bengt, from your traceback it seems you are assigning directly
>>to client.__dict__, but you cannot do that (I think because client.__dict__
>>is a dictproxy object and not a real dictionary). The right way to
>>go is via object.__setattr__ , or type.__setattr__ in the case of
>>metaclasses.
>>

>Try this to see what I'm getting at:
>
> >>> class o(object):

>... class p( object ):
>... def __set__( self, client, value, *args, **named ):
>... print '__set__', self, client, value, args, named
>... # now what do you do here to set without triggering
>ourselves
>... # (without having to code diff versions of the
>descriptor class
>... # for each possible type of client object (and for that
>matter, just
>... # making it possible for (meta-)types with properties
>w/out requiring
>... # e.g. a new dict object in each such serviced type))?.
>... return object.__setattr__( client, "v", value)

client.__dict__['v'] = value
the above line should work for this example, so it must be different from
what you were doing before? Perhaps the client object before was a class?
I guess I'm not getting the big picture yet of your design intent.

Are you trying to make a base class that has properties that can
set same-named properties in the subclass via attributes
of objects instantiated from the subclass? Or as attributes of the
subclass? Do you need the property ability to munge its arguments dynamically?
Otherwise a plain old attribute assignment to the subclass per se should install
the property for its instances, no?

>... v = p()
>...
> >>> s = o()
> >>> s.v = 3

>
>You'll notice you go into an infinite loop. What I'm looking for

For this example that's certainly what you'd expect.
>(really a thinly veiled attempt to get other people to demand it from
>Guido so he doesn't think I'm a lone crackpot ) is a function/method
>that provides the default implementation of the get/set functionality
>*below* the level of the descriptor hooks, but high enough that it can
>deal with the differences between classes, types, instances, and
>instances-with-__slots__ (I realise that last one probably isn't going
>to work, BTW).
>
>Thought of another way, it's asking for a superclass of descriptors
>which provides this logic in such a way that, by sub-classing from them,
>you can readily gain access to this descriptor-building functionality
>without needing to always use it, and without introducing unwanted
>restrictions (such as requiring a property-class initialisation).
>
>Thought of another way, it's asking for a further rationalisation of the
>get/set hooks so that there's a lower level at which you can either
>insert storage code *or* use the default storage code.
>

More simple examples like the above might help me understand, but I haven't
got the picture yet, I am afraid

Regards,
Bengt Richter
 
Reply With Quote
 
Mike C. Fletcher
Guest
Posts: n/a
 
      07-19-2003
Okay, rather than respond to the fragments first, which just seems to be
confusing people, as they aren't getting the previous discussion.
Here's a quick sketch of what I'm creating:

class Meta( type ):
tableName = common.StringProperty(
"tableName", """The table in which this class stores it's primary
data""",
defaultValue = "",
)
implementationBase = common.ClassByNameProperty(
"implementation", """Base class for implementation""",
defaultValue = "wxpytable.dbresultset.DBResultSet",
setDefaultOnGet = 0,
)
...

Now, those objects from "common" are part of a fairly involved hierarchy
of descriptor classes which provide type coercion, default-value
retrieval, automated lookup of factory functions, managed list-of-type
support, and a dozen other features. Here's the framework of what a
"basicproperty" does:

* hooks the __set__ event (and __get__ and __delete__)
o is thereby a descriptor
o can be introspected from the object with the properties
+ has documentation
+ has meta-data for coercion, type-checking, default
values, operations for choosing common values,
etceteras, etceteras
+ can be readily sub-classed to produce new effects,
such as using weak references or storing values in a
database based on schema objects, or calling methods
on a client...
* checks the data type of the value
o if necessary, coerces the value (normally defering to the
"baseType" for the property)
* finally, stores the value
o tries to do what would have been done if there were no
descriptor (with the new, coerced value)
o does *not* create new names in the object's namespace (all
names are documented w/ descriptors, there's not a lot of
'_' prefixed names cluttering the namespace)
o does *not* require a new dictionary/storage-object attribute
for the object (the descriptor works like any other
descriptor, a *stand-alone* object that replaces a regular
attribute)

It's that last part that I'd like to have a function/method to
accomplish. That is, store (and obviously retrieve as well) attribute
values for objects, instances, types, classes, __slot__'d instances,
etceteras under a given name without triggering any of the __setattr__
machinery which defers to the __set__ method of the associated descriptor.

I can work around the problem by violating either of those two bullet
points under "finally, stores the value", but I'm looking for something
that *doesn't* violate them. See below for responses to particular
points...

Bengt Richter wrote:
....

> client.__dict__['v'] = value
>the above line should work for this example, so it must be different from
>what you were doing before? Perhaps the client object before was a class?
>I guess I'm not getting the big picture yet of your design intent.
>

That's what the base properties do, but they just can't work when doing
a meta-class, as it's __dict__ is a dict-proxy, which doesn't allow
assignment. I'm looking for a method to tell the Python system "Okay,
what would you have done if there were no descriptors? Here's the key
and value to set, go set them." That sample was just to demonstrate why
calling object.__setattr__ wouldn't work (it recursively calls the
descriptor).

>Are you trying to make a base class that has properties that can
>set same-named properties in the subclass via attributes
>of objects instantiated from the subclass? Or as attributes of the
>subclass? Do you need the property ability to munge its arguments dynamically?
>Otherwise a plain old attribute assignment to the subclass per se should install
>the property for its instances, no?
>
>

Nope, I'm trying to make meta-classes which have rich properties. The
particular project is a plug-in system, where the classes (the
metaclass-instances) want to have all sorts of rich metadata associated
with them in a way which meshes with the rest of the system (i.e. using
a descriptor-based introspection mechanism).
....

Enjoy,
Mike
_______________________________________

Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/




 
Reply With Quote
 
Aahz
Guest
Posts: n/a
 
      07-19-2003
In article <(E-Mail Removed)>,
Mike C. Fletcher <(E-Mail Removed)> wrote:
>
>Nope, I'm trying to make meta-classes which have rich properties. The
>particular project is a plug-in system, where the classes (the
>metaclass-instances) want to have all sorts of rich metadata associated
>with them in a way which meshes with the rest of the system (i.e. using
>a descriptor-based introspection mechanism).
>...


Keeping in mind that I'm really not following this discussion all that
closely (because metaclasses give me headaches), are you trying to make
a *metaclass* that has properties or a *metaclass instance* (i.e. a
class) that has properties?
--
Aahz ((E-Mail Removed)) <*> http://www.pythoncraft.com/

This is Python. We don't care much about theory, except where it intersects
with useful practice. --Aahz
 
Reply With Quote
 
Mike C. Fletcher
Guest
Posts: n/a
 
      07-20-2003
Aahz wrote:

>In article <(E-Mail Removed)>,
>Mike C. Fletcher <(E-Mail Removed)> wrote:
>
>
>>Nope, I'm trying to make meta-classes which have rich properties. The
>>particular project is a plug-in system, where the classes (the
>>metaclass-instances) want to have all sorts of rich metadata associated
>>with them in a way which meshes with the rest of the system (i.e. using
>>a descriptor-based introspection mechanism).
>>...
>>
>>

>
>Keeping in mind that I'm really not following this discussion all that
>closely (because metaclasses give me headaches), are you trying to make
>a *metaclass* that has properties or a *metaclass instance* (i.e. a
>class) that has properties?
>
>

Just the meta-class instances (classes). Wasn't sufficiently precise in
my description, the properties are normally declared in the meta-class,
but they are actually properties of the meta-class instances.

Sorry about that,
Mike

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/




 
Reply With Quote
 
Aahz
Guest
Posts: n/a
 
      07-20-2003
In article <(E-Mail Removed)>,
Mike C. Fletcher <(E-Mail Removed)> wrote:
>Aahz wrote:
>>In article <(E-Mail Removed)>,
>>Mike C. Fletcher <(E-Mail Removed)> wrote:
>>>
>>>Nope, I'm trying to make meta-classes which have rich properties. The
>>>particular project is a plug-in system, where the classes (the
>>>metaclass-instances) want to have all sorts of rich metadata associated
>>>with them in a way which meshes with the rest of the system (i.e. using
>>>a descriptor-based introspection mechanism).

>>
>>
>>Keeping in mind that I'm really not following this discussion all that
>>closely (because metaclasses give me headaches), are you trying to make
>>a *metaclass* that has properties or a *metaclass instance* (i.e. a
>>class) that has properties?

>
>Just the meta-class instances (classes). Wasn't sufficiently precise in
>my description, the properties are normally declared in the meta-class,
>but they are actually properties of the meta-class instances.


Next question: are you also trying to access the properties on class
instances?
--
Aahz ((E-Mail Removed)) <*> http://www.pythoncraft.com/

This is Python. We don't care much about theory, except where it intersects
with useful practice. --Aahz
 
Reply With Quote
 
Beni Cherniavsky
Guest
Posts: n/a
 
      07-20-2003
Mike C. Fletcher wrote on 2003-07-19:

> * finally, stores the value
> o tries to do what would have been done if there were no
> descriptor (with the new, coerced value)
> o does *not* create new names in the object's namespace (all
> names are documented w/ descriptors, there's not a lot of
> '_' prefixed names cluttering the namespace)
> o does *not* require a new dictionary/storage-object attribute
> for the object (the descriptor works like any other
> descriptor, a *stand-alone* object that replaces a regular
> attribute)
>
> It's that last part that I'd like to have a function/method to
> accomplish. That is, store (and obviously retrieve as well) attribute
> values for objects, instances, types, classes, __slot__'d instances,
> etceteras under a given name without triggering any of the __setattr__
> machinery which defers to the __set__ method of the associated descriptor.
>
> I can work around the problem by violating either of those two bullet
> points under "finally, stores the value", but I'm looking for something
> that *doesn't* violate them. See below for responses to particular
> points...
>

I didn't grasp your precise problem but I've been having some similar
problems (without metaclasses however). Two tricks:

- Insert a dummy class into you heirarchy between object (or whatever
other superclass that doesn't have the properties yet and the class
where you install the properties. Then you might be able to use
this class to access the underliying class dict without being
intercepted by the properties. [I recall some problems with
properties vs. super, didn't follow them closely].

- If you use __slots__, they are also implemented as properties. So
if you define properties with the same name in the same class, you
lose all access to the raw slots. The solution is similar: define
__slots__ in a superclass, hide them with properties in a sublass.
See http://www.technion.ac.il/~cben/python/streams.py for an
example.

HTH,
Beni Cherniavsky <(E-Mail Removed)>

 
Reply With Quote
 
Mike C. Fletcher
Guest
Posts: n/a
 
      07-20-2003
Aahz wrote:

>In article <(E-Mail Removed)>,
>Mike C. Fletcher <(E-Mail Removed)> wrote:
>
>
>>Aahz wrote:
>>
>>
>>>In article <(E-Mail Removed)>,
>>>Mike C. Fletcher <(E-Mail Removed)> wrote:
>>>
>>>
>>>>Nope, I'm trying to make meta-classes which have rich properties. The
>>>>particular project is a plug-in system, where the classes (the
>>>>metaclass-instances) want to have all sorts of rich metadata associated
>>>>with them in a way which meshes with the rest of the system (i.e. using
>>>>a descriptor-based introspection mechanism).
>>>>
>>>>
>>>Keeping in mind that I'm really not following this discussion all that
>>>closely (because metaclasses give me headaches), are you trying to make
>>>a *metaclass* that has properties or a *metaclass instance* (i.e. a
>>>class) that has properties?
>>>
>>>

>>Just the meta-class instances (classes). Wasn't sufficiently precise in
>>my description, the properties are normally declared in the meta-class,
>>but they are actually properties of the meta-class instances.
>>
>>

>
>Next question: are you also trying to access the properties on class
>instances?
>

Not really, I want them to be properties of the class, and would prefer
that they *not* show up in the instances. That said, I can deal with it
if they do show up in the instances.

Enjoy,
Mike

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/




 
Reply With Quote
 
Mike C. Fletcher
Guest
Posts: n/a
 
      07-20-2003
Beni Cherniavsky wrote:

>Mike C. Fletcher wrote on 2003-07-19:
>
>
>
>> * finally, stores the value
>> o tries to do what would have been done if there were no
>> descriptor (with the new, coerced value)
>> o does *not* create new names in the object's namespace (all
>> names are documented w/ descriptors, there's not a lot of
>> '_' prefixed names cluttering the namespace)
>> o does *not* require a new dictionary/storage-object attribute
>> for the object (the descriptor works like any other
>> descriptor, a *stand-alone* object that replaces a regular
>> attribute)
>>
>>It's that last part that I'd like to have a function/method to
>>accomplish. That is, store (and obviously retrieve as well) attribute
>>values for objects, instances, types, classes, __slot__'d instances,
>>etceteras under a given name without triggering any of the __setattr__
>>machinery which defers to the __set__ method of the associated descriptor.
>>
>>I can work around the problem by violating either of those two bullet
>>points under "finally, stores the value", but I'm looking for something
>>that *doesn't* violate them. See below for responses to particular
>>points...
>>
>>
>>

>I didn't grasp your precise problem but I've been having some similar
>problems (without metaclasses however). Two tricks:
>
>- Insert a dummy class into you heirarchy between object (or whatever
> other superclass that doesn't have the properties yet and the class
> where you install the properties. Then you might be able to use
> this class to access the underliying class dict without being
> intercepted by the properties. [I recall some problems with
> properties vs. super, didn't follow them closely].
>

This violates the "does *not* require a new dictionary/storage-object
attribute" constraint. The super-class is just another way of spelling
"special place to store data" within the class instance, albeit a nicely
evil one . I'm looking for something that doesn't require modifying
classes to be property-aware just to add the properties, that is, a
stand-alone property object should be able to do this stuff w/out
requiring that the client objects know about the properties at all.

>- If you use __slots__, they are also implemented as properties. So
> if you define properties with the same name in the same class, you
> lose all access to the raw slots. The solution is similar: define
> __slots__ in a superclass, hide them with properties in a sublass.
> See http://www.technion.ac.il/~cben/python/streams.py for an
> example.
>

Will look it up. Basically, I'm not too worried about slotted instances
yet. I just think it should be part of whatever general solution Guido
figures is best.

Have fun,
Mike

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/




 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Unix file desciptors Lorenzo Chomp Ruby 0 03-15-2006 03:34 AM
CompositeControls: ViewState properties w/ Mapped properties probl =?Utf-8?B?Q2hyaXN0b3BoZSBQZWlsbGV0?= ASP .Net 1 01-19-2006 09:19 AM
Making Custom Control Properties Visible in Visual Studio's Properties Palette Nathan Sokalski ASP .Net 0 10-17-2005 02:05 AM
Problems parsing when Properties.dtd.properties Kent Lichty Java 0 04-16-2004 03:08 PM
Re: properties + types, implementing meta-class desciptors elegantly? Michael Hudson Python 3 07-22-2003 02:06 AM



Advertisments