Re: setattr() oddness

2010-01-20 Thread M.-A. Lemburg
Dieter Maurer wrote:
 Steven D'Aprano ste...@remove.this.cybersource.com.au writes on 18 Jan 2010 
 06:47:59 GMT:
 On Mon, 18 Jan 2010 07:25:58 +0100, Dieter Maurer wrote:

 Lie Ryan lie.1...@gmail.com writes on Sat, 16 Jan 2010 19:37:29 +1100:
 On 01/16/10 10:10, Sean DiZazzo wrote:
 Interesting.  I can understand the would take time argument, but I
 don't see any legitimate use case for an attribute only accessible
 via getattr().  Well, at least not a pythonic use case.

 mostly for people (ab)using attributes instead of dictionary.

 Here is one use case:

  A query application. Queries are described by complex query objects.
  For efficiency reasons, query results should be cached. For this, it is
  not unnatural to use query objects as cache keys. Then, query objects
  must not get changed in an uncontrolled way. I use __setattr__ to
  control access to the objects.


 (1) Wouldn't it be more natural to store these query keys in a list or 
 dictionary rather than as attributes on an object?

 e.g. instead of:

 cache.__setattr__('complex query object', value)

 use:

 cache['complex query object'] = value
 
 Few will use cache.__setattr__(...) but cache.attr = ... which
 is nicer than cache['attr'] = 
 
 Moreover, it is not the cache but the query of which I want to protect
 modification. My cache indeed uses cache[query_object] = 
 But I want to prevent query_object from being changed after a potential
 caching.

You might want to look at mxProxy which provides object-level
access control:

http://www.egenix.com/products/python/mxBase/mxProxy/

See the Access Protocol in the documentation:

