code: def contextmanager(func):
      
      @wraps(func)
      def helper(*args, **kwds):
          return GeneratorContextManager(func(*args, **kwds))
      return helper
docs: @contextmanager decorator.
  
      Typical usage:
  
          @contextmanager
          def some_generator(<arguments>):
              <setup>
              try:
                  yield <value>
              finally:
                  <cleanup>
  
      This makes this:
  
          with some_generator(<arguments>) as <variable>:
              <body>
  
      equivalent to this:
  
          <setup>
          try:
              <variable> = <value>
              <body>
          finally:
              <cleanup>