[Python-Dev] PEP 377 - allow __enter__() methods to skip the statement body

Nick Coghlan ncoghlan at gmail.com
Sat Mar 21 10:13:06 CET 2009


James Pye wrote:
> The identification of this issue came from an *experiment* attempting to
> create a *single* "daemonized()" CM that would execute the
> with-statement's block in a new child process and, of course, not
> execute it in the parent. At first, I ran into the RuntimeError in the
> parent process, and then after rewriting the CMs as classes, I realized
> the futility.
> 
> with daemonized():
>  run_some_subprocess()
> 
> Of course it was all possible if I used the component CMs directly:
> 
> with parent_trap():
>  with fork_but_raise_in_parent():
>   run_some_subprocess()

When updating the PEP with the rejection notice, it occurred to me that
it is fairly easy to handle specific use cases like this reasonably
cleanly by including a callable in the design that is always used inline
in the body of the outermost with statement. For example:

  @contextmanager
  def make_daemon()
    class SkipInParent(Exception): pass
    def startd():
       # Fork process, then raise SkipInParent
       # in the parent process. The child process
       # continues running as a daemon.
    try:
      yield startd
    except SkipInParent:
      pass


  with make_daemon() as startd:
    startd()
    # Daemon code goes here

With that approach, since it is startd() that raises the exception
rather than __enter__() then __exit__() will always be given the chance
to suppress it.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------


More information about the Python-Dev mailing list