http://www.egenix.com/products/python/mxBase/mxProxy/doc/#_Toc162774446

 (2) How does __setattr__ let you control access to the object? If a user 
 wants to modify the cache, and they know the complex query object, what's 
 stopping them from using __setattr__ too?
 
 In my specific case, __setattr__ prevents all modifications via attribute
 assignment. The class uses __dict__ access to set attributes when
 it knows it is still safe.
 
 Of course, this is no real protection against attackers (which could
 use __dict__ as well). It only protects against accidental change
 of query objects.
 
 
 Meanwhile, I remembered a more important use case for __setattr__:
 providing for transparent persistancy. The ZODB (Zope Object DataBase)
 customizes __setattr__ in order to intercept object modifications
 and register automatically that the change needs to be persisted at
 the next transaction commit.

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Source  (#1, Jan 20 2010)
 Python/Zope Consulting and Support ...http://www.egenix.com/
 mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/
 mxODBC, mxDateTime, mxTextTools ...http://python.egenix.com/


::: Try our new mxODBC.Connect Python Database Interface for free ! 


   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
   Registered at Amtsgericht Duesseldorf: HRB 46611
   http://www.egenix.com/company/contact/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: setattr() oddness

2010-01-19 Thread Dieter Maurer
Steven D'Aprano ste...@remove.this.cybersource.com.au writes on 18 Jan 2010 
06:47:59 GMT:
 On Mon, 18 Jan 2010 07:25:58 +0100, Dieter Maurer wrote:
 
  Lie Ryan lie.1...@gmail.com writes on Sat, 16 Jan 2010 19:37:29 +1100:
  On 01/16/10 10:10, Sean DiZazzo wrote:
   Interesting.  I can understand the would take time argument, but I
   don't see any legitimate use case for an attribute only accessible
   via getattr().  Well, at least not a pythonic use case.
  
  mostly for people (ab)using attributes instead of dictionary.
  
  Here is one use case:
  
   A query application. Queries are described by complex query objects.
   For efficiency reasons, query results should be cached. For this, it is
   not unnatural to use query objects as cache keys. Then, query objects
   must not get changed in an uncontrolled way. I use __setattr__ to
   control access to the objects.
 
 
 (1) Wouldn't it be more natural to store these query keys in a list or 
 dictionary rather than as attributes on an object?
 
 e.g. instead of:
 
 cache.__setattr__('complex query object', value)
 
 use:
 
 cache['complex query object'] = value

Few will use cache.__setattr__(...) but cache.attr = ... which
is nicer than cache['attr'] = 

Moreover, it is not the cache but the query of which I want to protect
modification. My cache indeed uses cache[query_object] = 
But I want to prevent query_object from being changed after a potential
caching.



 (2) How does __setattr__ let you control access to the object? If a user 
 wants to modify the cache, and they know the complex query object, what's 
 stopping them from using __setattr__ too?

In my specific case, __setattr__ prevents all modifications via attribute
assignment. The class uses __dict__ access to set attributes when
it knows it is still safe.

Of course, this is no real protection against attackers (which could
use __dict__ as well). It only protects against accidental change
of query objects.


Meanwhile, I remembered a more important use case for __setattr__:
providing for transparent persistancy. The ZODB (Zope Object DataBase)
customizes __setattr__ in order to intercept object modifications
and register automatically that the change needs to be persisted at
the next transaction commit.


Dieter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: setattr() oddness

2010-01-17 Thread Dieter Maurer
Lie Ryan lie.1...@gmail.com writes on Sat, 16 Jan 2010 19:37:29 +1100:
 On 01/16/10 10:10, Sean DiZazzo wrote:
  Interesting.  I can understand the would take time argument, but I
  don't see any legitimate use case for an attribute only accessible via
  getattr().  Well, at least not a pythonic use case.
 
 mostly for people (ab)using attributes instead of dictionary.

Here is one use case:

 A query application. Queries are described by complex query objects.
 For efficiency reasons, query results should be cached.
 For this, it is not unnatural to use query objects as cache keys.
 Then, query objects must not get changed in an uncontrolled way.
 I use __setattr__ to control access to the objects.

Dieter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: setattr() oddness

2010-01-17 Thread Steven D'Aprano
On Mon, 18 Jan 2010 07:25:58 +0100, Dieter Maurer wrote:

 Lie Ryan lie.1...@gmail.com writes on Sat, 16 Jan 2010 19:37:29 +1100:
 On 01/16/10 10:10, Sean DiZazzo wrote:
  Interesting.  I can understand the would take time argument, but I
  don't see any legitimate use case for an attribute only accessible
  via getattr().  Well, at least not a pythonic use case.
 
 mostly for people (ab)using attributes instead of dictionary.
 
 Here is one use case:
 
  A query application. Queries are described by complex query objects.
  For efficiency reasons, query results should be cached. For this, it is
  not unnatural to use query objects as cache keys. Then, query objects
  must not get changed in an uncontrolled way. I use __setattr__ to
  control access to the objects.


(1) Wouldn't it be more natural to store these query keys in a list or 
dictionary rather than as attributes on an object?

e.g. instead of:

cache.__setattr__('complex query object', value)

use:

cache['complex query object'] = value



(2) How does __setattr__ let you control access to the object? If a user 
wants to modify the cache, and they know the complex query object, what's 
stopping them from using __setattr__ too?




-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: setattr() oddness

2010-01-16 Thread Lie Ryan
On 01/16/10 10:10, Sean DiZazzo wrote:
 Interesting.  I can understand the would take time argument, but I
 don't see any legitimate use case for an attribute only accessible via
 getattr().  Well, at least not a pythonic use case.

mostly for people (ab)using attributes instead of dictionary.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: setattr() oddness

2010-01-15 Thread Terry Reedy

On 1/15/2010 3:37 PM, Sean DiZazzo wrote:

Should the following be legal?


class TEST(object): pass

...

t = TEST()
setattr(t, , 123)
getattr(t, )

'123'


Different people have different opinions as to whether setattr (and 
correspondingly getattr) should be strict or permissive as to whether or 
not the 'name' string is a legal name. CPython is permissive. The 
rationale is that checking would take time and prevent possible 
legitimate use cases.


CPython is actually looser than this. Try

t.__dict__[1] = 2

Now there is an 'attribute' whose 'name' is an int! -- and which can 
only be accessed via the same trick of delving into the internals. This 
is, however, implementation behavior that would go away if an 
implementation used string-key-only dicts to store attributes.


Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: setattr() oddness

2010-01-15 Thread Steve Holden
Terry Reedy wrote:
 On 1/15/2010 3:37 PM, Sean DiZazzo wrote:
 Should the following be legal?

 class TEST(object): pass
 ...
 t = TEST()
 setattr(t, , 123)
 getattr(t, )
 '123'
 
 Different people have different opinions as to whether setattr (and
 correspondingly getattr) should be strict or permissive as to whether or
 not the 'name' string is a legal name. CPython is permissive. The
 rationale is that checking would take time and prevent possible
 legitimate use cases.
 
 CPython is actually looser than this. Try
 
 t.__dict__[1] = 2
 
 Now there is an 'attribute' whose 'name' is an int! -- and which can
 only be accessed via the same trick of delving into the internals. This
 is, however, implementation behavior that would go away if an
 implementation used string-key-only dicts to store attributes.
 
Good question, great answer!

regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
PyCon is coming! Atlanta, Feb 2010  http://us.pycon.org/
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS:http://holdenweb.eventbrite.com/

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: setattr() oddness

2010-01-15 Thread Sean DiZazzo
On Jan 15, 2:22 pm, Terry Reedy tjre...@udel.edu wrote:
 On 1/15/2010 3:37 PM, Sean DiZazzo wrote:

  Should the following be legal?

  class TEST(object): pass
  ...
  t = TEST()
  setattr(t, , 123)
  getattr(t, )
  '123'

 Different people have different opinions as to whether setattr (and
 correspondingly getattr) should be strict or permissive as to whether or
 not the 'name' string is a legal name. CPython is permissive. The
 rationale is that checking would take time and prevent possible
 legitimate use cases.

 CPython is actually looser than this. Try

 t.__dict__[1] = 2

 Now there is an 'attribute' whose 'name' is an int! -- and which can
 only be accessed via the same trick of delving into the internals. This
 is, however, implementation behavior that would go away if an
 implementation used string-key-only dicts to store attributes.

 Terry Jan Reedy

Interesting.  I can understand the would take time argument, but I
don't see any legitimate use case for an attribute only accessible via
getattr().  Well, at least not a pythonic use case.

Thanks for the info!

~Sean
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: setattr() oddness

2010-01-15 Thread Terry Reedy

On 1/15/2010 6:10 PM, Sean DiZazzo wrote:

On Jan 15, 2:22 pm, Terry Reedytjre...@udel.edu  wrote:

On 1/15/2010 3:37 PM, Sean DiZazzo wrote:


Should the following be legal?



class TEST(object): pass

...

t = TEST()
setattr(t, , 123)
getattr(t, )

'123'


Different people have different opinions as to whether setattr (and
correspondingly getattr) should be strict or permissive as to whether or
not the 'name' string is a legal name. CPython is permissive. The
rationale is that checking would take time and prevent possible
legitimate use cases.

CPython is actually looser than this. Try

t.__dict__[1] = 2

Now there is an 'attribute' whose 'name' is an int! -- and which can
only be accessed via the same trick of delving into the internals. This
is, however, implementation behavior that would go away if an
implementation used string-key-only dicts to store attributes.

Terry Jan Reedy


Interesting.  I can understand the would take time argument, but I
don't see any legitimate use case for an attribute only accessible via
getattr().  Well, at least not a pythonic use case.


That was my first thought, but one thing I thought of would be a proxy 
object for remote objects coded in a language with different name rules, 
or any situation where 'names' and values come over the wire to be 
stored and later retrieved, so that all 'foreign' attribute access was 
done with set/get/del/attr.


I expect that creative Python programmers have found other uses too.

Terry Jan Reedy


--
http://mail.python.org/mailman/listinfo/python-list