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 [email protected]
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