()
| 309 | |
| 310 | |
| 311 | def test_closing_iterator(): |
| 312 | class Namespace: |
| 313 | got_close = False |
| 314 | got_additional = False |
| 315 | |
| 316 | class Response: |
| 317 | def __init__(self, environ, start_response): |
| 318 | self.start = start_response |
| 319 | |
| 320 | # Return a generator instead of making the object its own |
| 321 | # iterator. This ensures that ClosingIterator calls close on |
| 322 | # the iterable (the object), not the iterator. |
| 323 | def __iter__(self): |
| 324 | self.start("200 OK", [("Content-Type", "text/plain")]) |
| 325 | yield "some content" |
| 326 | |
| 327 | def close(self): |
| 328 | Namespace.got_close = True |
| 329 | |
| 330 | def additional(): |
| 331 | Namespace.got_additional = True |
| 332 | |
| 333 | def app(environ, start_response): |
| 334 | return ClosingIterator(Response(environ, start_response), additional) |
| 335 | |
| 336 | app_iter, status, headers = run_wsgi_app(app, create_environ(), buffered=True) |
| 337 | |
| 338 | assert "".join(app_iter) == "some content" |
| 339 | assert Namespace.got_close |
| 340 | assert Namespace.got_additional |
nothing calls this directly
no test coverage detected