[Python-Dev] More on contextlib - adding back a contextmanager decorator
Phillip J. Eby
pje at telecommunity.com
Sun Apr 30 20:58:56 CEST 2006
At 09:53 AM 4/30/2006 -0700, Guido van Rossum wrote:
>I have a counter-proposal: let's drop __context__. Nearly all use
>cases have __context__ return self. In the remaining cases, would it
>really be such a big deal to let the user make an explicit call to
>some appropriately named method? The only example that I know of where
>__context__ doesn't return self is the decimal module. So the decimal
>users would have to type
>
> with mycontext.some_method() as ctx: # ctx is a clone of mycontext
> ctx.prec += 2
> <BODY>
>
>The implementation of some_method() could be exactly what we currently
>have as the __context__ method on the decimal.Context object. Its
>return value is a decimal.WithStatementContext() instance, whose
>__enter__() method returns a clone of the original context object
>which is assigned to the variable in the with-statement (here 'ctx').
>
>This even has an additional advantage -- some_method() could have
>keyword parameters to set the precision and various other context
>parameters, so we could write this:
>
> with mycontext.some_method(prec=mycontext.prec+2):
> <BODY>
>
>Note that we can drop the variable too now (unless we have another
>need to reference it). An API tweak for certain attributes that are
>often incremented or decremented could reduce writing:
>
> with mycontext.some_method(prec_incr=2):
> <BODY>
But what's an appropriate name for some_method? Given that documentation
is the sore spot that keeps us circling around this point, doesn't this
just push the problem to finding a name to use in place of
__context__? And not only for this use case, but for others?
After all, for any library that has a notion of "the current X", it seems
reasonable to want to be able to say "with some_X" to mean "use some_X as
the current X for this block". And it thus seems to me that people will
want to have something like:
def using(obj):
if hasattr(obj,'__context__'):
obj = obj.__context__()
return obj
so they can do "with using(some_X)", because "with some_X.using()" or "with
some_X.as_current()" is awkward.
If you can solve the naming issue for these use cases (and I notice you
punted on that issue by calling it "some_method"), then +1 on removing
__context__. Otherwise, I'm -0; we're just fixing one
documentation/explanation problem (that only people writing contexts will
care about) by creating others (that will affect the people *using*
contexts too).
More information about the Python-Dev
mailing list