<div dir="ltr">2013/6/18 Wolfgang Maier <span dir="ltr"><<a href="mailto:wolfgang.maier@biologie.uni-freiburg.de" target="_blank">wolfgang.maier@biologie.uni-freiburg.de</a>></span><br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">andrea crotti <andrea.crotti.0 <at> <a href="http://gmail.com" target="_blank">gmail.com</a>> writes:<br>

<br>
><br>
><br>
> Using a CouchDB server we have a different database object potentially for<br>
every request.<br>
><br>
> We already set that db in the request object to make it easy to pass it<br>
around form our django app, however it would be nice if I could set it once<br>
in the API and automatically fetch it from there.<br>
><br>
> Basically I have something like<br>
><br>
> class Entity:<br>
>      def save_doc(db)<br>
>         ...<br>
><br>
> I would like basically to decorate this function in such a way that:<br>
> - if I pass a db object use it<br>
> - if I don't pass it in try to fetch it from a global object<br>
> - if both don't exist raise an exception<br>
><br>
> Now it kinda of works already with the decorator below.<br>
> The problem is that the argument is positional so I end up maybe passing<br>
it twice.<br>
> So I have to enforce that 'db' if there is passed as first argument..<br>
><br>
> It would be a lot easier removing the db from the arguments but then it<br>
would look too magic and I didn't want to change the signature.. any other<br>
advice?<br>
><br>
> def with_optional_db(func):<br>
>     """Decorator that sets the database to the global current one if<br>
>     not passed in or if passed in and None<br>
>     """<br>
</div>>      <at> wraps(func)<br>
<div class="im">>     def _with_optional_db(*args, **kwargs):<br>
>         func_args = func.func_code.co_varnames<br>
>         db = None<br>
>         # if it's defined in the first elements it needs to be<br>
>         # assigned to *args, otherwise to kwargs<br>
>         if 'db' in func_args:<br>
>             assert 'db' == func_args[0], "Needs to be the first defined"<br>
>         else:<br>
>             db = kwargs.get('db', None)<br>
><br>
>         if db is None:<br>
>             kwargs['db'] = get_current_db()<br>
><br>
>         assert kwargs['db'] is not None, "Can't have a not defined database"<br>
>         ret = func(*args, **kwargs)<br>
>         return ret<br>
><br>
>     return _with_optional_db<br>
><br>
<br>
</div>I'm not sure, whether your code would work. I get the logic for the db in<br>
kwargs case, but why are you checking whether db is in func_args? Isn't the<br>
real question whether it's in args ?? In general, I don't understand why you<br>
want to use .func_code.co_varnames here. You know how you defined your<br>
function (or rather method):<br>
<div class="im">class Entity:<br>
    def save_doc(db):<br>
        ...<br>
</div>Maybe I misunderstood the problem?<br>
<span class="HOEnZb"><font color="#888888">Wolfgang<br>
<br>
<br>
<br>
<br>
--<br>
<a href="http://mail.python.org/mailman/listinfo/python-list" target="_blank">http://mail.python.org/mailman/listinfo/python-list</a><br>
</font></span></blockquote></div><br></div><div class="gmail_extra"><br></div><div class="gmail_extra" style>Well the point is that I could allow someone to not use "db" as argument of the function if he only wants to use the global db object..</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>Or at least I want to check that it's the first argument and not in another position, just as a sanity check.</div><div class="gmail_extra" style>
<br></div><div class="gmail_extra" style>I might drop some magic and make it a bit simpler though, even the default argument DEFAULT_DB could be actually good, and I would not even need the decorator at that point..</div>
</div>