3050 pos = path.rfind('/') |
3050 pos = path.rfind('/') |
3051 while pos != -1: |
3051 while pos != -1: |
3052 yield path[:pos] |
3052 yield path[:pos] |
3053 pos = path.rfind('/', 0, pos) |
3053 pos = path.rfind('/', 0, pos) |
3054 |
3054 |
3055 class ctxmanager(object): |
|
3056 '''A context manager for use in 'with' blocks to allow multiple |
|
3057 contexts to be entered at once. This is both safer and more |
|
3058 flexible than contextlib.nested. |
|
3059 |
|
3060 Once Mercurial supports Python 2.7+, this will become mostly |
|
3061 unnecessary. |
|
3062 ''' |
|
3063 |
|
3064 def __init__(self, *args): |
|
3065 '''Accepts a list of no-argument functions that return context |
|
3066 managers. These will be invoked at __call__ time.''' |
|
3067 self._pending = args |
|
3068 self._atexit = [] |
|
3069 |
|
3070 def __enter__(self): |
|
3071 return self |
|
3072 |
|
3073 def enter(self): |
|
3074 '''Create and enter context managers in the order in which they were |
|
3075 passed to the constructor.''' |
|
3076 values = [] |
|
3077 for func in self._pending: |
|
3078 obj = func() |
|
3079 values.append(obj.__enter__()) |
|
3080 self._atexit.append(obj.__exit__) |
|
3081 del self._pending |
|
3082 return values |
|
3083 |
|
3084 def atexit(self, func, *args, **kwargs): |
|
3085 '''Add a function to call when this context manager exits. The |
|
3086 ordering of multiple atexit calls is unspecified, save that |
|
3087 they will happen before any __exit__ functions.''' |
|
3088 def wrapper(exc_type, exc_val, exc_tb): |
|
3089 func(*args, **kwargs) |
|
3090 self._atexit.append(wrapper) |
|
3091 return func |
|
3092 |
|
3093 def __exit__(self, exc_type, exc_val, exc_tb): |
|
3094 '''Context managers are exited in the reverse order from which |
|
3095 they were created.''' |
|
3096 received = exc_type is not None |
|
3097 suppressed = False |
|
3098 pending = None |
|
3099 self._atexit.reverse() |
|
3100 for exitfunc in self._atexit: |
|
3101 try: |
|
3102 if exitfunc(exc_type, exc_val, exc_tb): |
|
3103 suppressed = True |
|
3104 exc_type = None |
|
3105 exc_val = None |
|
3106 exc_tb = None |
|
3107 except BaseException: |
|
3108 pending = sys.exc_info() |
|
3109 exc_type, exc_val, exc_tb = pending = sys.exc_info() |
|
3110 del self._atexit |
|
3111 if pending: |
|
3112 raise exc_val |
|
3113 return received and suppressed |
|
3114 |
|
3115 # compression code |
3055 # compression code |
3116 |
3056 |
3117 SERVERROLE = 'server' |
3057 SERVERROLE = 'server' |
3118 CLIENTROLE = 'client' |
3058 CLIENTROLE = 'client' |
3119 |
3059 |