annotate tests/test-ctxmanager.py @ 31426:43a7dfbead0c

parsers: handle refcounting of "parents" consistently Py_None can be refcounted like any other Python object. So do that.
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 13 Mar 2017 17:49:13 -0700
parents 441491aba8c3
children 68c43a416585
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1 from __future__ import absolute_import
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
2
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
3 import silenttestrunner
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
4 import unittest
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
5
28801
441491aba8c3 test-ctxmanager: stop direct symbol import of mercurial.util
Yuya Nishihara <yuya@tcha.org>
parents: 27786
diff changeset
6 from mercurial import util
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
7
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
8 class contextmanager(object):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
9 def __init__(self, name, trace):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
10 self.name = name
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
11 self.entered = False
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
12 self.exited = False
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
13 self.trace = trace
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
14
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
15 def __enter__(self):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
16 self.entered = True
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
17 self.trace(('enter', self.name))
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
18 return self
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
19
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
20 def __exit__(self, exc_type, exc_val, exc_tb):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
21 self.exited = exc_type, exc_val, exc_tb
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
22 self.trace(('exit', self.name))
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
23
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
24 def __repr__(self):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
25 return '<ctx %r>' % self.name
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
26
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
27 class ctxerror(Exception):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
28 pass
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
29
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
30 class raise_on_enter(contextmanager):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
31 def __enter__(self):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
32 self.trace(('raise', self.name))
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
33 raise ctxerror(self.name)
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
34
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
35 class raise_on_exit(contextmanager):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
36 def __exit__(self, exc_type, exc_val, exc_tb):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
37 self.trace(('raise', self.name))
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
38 raise ctxerror(self.name)
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
39
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
40 def ctxmgr(name, trace):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
41 return lambda: contextmanager(name, trace)
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
42
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
43 class test_ctxmanager(unittest.TestCase):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
44 def test_basics(self):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
45 trace = []
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
46 addtrace = trace.append
28801
441491aba8c3 test-ctxmanager: stop direct symbol import of mercurial.util
Yuya Nishihara <yuya@tcha.org>
parents: 27786
diff changeset
47 with util.ctxmanager(ctxmgr('a', addtrace), ctxmgr('b', addtrace)) as c:
27785
ba427b51f1d8 util: rename ctxmanager's __call__ method to enter
Bryan O'Sullivan <bryano@fb.com>
parents: 27703
diff changeset
48 a, b = c.enter()
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
49 c.atexit(addtrace, ('atexit', 'x'))
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
50 c.atexit(addtrace, ('atexit', 'y'))
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
51 self.assertEqual(trace, [('enter', 'a'), ('enter', 'b'),
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
52 ('atexit', 'y'), ('atexit', 'x'),
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
53 ('exit', 'b'), ('exit', 'a')])
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
54
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
55 def test_raise_on_enter(self):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
56 trace = []
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
57 addtrace = trace.append
27786
4a7dc29bfad8 test-ctxmanager: fix Python 2.6 compatibility problem
Bryan O'Sullivan <bryano@fb.com>
parents: 27785
diff changeset
58 def go():
28801
441491aba8c3 test-ctxmanager: stop direct symbol import of mercurial.util
Yuya Nishihara <yuya@tcha.org>
parents: 27786
diff changeset
59 with util.ctxmanager(ctxmgr('a', addtrace),
441491aba8c3 test-ctxmanager: stop direct symbol import of mercurial.util
Yuya Nishihara <yuya@tcha.org>
parents: 27786
diff changeset
60 lambda: raise_on_enter('b', addtrace)) as c:
27785
ba427b51f1d8 util: rename ctxmanager's __call__ method to enter
Bryan O'Sullivan <bryano@fb.com>
parents: 27703
diff changeset
61 c.enter()
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
62 addtrace('unreachable')
27786
4a7dc29bfad8 test-ctxmanager: fix Python 2.6 compatibility problem
Bryan O'Sullivan <bryano@fb.com>
parents: 27785
diff changeset
63 self.assertRaises(ctxerror, go)
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
64 self.assertEqual(trace, [('enter', 'a'), ('raise', 'b'), ('exit', 'a')])
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
65
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
66 def test_raise_on_exit(self):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
67 trace = []
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
68 addtrace = trace.append
27786
4a7dc29bfad8 test-ctxmanager: fix Python 2.6 compatibility problem
Bryan O'Sullivan <bryano@fb.com>
parents: 27785
diff changeset
69 def go():
28801
441491aba8c3 test-ctxmanager: stop direct symbol import of mercurial.util
Yuya Nishihara <yuya@tcha.org>
parents: 27786
diff changeset
70 with util.ctxmanager(ctxmgr('a', addtrace),
441491aba8c3 test-ctxmanager: stop direct symbol import of mercurial.util
Yuya Nishihara <yuya@tcha.org>
parents: 27786
diff changeset
71 lambda: raise_on_exit('b', addtrace)) as c:
27785
ba427b51f1d8 util: rename ctxmanager's __call__ method to enter
Bryan O'Sullivan <bryano@fb.com>
parents: 27703
diff changeset
72 c.enter()
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
73 addtrace('running')
27786
4a7dc29bfad8 test-ctxmanager: fix Python 2.6 compatibility problem
Bryan O'Sullivan <bryano@fb.com>
parents: 27785
diff changeset
74 self.assertRaises(ctxerror, go)
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
75 self.assertEqual(trace, [('enter', 'a'), ('enter', 'b'), 'running',
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
76 ('raise', 'b'), ('exit', 'a')])
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
77
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
78 if __name__ == '__main__':
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
79 silenttestrunner.main(__name__)