Skip to content

Missing information about non-yielding generator causing a RuntimeError in contextmanager decorator of contextlib #131658

@ArthurHNL

Description

@ArthurHNL

Documentation

When using the contextmanager decorator from contextlib, the documentation clearly states how it should be used. However, it does not mention that a RuntimeError is thrown when the provided generator never yields a value. See the following example:

@contextmanager
def my_optional_resource():
  if resource_is_required():
    resource = None
    try:
      resource = initialize_resource()
      yield resource
    finally:
      if resource:
        cleanup_resource(resource)

If in the example above is_resource_required() is False, the resource is never initialized and the generator never yields. Personally I expected nothing would actually happen and that the variable originating from the context manager would be None in any with statement using it. However it appears that (at least cpython) throws a RuntimeError indicating that the generator did not yield.

It feels like it makes sense to throw an exception here, but it would be benificial to include this in the documentation.

For completeness, this is a full example to replicate the exception being thrown:

from contextlib import contextmanager

def resource_is_required():
    return False

@contextmanager
def my_optional_resource():
  if resource_is_required():
    resource = None
    try:
      resource = initialize_resource()
      yield resource
    finally:
      if resource:
        cleanup_resource(resource)
        
with my_optional_resource() as resource:
    print(resource)

This yields the following exception output:

Traceback (most recent call last):
  File "main.py", line 17, in <module>
    with my_optional_resource() as resource:
  File "/usr/lib/python3.8/contextlib.py", line 115, in __enter__
    raise RuntimeError("generator didn't yield") from None
RuntimeError: generator didn't yield

It appears that the same happens for the asynccontextmanager decorator, but I did not attempt to replicate this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsDocumentation in the Doc dir

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions