##// END OF EJS Templates
extensions: register functions always at loading extension (issue5601)...
extensions: register functions always at loading extension (issue5601) Before this patch, functions defined in extensions are registered via extra loaders only in _dispatch(). Therefore, loading extensions in other code paths like below omits registration of functions. - WSGI service - operation across repositories (e.g. subrepo) - test-duplicateoptions.py, using extensions.loadall() directly To register functions always at loading new extension, this patch moves implementation for extra loading from dispatch._dispatch() to extensions.loadall(). AFAIK, only commands module causes cyclic dependency between extensions module, but this patch imports all related modules just before extra loading in loadall(), in order to centralize them. This patch makes extensions.py depend on many other modules, even though extensions.py itself doesn't. It should be avoided if possible, but I don't have any better idea. Some other places like below aren't reasonable for extra loading, IMHO. - specific function in newly added module: existing callers of extensions.loadall() should invoke it, too - hg.repository() or so: no-repo commands aren't covered by this. BTW, this patch removes _loaded.add(name) on relocation, because dispatch._loaded is used only for extraloaders (for similar reason, "exts" variable is removed, too).

File last commit:

r32279:68c43a41 default
r33052:45b0e9d0 default
Show More
test-ctxmanager.py
77 lines | 2.4 KiB | text/x-python | PythonLexer
/ tests / test-ctxmanager.py
Bryan O'Sullivan
util: introduce ctxmanager, to avoid nested try/finally blocks...
r27703 from __future__ import absolute_import
import silenttestrunner
import unittest
Yuya Nishihara
test-ctxmanager: stop direct symbol import of mercurial.util
r28801 from mercurial import util
Bryan O'Sullivan
util: introduce ctxmanager, to avoid nested try/finally blocks...
r27703
class contextmanager(object):
def __init__(self, name, trace):
self.name = name
self.entered = False
self.exited = False
self.trace = trace
def __enter__(self):
self.entered = True
self.trace(('enter', self.name))
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.exited = exc_type, exc_val, exc_tb
self.trace(('exit', self.name))
def __repr__(self):
return '<ctx %r>' % self.name
class ctxerror(Exception):
pass
class raise_on_enter(contextmanager):
def __enter__(self):
self.trace(('raise', self.name))
raise ctxerror(self.name)
class raise_on_exit(contextmanager):
def __exit__(self, exc_type, exc_val, exc_tb):
self.trace(('raise', self.name))
raise ctxerror(self.name)
def ctxmgr(name, trace):
return lambda: contextmanager(name, trace)
class test_ctxmanager(unittest.TestCase):
def test_basics(self):
trace = []
addtrace = trace.append
Yuya Nishihara
test-ctxmanager: stop direct symbol import of mercurial.util
r28801 with util.ctxmanager(ctxmgr('a', addtrace), ctxmgr('b', addtrace)) as c:
Bryan O'Sullivan
util: rename ctxmanager's __call__ method to enter
r27785 a, b = c.enter()
Bryan O'Sullivan
util: introduce ctxmanager, to avoid nested try/finally blocks...
r27703 c.atexit(addtrace, ('atexit', 'x'))
c.atexit(addtrace, ('atexit', 'y'))
self.assertEqual(trace, [('enter', 'a'), ('enter', 'b'),
('atexit', 'y'), ('atexit', 'x'),
('exit', 'b'), ('exit', 'a')])
def test_raise_on_enter(self):
trace = []
addtrace = trace.append
Gregory Szorc
tests: use context manager form of assertRaises...
r32279 with self.assertRaises(ctxerror):
Yuya Nishihara
test-ctxmanager: stop direct symbol import of mercurial.util
r28801 with util.ctxmanager(ctxmgr('a', addtrace),
lambda: raise_on_enter('b', addtrace)) as c:
Bryan O'Sullivan
util: rename ctxmanager's __call__ method to enter
r27785 c.enter()
Bryan O'Sullivan
util: introduce ctxmanager, to avoid nested try/finally blocks...
r27703 addtrace('unreachable')
self.assertEqual(trace, [('enter', 'a'), ('raise', 'b'), ('exit', 'a')])
def test_raise_on_exit(self):
trace = []
addtrace = trace.append
Gregory Szorc
tests: use context manager form of assertRaises...
r32279 with self.assertRaises(ctxerror):
Yuya Nishihara
test-ctxmanager: stop direct symbol import of mercurial.util
r28801 with util.ctxmanager(ctxmgr('a', addtrace),
lambda: raise_on_exit('b', addtrace)) as c:
Bryan O'Sullivan
util: rename ctxmanager's __call__ method to enter
r27785 c.enter()
Bryan O'Sullivan
util: introduce ctxmanager, to avoid nested try/finally blocks...
r27703 addtrace('running')
self.assertEqual(trace, [('enter', 'a'), ('enter', 'b'), 'running',
('raise', 'b'), ('exit', 'a')])
if __name__ == '__main__':
silenttestrunner.main(__name__)