(I just hit Reply, usually that replies to the list...) How about something like: "A class for writing enhanced context managers. Allows using context managers as decorators, a new succinct way to define context managers, and some other goodies."
I must say, the actual benefits are really unclear. How is using @MyContextManager() better than contextlib.ContextDecorator (the latter being more explicit)? How is using the "manage_context()" method better than just defining a context manager with a function and contextlib.contextmanager? - Tal On Wed, Jan 5, 2011 at 5:13 PM, cool-RR <[email protected]> wrote: > Yes, I agree that's kind of an opaque description. But I haven't been able > to come up with a description which (a) explains enough and (b) > is succinct enough. Do you have a suggestion? > > Also, I think you should be sending critiques on the list; Other people may > have interesting opinions. > > > On Wed, Jan 5, 2011 at 9:29 AM, Tal Einat <[email protected]> wrote: > >> "Allows greater freedom" isn't much of a description. I had to read >> through the entire docstring to understand what it does. You should make it >> very clear what new functionality this supplies compared to the basic stuff. >> >> On Tue, Jan 4, 2011 at 7:55 PM, cool-RR <[email protected]> wrote: >> >>> Hello folks. >>> >>> Ever since Michael Foord talked about `ContextDecorator` in python-ideas >>> I've been kicking around an idea for my own take on it. It's a >>> `ContextManager` class which provides the same thing that Foord's >>> `ContextDecorator` does, but also provides a few more goodies, chief of >>> which being the `manage_context` method. >>> >>> I've been working on this for a few days and I think it's ready for >>> review. It's well-tested and extensively documented. I started using it >>> wherever I have context managers in GarlicSim. >>> >>> I'll be happy to get your opinions on my approach and any critiques you >>> may have. If there are no problems with this approach, I'll probably release >>> it with GarlicSim 0.6.1 and blog about it. >>> >>> Here is my `context_manager` >>> module<https://github.com/cool-RR/GarlicSim/blob/first_context_manager_review/garlicsim/garlicsim/general_misc/context_manager.py>. >>> Here are its >>> tests<https://github.com/cool-RR/GarlicSim/tree/first_context_manager_review/garlicsim/test_garlicsim/test_general_misc/test_context_manager> >>> . >>> >>> Following is the module's docstring which explains the module in more >>> detail. >>> >>> Ram. >>> >>> Defines the `ContextManager` and `ContextManagerType` classes. >>> >>> These classes allow for greater freedom both when (a) defining context >>> managers >>> and when (b) using them. >>> >>> Inherit all your context managers from `ContextManager` (or decorate your >>> generator functions with `ContextManagerType`) to enjoy all the benefits >>> described below. >>> >>> >>> Defining context managers >>> ------------------------- >>> >>> There are 3 different ways in which context managers can be defined, and >>> each >>> has their own advantages and disadvantages over the others. >>> >>> 1. The classic way to define a context manager is to define a class >>> with >>> `__enter__` and `__exit__` methods. This is allowed, and if you do >>> this >>> you should still inherit from `ContextManager`. Example: >>> >>> class MyContextManager(ContextManager): >>> def __enter__(self): >>> pass # preparation >>> def __exit__(self, type_=None, value=None, traceback=None): >>> pass # cleanup >>> >>> 2. As a decorated generator, like so: >>> >>> @ContextManagerType >>> def MyContextManager(): >>> try: >>> yield >>> finally: >>> pass # clean-up >>> >>> This usage is nothing new; It's also available when using the >>> standard >>> library's `contextlib.contextmanager` decorator. One thing that is >>> allowed >>> here that `contextlib` doesn't allow is to yield the context manager >>> itself >>> by doing `yield SelfHook`. >>> >>> 3. The third and novel way is by defining a class with a >>> `manage_context` >>> method which returns a decorator. Example: >>> >>> class MyContextManager(ContextManager): >>> def manage_context(self): >>> do_some_preparation() >>> try: >>> with some_lock: >>> yield self >>> finally: >>> do_some_cleanup() >>> >>> This approach is sometimes cleaner than defining `__enter__` and >>> `__exit__`; Especially when using another context manager inside >>> `manage_context`. In our example we did `with some_lock` in our >>> `manage_context`, which is shorter and more idiomatic than calling >>> `some_lock.__enter__` in an `__enter__` method and >>> `some_lock.__exit__` in >>> an `__exit__` method. >>> >>> >>> These were the different ways of *defining* a context manager. Now let's >>> see >>> the different ways of *using* a context manager: >>> >>> >>> Using context managers >>> ---------------------- >>> >>> There are 2 different ways in which context managers can be used: >>> >>> 1. The plain old honest-to-Guido `with` keyword: >>> >>> with MyContextManager() as my_context_manager: >>> do_stuff() >>> >>> 2. As a decorator to a function >>> >>> @MyContextManager() >>> def do_stuff(): >>> pass # doing stuff >>> >>> When the `do_stuff` function will be called, the context manager will >>> be >>> used. This functionality is also available in the standard library of >>> Python 3.2+ by using `contextlib.ContextDecorator`, but here it is >>> combined >>> with all the other goodies given by `ContextManager`. >>> >>> >>> That's it. Inherit all your context managers from `ContextManager` (or >>> decorate >>> your generator functions with `ContextManagerType`) to enjoy all these >>> benefits. >>> >>> >>> -- >>> Sincerely, >>> Ram Rachum >>> >>> _______________________________________________ >>> Python-il mailing list >>> [email protected] >>> http://hamakor.org.il/cgi-bin/mailman/listinfo/python-il >>> >>> >> > > > -- > Sincerely, > Ram Rachum >
_______________________________________________ Python-il mailing list [email protected] http://hamakor.org.il/cgi-bin/mailman/listinfo/python-il
