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