On 04/07/10 10:21 +0200, Cédric Krier wrote:
> On 23/06/10 08:35 +0200, Cédric Krier wrote:
> > Hi,
> > 
> > I will start the developpement of the contextualisation of cursor, user and
> > context inside a threading locale [1].
> > I would like to use the with statement (available in Python 2.6 by default 
> > and
> > 2.5 (with "from __future__ import with_statement")) for this kind of 
> > purpose:
> > 
> > 
> >     from trytond import transaction
> >     with transaction.set('user', 0):
> >         ...
> > 
> > The 'user' will be restored at exit of the with statement.
> > 
> 
> I'm starting this implementation and I'm facing an issue with "context".
> I would like also to put context in the transaction but there is some
> problems:
> 
> - the context has been most of the time put as last keyword (except for some
>   methods like search). So it is complicated to find it in the args list.
>   But we can change those methods and put the context as first argument for
>   external calls (this will change the API).
> 
> - if we remove the context from the methods then the signature of each method
>   will be different between external call and internal. It is already the case
>   with cursor and user but one goal of this change is to fix it.
> 
> 
> So is there someone knows an other framework that has the same context-like
> behavior and how they solve it?
> 
> Or perhaps the solution will be to drop the context for a better solution as
> I always found it is not an elegant one.
> 

I think I found a solution.
The context parameter is only an issue for method callable by rpc. So I
propose to create a decorator on these methods that will put the context
dictionnary from parameter and put it in the transaction.
So methods will look like this:

    from trytond.protocols import rpc

    @rpc(True)
    def read(self, fields_names=None, context=None):
        ...


rpc will look:

    def rpc(commit=False):
        def __call__(self, function):
            arg_names = inspect.getargspec(function)[0]
            i = arg_names.index('context')
            def call(*args, **kwargs):
                context = None
                if len(args) >= i and args[i]:
                    context = args[i]
                elif 'context' in kwargs:
                    context = kwargs['context']
                transaction.set_context(context)
                return function(*args, **kwargs)


And more we will be able to construct _rpc by introspection.

-- 
Cédric Krier

B2CK SPRL
Rue de Rotterdam, 4
4000 Liège
Belgium
Tel: +32 472 54 46 59
Email/Jabber: [email protected]
Website: http://www.b2ck.com/

Attachment: pgpI6UO0SADUQ.pgp
Description: PGP signature

Reply via email to