hi
i need to have a list collection with list.appender (in SA 0.4 terms) 
that accepts either one positional arg as the value, or keyword args 
which it uses to create the value. Each collection instance knows 
what type of values to create.

so i do:
    class MyCollection( list):
        factory = None
        @collection.appender
        def append( me, obj =_NOTSET, **kargs):
            if obj is _NOTSET:    #marker for notset
                obj = me.factory( **kargs)
            list.append( me, obj)
            return obj

    @classmethod
    def myCollectionFactory( klas):
        m = Association.MyCollection()
        m.factory = klas
        return m

and in the mapper, 
  ... relation( ..., 
           uselist = True,
           collection_class = assoc_klas.myCollectionFactory
     )

well, it doesnot work. 
all is well until in _instrument_class() the ABC decoration kicks in, 
and setup a preset append-wrapping decorator that has another 
interface (as in _list_decorators(): 
        def append(self, item, _sa_initiator=None):...

Any idea to fix/enhance this, letting **kwargs through to my function?
The dynamic wrapper() can do this, while these preset ones cannot... 
while they should be equaly powerful.

There are 2 (different) uses of an appender, one is the SA itself, but 
the other is the programmer. SA will always use single 
arg/positionals, while i could use this or that or combination.

===========
coupe of comments on orm.collections.py:
 - there are several lines like
       setattr(fn, '_sa_instrumented', True)
   why not just use fn._sa_instrumented= True ?

 - the repeated check/setup in _instrument_class() can be looped:
    ....
    # ensure all roles are present, and apply implicit instrumentation 
if needed
    for rolename,eventname in dict(
                appender='fire_append_event',
                remover ='fire_remove_event',
                iterator=None,
            ).iteritems():
        roler = roles.get( rolename, None)
        if not role or not hasattr(cls, roler):
            typename = cls.__name__
            raise exceptions.ArgumentError(
                "Type %(typename)s must elect an %(rolename)s method 
to be a collection class" % locals() )
        elif (eventname and
                roler not in methods and
                not hasattr(getattr(cls, roler), '_sa_instrumented')):
            methods[ roler] = ( eventname, 1, None)
 

patch attached.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Index: orm/collections.py
===================================================================
--- orm/collections.py	(revision 3333)
+++ orm/collections.py	(working copy)
@@ -647,35 +655,32 @@
 
     # ensure all roles are present, and apply implicit instrumentation if
     # needed
-    if 'appender' not in roles or not hasattr(cls, roles['appender']):
+    for rolename,eventname in dict(
+                appender='fire_append_event',
+                remover ='fire_remove_event',
+                iterator=None,
+            ).iteritems():
+        roler = roles.get( rolename, None)
+        if not role or not hasattr(cls, roler):
+            typename = cls.__name__
         raise exceptions.ArgumentError(
-            "Type %s must elect an appender method to be "
-            "a collection class" % cls.__name__)
-    elif (roles['appender'] not in methods and
-          not hasattr(getattr(cls, roles['appender']), '_sa_instrumented')):
-        methods[roles['appender']] = ('fire_append_event', 1, None)
-
-    if 'remover' not in roles or not hasattr(cls, roles['remover']):
-        raise exceptions.ArgumentError(
-            "Type %s must elect a remover method to be "
-            "a collection class" % cls.__name__)
-    elif (roles['remover'] not in methods and
-          not hasattr(getattr(cls, roles['remover']), '_sa_instrumented')):
-        methods[roles['remover']] = ('fire_remove_event', 1, None)
-
-    if 'iterator' not in roles or not hasattr(cls, roles['iterator']):
-        raise exceptions.ArgumentError(
-            "Type %s must elect an iterator method to be "
-            "a collection class" % cls.__name__)
+                "Type %(typename)s must elect an %(role)s method to be "
+                "a collection class" % locals() )
+        elif (eventname and
+                roler not in methods and
+                not hasattr(getattr(cls, roler), '_sa_instrumented')):
+            methods[ roler] = ( eventname, 1, None)
 
     # apply ad-hoc instrumentation from decorators, class-level defaults
     # and implicit role declarations

Reply via email to