@@ -399,6 +399,8 @@ The execution of the :keyword:`with` statement with one "item" proceeds as follo
399399#. The context expression (the expression given in the :token: `with_item `) is
400400 evaluated to obtain a context manager.
401401
402+ #. The context manager's :meth: `__enter__ ` is loaded for later use.
403+
402404#. The context manager's :meth: `__exit__ ` is loaded for later use.
403405
404406#. The context manager's :meth: `__enter__ ` method is invoked.
@@ -430,17 +432,41 @@ The execution of the :keyword:`with` statement with one "item" proceeds as follo
430432 value from :meth: `__exit__ ` is ignored, and execution proceeds at the normal
431433 location for the kind of exit that was taken.
432434
435+ The following code::
436+
437+ with EXPRESSION as TARGET:
438+ SUITE
439+
440+ is semantically equivalent to::
441+
442+ manager = (EXPRESSION)
443+ enter = type(manager).__enter__
444+ exit = type(manager).__exit__
445+ value = enter(manager)
446+ hit_except = False
447+
448+ try:
449+ TARGET = value
450+ SUITE
451+ except:
452+ hit_except = True
453+ if not exit(manager, *sys.exc_info()):
454+ raise
455+ finally:
456+ if not hit_except:
457+ exit(manager, None, None, None)
458+
433459With more than one item, the context managers are processed as if multiple
434460:keyword: `with ` statements were nested::
435461
436462 with A() as a, B() as b:
437- suite
463+ SUITE
438464
439- is equivalent to ::
465+ is semantically equivalent to::
440466
441467 with A() as a:
442468 with B() as b:
443- suite
469+ SUITE
444470
445471.. versionchanged :: 3.1
446472 Support for multiple context expressions.
@@ -772,24 +798,25 @@ iterators.
772798The following code::
773799
774800 async for TARGET in ITER:
775- BLOCK
801+ SUITE
776802 else:
777- BLOCK2
803+ SUITE2
778804
779805Is semantically equivalent to::
780806
781807 iter = (ITER)
782808 iter = type(iter).__aiter__(iter)
783809 running = True
810+
784811 while running:
785812 try:
786813 TARGET = await type(iter).__anext__(iter)
787814 except StopAsyncIteration:
788815 running = False
789816 else:
790- BLOCK
817+ SUITE
791818 else:
792- BLOCK2
819+ SUITE2
793820
794821See also :meth: `__aiter__ ` and :meth: `__anext__ ` for details.
795822
@@ -811,23 +838,27 @@ able to suspend execution in its *enter* and *exit* methods.
811838
812839The following code::
813840
814- async with EXPR as VAR :
815- BLOCK
841+ async with EXPRESSION as TARGET :
842+ SUITE
816843
817- Is semantically equivalent to::
844+ is semantically equivalent to::
818845
819- mgr = (EXPR)
820- aexit = type(mgr).__aexit__
821- aenter = type(mgr).__aenter__(mgr)
846+ manager = (EXPRESSION)
847+ aexit = type(manager).__aexit__
848+ aenter = type(manager).__aenter__
849+ value = await aenter(manager)
850+ hit_except = False
822851
823- VAR = await aenter
824852 try:
825- BLOCK
853+ TARGET = value
854+ SUITE
826855 except:
827- if not await aexit(mgr, *sys.exc_info()):
856+ hit_except = True
857+ if not await aexit(manager, *sys.exc_info()):
828858 raise
829- else:
830- await aexit(mgr, None, None, None)
859+ finally:
860+ if not hit_except:
861+ await aexit(manager, None, None, None)
831862
832863See also :meth: `__aenter__ ` and :meth: `__aexit__ ` for details.
833864
0 commit comments