﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
34369	Improve the interaction between transaction.atomic() and generator functions	Raphaël Barrois	nobody	"When wrapping a generator function with `@transaction.atomic()`, the decorator doesn't apply during the generator's execution.

This is a standard behaviour of all decorators for all generators — when the decorator calls the decorated function, that function returns immediately with the generator object — and doesn't execute even a single line of code.

Thus, in the following code example:

{{{#!python
@transaction.atomic()
def frobnicate_users(qs):
  for user in qs.select_for_update():
    yield user.spam_it()
}}}

The code will fail at runtime, since the `.select_for_update()` is called **after** returning from the `@transaction.atomic()` block.

I believe it would make sense for Django to improve this interaction; possible options would be:
- Having `transaction.atomic()` use `inspect.isgeneratorfunction(wrapped)` to raise when it is decorating a generator function (with guidance to replace it with a `with transaction.atomic()` in the function body);
- Having `transaction.atomic()` automatically adjust itself to generator functions — if the wrapped function is a generator function, place the atomic block around a new generator wrapping the returned generator;
- Have `transaction.atomic()` raise a warning if the value returned by its wrapped function is a generator.

It might make sense to add an optional kwarg to `transaction.atomic()` to control that behaviour — for instance, this improvement should not alter the handling of `StreamingResponse`.

If there is a consensus on moving this forward, I will happily provide a related pull-request."	Cleanup/optimization	closed	Database layer (models, ORM)	4.1	Normal	wontfix	atomic generator		Unreviewed	0	0	0	0	0	0
