NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

contextlib.py (2192B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\contextlib.py
      2 import sys
      3 from functools import wraps
      4 from warnings import warn
      5 __all__ = ['contextmanager', 'nested', 'closing']
      6 
      7 class GeneratorContextManager(object):
      8 
      9     def __init__(self, gen):
     10         self.gen = gen
     11 
     12     def __enter__(self):
     13         try:
     14             return self.gen.next()
     15         except StopIteration:
     16             raise RuntimeError("generator didn't yield")
     17 
     18     def __exit__(self, type, value, traceback):
     19         if type is None:
     20             try:
     21                 self.gen.next()
     22             except StopIteration:
     23                 return
     24 
     25             raise RuntimeError("generator didn't stop")
     26         else:
     27             if value is None:
     28                 value = type()
     29             try:
     30                 self.gen.throw(type, value, traceback)
     31                 raise RuntimeError("generator didn't stop after throw()")
     32             except StopIteration as exc:
     33                 return exc is not value
     34             except:
     35                 if sys.exc_info()[1] is not value:
     36                     raise
     37 
     38 
     39 def contextmanager(func):
     40 
     41     @wraps(func)
     42     def helper(*args, **kwds):
     43         return GeneratorContextManager(func(*args, **kwds))
     44 
     45     return helper
     46 
     47 
     48 @contextmanager
     49 def nested(*managers):
     50     warn('With-statements now directly support multiple context managers', DeprecationWarning, 3)
     51     exits = []
     52     vars = []
     53     exc = (None, None, None)
     54     try:
     55         for mgr in managers:
     56             exit = mgr.__exit__
     57             enter = mgr.__enter__
     58             vars.append(enter())
     59             exits.append(exit)
     60 
     61         yield vars
     62     except:
     63         exc = sys.exc_info()
     64     finally:
     65         while exits:
     66             exit = exits.pop()
     67             try:
     68                 if exit(*exc):
     69                     exc = (None, None, None)
     70             except:
     71                 exc = sys.exc_info()
     72 
     73         if exc != (None, None, None):
     74             raise exc[0], exc[1], exc[2]
     75 
     76 
     77 class closing(object):
     78 
     79     def __init__(self, thing):
     80         self.thing = thing
     81 
     82     def __enter__(self):
     83         return self.thing
     84 
     85     def __exit__(self, *exc_info):
     86         self.thing.close()