I'm still looking for more feedback on the issues raised in the last update of PEP 343. There hasn't been much direct feedback so far, but I've rephrased and suggested resolutions for the outstanding issues based on what feedback I have received, and my own thoughts over the last week of so.
For those simply skimming, my proposed issue resolutions are: 1. Use the slot name "__context__" instead of "__with__" 2. Reserve the builtin name "context" for future use as described below 3a. Give generator-iterators a native context that invokes self.close() 3b. Use "contextmanager" as a builtin decorator to get generator-contexts 4. Special case the __context__ slot to avoid the need to decorate it For those that disagree with the proposed resolutions above, or simply would like more details, here's the reasoning: 1. Should the slot be named "__with__" or "__context__"? Guido raised this as a side comment during the discussion of PJE's task variables pre-PEP, and it's a fair question. The closest analogous slot method ("__iter__") is named after the protocol it relates to, rather than the associated statement/expression keyword (that is, the method isn't called "__for__"). The next closest analogous slot is one that doesn't actually exist yet - the proposed "boolean" protocol. This again uses the name of a protocol rather than the associated keyword (that is, the name "__bool__" was suggested rather than "__if__"). At the moment, PEP 343 makes the opposite choice - it uses the keyword, rather than the protocol name (that is, it uses "__with__" instead of using "__context__"). That inconsistency would be a bad thing, in my opinion, and I propose that the slot should instead be named "__context__". 2. If the slot is called "__context__" what should a "context" builtin do? Again, considering existing slot names, a slot with a given name is generally invoked by the builtin type or function with the same name. This is true of the builtin types, and also true of iter, cmp and pow. getattr, setattr and delattr get in on the act as well. So, to be consistent, one would expect a "context" builtin to be able to be used such that "context(x)" invoked "x.__context__()". Such a method might special-case certain types, or have a two-argument form that accepted an "enter" function and an "exit" function, but using it to mark a generator that is to be used as a context manager (as currently suggested in PEP 343) would not be appropriate. I don't mind either way whether or not a "context" builtin is actually included for Python 2.5. However, even if it isn't included, the name should be reserved for that purpose (that is, we shouldn't be using it to name a generator decorator or a module). 3. How should generators behave when used as contexts? With PEP 342 accepted, generators pose a problem, because they have two possible uses as contexts. The first is for a generator that is intended to be used as an actual iterator. This case is a case of resource management - ensuring the close method is invoked on the generator-iterator when done with it (i.e., similar to the proposed native context for files). PEP 343 proposes a second use case for generators - to write custom context managers. In this case, the __enter__ method steps the generator once, and the __exit__ method finishes the job. I propose that we give generator-iterator objects resource management behaviour by default (i.e., __context__ and __enter__ methods that just "return self", and an __exit__ method that invokes "self.close()"). The "contextmanager" builtin decorator from previous drafts of the PEP (called simply "context" in the current draft) can then be used to get the custom context manager behaviour. I previously thought giving generators a native context caused problems with getting silent failures when the "contextmanager" decorator was inadvertently omitted. This is still technically true - the "with" statement itself won't raise a TypeError because the generator is a legal context. However, with this bug, the context manager won't be getting entered *at all* (it gets closed without its next() method ever being called). Even the most cursory testing of the generator-context function should be able to tell whether the generator-context is being entered or not. The main alternative (having yet-another-decorator to give generators "auto-close" functionality) would be possible, but the additional builtin clutter would be getting to the point where it started to concern me. And given that "yield" inside "try/finally" is now always legal, I consider it reasonable that using a generator in a "with" statement would also always be legal. Further, if type_new special cases __context__ as suggested below, then the context behaviour of generators used to define "__iter__" and "__context__" slots will always be appropriate. 4. Should the __context__ slot be special-cased in type_new? Currently, type_new special cases the "__new__" slot and automatically applies the staticmethod decorator when it finds a function occupying that slot in the class attribute dictionary. I propose that type_new also special case the situation where the "__context__" slot is occupied by a generator function, and automatically apply the "contextmanager" decorator. This looks much nicer when using a generator to write a __context__ function, and also avoids the situation where the decorator is omitted, and the object becomes legal to use directly in with statements but doesn't actually do the right thing. Regards, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.blogspot.com _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com