[Zope3-checkins] CVS: Zope3/src/zope/app/rdb - __init__.py:1.14

Steve Alexander steve@cat-box.net
Mon, 9 Jun 2003 11:32:28 -0400


Update of /cvs-repository/Zope3/src/zope/app/rdb
In directory cvs.zope.org:/tmp/cvs-serv718/src/zope/app/rdb

Modified Files:
	__init__.py 
Log Message:
Some minor stylistic cleanups.

Created an InstanceOnlyDescriptor to fix the problem of a
__Security_checker__ attribute of a class, intended for its instances
only, also acting for the class.

The InstanceOnlyDescriptor may be more generally applicable. It is written
and tested to act as a complete data descriptor, that is more than strictly
the minimum needed for this module. Perhaps it should be moved elsewhere?



=== Zope3/src/zope/app/rdb/__init__.py 1.13 => 1.14 ===
--- Zope3/src/zope/app/rdb/__init__.py:1.13	Mon Jun  9 11:02:45 2003
+++ Zope3/src/zope/app/rdb/__init__.py	Mon Jun  9 11:31:57 2003
@@ -19,6 +19,8 @@
 
 $Id$
 """
+__metaclass__ = type
+
 from types import StringTypes
 
 from persistence import Persistent
@@ -26,7 +28,7 @@
 from transaction import get_transaction
 from transaction.interfaces import IDataManager
 
-from zope.security import checker
+from zope.security.checker import NamesChecker
 
 from zope.interface import implements
 
@@ -259,8 +261,9 @@
         converters = [getConverter(col_info[1])
                       for col_info in self.cursor.description]
 ## A possible optimization -- need benchmarks to check if it is worth it
-##      if filter(lambda x: x is not ZopeDatabaseAdapter.identity, converters):
+##      if [x for x in converters if x is not ZopeDatabaseAdapter.identity]:
 ##          return results  # optimize away
+
         def convertRow(row):
             return map(lambda converter, value: converter(value),
                        converters, row)
@@ -296,7 +299,6 @@
         self._txn_registered = False
         self.conn.commit()
 
-
     def rollback(self):
         'See IDBIConnection'
         self._txn_registered = False
@@ -315,7 +317,7 @@
 
     try:
         cursor.execute(query)
-    except Exception, error:
+    except Exception, error:  # XXX This looks a bit yucky.
         raise DatabaseException(str(error))
 
     if cursor.description is not None:
@@ -374,21 +376,28 @@
                 return c
         return 0
 
+class InstanceOnlyDescriptor:
+    __marker = object()
+    def __init__(self, value=__marker):
+        if value is not self.__marker:
+            self.value = value
+
+    def __get__(self, inst, cls=None):
+        if inst is None:
+            raise AttributeError
+        return self.value
+
+    def __set__(self, inst, value):
+        self.value = value
+
+    def __delete__(self, inst):
+        del self.value
 
 def RowClassFactory(columns):
     """Creates a Row object"""
     klass_namespace = {}
-
-    #XXX +['__bases__'] is described below
-    #
-    #<SteveA> the class is supposed to provide the attributes for the instancesa
-    #<SteveA> but, either the checker selection thing needs to ignore it for types
-    #<SteveA> (which is ropey when you're working with metatypes)
-    #<SteveA> or, it really should be a descriptor that doesn't @#$% with the value on the class
-    #
-    #unit tests indicate columns will be tupled
-    #queryForResults indicate columns will be a list - so we cast to tuple
-    klass_namespace['__Security_checker__'] = checker.NamesChecker(tuple(columns)+('__bases__',))
+    klass_namespace['__Security_checker__'] = InstanceOnlyDescriptor(
+        NamesChecker(columns))
     klass_namespace['__slots__'] = tuple(columns)
 
     return type('GeneratedRowClass', (Row,), klass_namespace)