Merge lp:~jelmer/bzr/more-lazy-hooks into lp:bzr

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Vincent Ladeuil
Approved revision: no longer in the source branch.
Merged at revision: 5748
Proposed branch: lp:~jelmer/bzr/more-lazy-hooks
Merge into: lp:bzr
Prerequisite: lp:~jelmer/bzr/reset-lazy-hooks
Diff against target: 747 lines (+137/-160)
21 files modified
bzrlib/branch.py (+28/-28)
bzrlib/bzrdir.py (+5/-5)
bzrlib/commands.py (+10/-10)
bzrlib/hooks.py (+4/-2)
bzrlib/info.py (+3/-4)
bzrlib/lock.py (+11/-11)
bzrlib/merge.py (+3/-3)
bzrlib/merge_directive.py (+3/-3)
bzrlib/msgeditor.py (+4/-4)
bzrlib/mutabletree.py (+5/-5)
bzrlib/plugins/changelog_merge/__init__.py (+6/-17)
bzrlib/plugins/launchpad/lp_propose.py (+6/-13)
bzrlib/plugins/news_merge/__init__.py (+7/-16)
bzrlib/smart/client.py (+3/-3)
bzrlib/smart/server.py (+8/-8)
bzrlib/status.py (+5/-5)
bzrlib/tests/test_hooks.py (+15/-16)
bzrlib/tests/test_selftest.py (+5/-5)
bzrlib/tests/transport_util.py (+2/-1)
bzrlib/version_info_formats/format_rio.py (+1/-1)
doc/en/release-notes/bzr-2.4.txt (+3/-0)
To merge this branch: bzr merge lp:~jelmer/bzr/more-lazy-hooks
Reviewer Review Type Date Requested Status
Vincent Ladeuil Needs Fixing
Review via email: mp+55523@code.launchpad.net

Commit message

Support installing lazy hooks for all existing hook points, deprecate Hooks.create_hook.

Description of the change

Support installing lazy hooks for all existing hook points, like was already done for bzrlib.version_info_formats.format_rio.

Deprecate Hooks.create_hook, which doesn't work well together with lazy hooks.

To post a comment you must log in.
Revision history for this message
Vincent Ladeuil (vila) wrote :

One test failure when run on babune:
http://babune.ladeuil.net:24842/view/debug/job/selftest-subset-all/108/aggregatedTestReport/

<<< bzrlib.tests.test_branch.TestHooks.test_constructor
Stack Trace

_StringException: Text attachment: log
------------
1426.373 opening working tree '/private/tmp/testbzr-EefziM.tmp'
------------
Text attachment: traceback
------------
Traceback (most recent call last):
  File "/home/vila/lib/python/testtools/runtest.py", line 144, in _run_user
  File "/home/vila/lib/python/testtools/testcase.py", line 487, in _run_test_method
  File "/Users/babune/babune/slaves/macadam.local/workspace/selftest-subset-macadam/bzrlib/tests/test_branch.py", line 574, in test_constructor
    hooks = _mod_branch.BranchHooks("bzrlib.tests.test_branch", "branch.hooks")
TypeError: __init__() takes exactly 1 argument (3 given)
------------

Since the changes are pretty mechanical, it's probably shallow, so tweak.

review: Needs Fixing
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

On Thu, 2011-03-31 at 14:26 +0000, Vincent Ladeuil wrote:
> Review: Needs Fixing
> One test failure when run on babune:
> http://babune.ladeuil.net:24842/view/debug/job/selftest-subset-all/108/aggregatedTestReport/
>
> <<< bzrlib.tests.test_branch.TestHooks.test_constructor
> Stack Trace
>
> _StringException: Text attachment: log
> ------------
> 1426.373 opening working tree '/private/tmp/testbzr-EefziM.tmp'
> ------------
> Text attachment: traceback
> ------------
> Traceback (most recent call last):
> File "/home/vila/lib/python/testtools/runtest.py", line 144, in _run_user
> File "/home/vila/lib/python/testtools/testcase.py", line 487, in _run_test_method
> File "/Users/babune/babune/slaves/macadam.local/workspace/selftest-subset-macadam/bzrlib/tests/test_branch.py", line 574, in test_constructor
> hooks = _mod_branch.BranchHooks("bzrlib.tests.test_branch", "branch.hooks")
> TypeError: __init__() takes exactly 1 argument (3 given)
> ------------
>
> Since the changes are pretty mechanical, it's probably shallow, so tweak.
Fixed, thanks for the review!

Cheers,

Jelmer

Revision history for this message
Jelmer Vernooij (jelmer) wrote :

sent to pqm by email

Revision history for this message
Jelmer Vernooij (jelmer) wrote :

sent to pqm by email

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/branch.py'
2--- bzrlib/branch.py 2011-03-26 01:37:08 +0000
3+++ bzrlib/branch.py 2011-03-31 15:13:30 +0000
4@@ -57,7 +57,7 @@
5 needs_write_lock,
6 only_raises,
7 )
8-from bzrlib.hooks import HookPoint, Hooks
9+from bzrlib.hooks import Hooks
10 from bzrlib.inter import InterObject
11 from bzrlib.lock import _RelockDebugMixin, LogicalLockResult
12 from bzrlib import registry
13@@ -1808,25 +1808,25 @@
14 These are all empty initially, because by default nothing should get
15 notified.
16 """
17- Hooks.__init__(self)
18- self.create_hook(HookPoint('set_rh',
19+ Hooks.__init__(self, "bzrlib.branch", "Branch.hooks")
20+ self.add_hook('set_rh',
21 "Invoked whenever the revision history has been set via "
22 "set_revision_history. The api signature is (branch, "
23 "revision_history), and the branch will be write-locked. "
24 "The set_rh hook can be expensive for bzr to trigger, a better "
25- "hook to use is Branch.post_change_branch_tip.", (0, 15), None))
26- self.create_hook(HookPoint('open',
27+ "hook to use is Branch.post_change_branch_tip.", (0, 15))
28+ self.add_hook('open',
29 "Called with the Branch object that has been opened after a "
30- "branch is opened.", (1, 8), None))
31- self.create_hook(HookPoint('post_push',
32+ "branch is opened.", (1, 8))
33+ self.add_hook('post_push',
34 "Called after a push operation completes. post_push is called "
35 "with a bzrlib.branch.BranchPushResult object and only runs in the "
36- "bzr client.", (0, 15), None))
37- self.create_hook(HookPoint('post_pull',
38+ "bzr client.", (0, 15))
39+ self.add_hook('post_pull',
40 "Called after a pull operation completes. post_pull is called "
41 "with a bzrlib.branch.PullResult object and only runs in the "
42- "bzr client.", (0, 15), None))
43- self.create_hook(HookPoint('pre_commit',
44+ "bzr client.", (0, 15))
45+ self.add_hook('pre_commit',
46 "Called after a commit is calculated but before it is "
47 "completed. pre_commit is called with (local, master, old_revno, "
48 "old_revid, future_revno, future_revid, tree_delta, future_tree"
49@@ -1835,29 +1835,29 @@
50 "basis revision. hooks MUST NOT modify this delta. "
51 " future_tree is an in-memory tree obtained from "
52 "CommitBuilder.revision_tree() and hooks MUST NOT modify this "
53- "tree.", (0,91), None))
54- self.create_hook(HookPoint('post_commit',
55+ "tree.", (0,91))
56+ self.add_hook('post_commit',
57 "Called in the bzr client after a commit has completed. "
58 "post_commit is called with (local, master, old_revno, old_revid, "
59 "new_revno, new_revid). old_revid is NULL_REVISION for the first "
60- "commit to a branch.", (0, 15), None))
61- self.create_hook(HookPoint('post_uncommit',
62+ "commit to a branch.", (0, 15))
63+ self.add_hook('post_uncommit',
64 "Called in the bzr client after an uncommit completes. "
65 "post_uncommit is called with (local, master, old_revno, "
66 "old_revid, new_revno, new_revid) where local is the local branch "
67 "or None, master is the target branch, and an empty branch "
68- "receives new_revno of 0, new_revid of None.", (0, 15), None))
69- self.create_hook(HookPoint('pre_change_branch_tip',
70+ "receives new_revno of 0, new_revid of None.", (0, 15))
71+ self.add_hook('pre_change_branch_tip',
72 "Called in bzr client and server before a change to the tip of a "
73 "branch is made. pre_change_branch_tip is called with a "
74 "bzrlib.branch.ChangeBranchTipParams. Note that push, pull, "
75- "commit, uncommit will all trigger this hook.", (1, 6), None))
76- self.create_hook(HookPoint('post_change_branch_tip',
77+ "commit, uncommit will all trigger this hook.", (1, 6))
78+ self.add_hook('post_change_branch_tip',
79 "Called in bzr client and server after a change to the tip of a "
80 "branch is made. post_change_branch_tip is called with a "
81 "bzrlib.branch.ChangeBranchTipParams. Note that push, pull, "
82- "commit, uncommit will all trigger this hook.", (1, 4), None))
83- self.create_hook(HookPoint('transform_fallback_location',
84+ "commit, uncommit will all trigger this hook.", (1, 4))
85+ self.add_hook('transform_fallback_location',
86 "Called when a stacked branch is activating its fallback "
87 "locations. transform_fallback_location is called with (branch, "
88 "url), and should return a new url. Returning the same url "
89@@ -1868,23 +1868,23 @@
90 "fallback locations have not been activated. When there are "
91 "multiple hooks installed for transform_fallback_location, "
92 "all are called with the url returned from the previous hook."
93- "The order is however undefined.", (1, 9), None))
94- self.create_hook(HookPoint('automatic_tag_name',
95+ "The order is however undefined.", (1, 9))
96+ self.add_hook('automatic_tag_name',
97 "Called to determine an automatic tag name for a revision. "
98 "automatic_tag_name is called with (branch, revision_id) and "
99 "should return a tag name or None if no tag name could be "
100 "determined. The first non-None tag name returned will be used.",
101- (2, 2), None))
102- self.create_hook(HookPoint('post_branch_init',
103+ (2, 2))
104+ self.add_hook('post_branch_init',
105 "Called after new branch initialization completes. "
106 "post_branch_init is called with a "
107 "bzrlib.branch.BranchInitHookParams. "
108 "Note that init, branch and checkout (both heavyweight and "
109- "lightweight) will all trigger this hook.", (2, 2), None))
110- self.create_hook(HookPoint('post_switch',
111+ "lightweight) will all trigger this hook.", (2, 2))
112+ self.add_hook('post_switch',
113 "Called after a checkout switches branch. "
114 "post_switch is called with a "
115- "bzrlib.branch.SwitchHookParams.", (2, 2), None))
116+ "bzrlib.branch.SwitchHookParams.", (2, 2))
117
118
119
120
121=== modified file 'bzrlib/bzrdir.py'
122--- bzrlib/bzrdir.py 2011-03-24 01:23:35 +0000
123+++ bzrlib/bzrdir.py 2011-03-31 15:13:30 +0000
124@@ -1082,15 +1082,15 @@
125
126 def __init__(self):
127 """Create the default hooks."""
128- hooks.Hooks.__init__(self)
129- self.create_hook(hooks.HookPoint('pre_open',
130+ hooks.Hooks.__init__(self, "bzrlib.bzrdir", "BzrDir.hooks")
131+ self.add_hook('pre_open',
132 "Invoked before attempting to open a BzrDir with the transport "
133- "that the open will use.", (1, 14), None))
134- self.create_hook(hooks.HookPoint('post_repo_init',
135+ "that the open will use.", (1, 14))
136+ self.add_hook('post_repo_init',
137 "Invoked after a repository has been initialized. "
138 "post_repo_init is called with a "
139 "bzrlib.bzrdir.RepoInitHookParams.",
140- (2, 2), None))
141+ (2, 2))
142
143 # install the default hooks
144 BzrDir.hooks = BzrDirHooks()
145
146=== modified file 'bzrlib/commands.py'
147--- bzrlib/commands.py 2011-02-04 22:25:59 +0000
148+++ bzrlib/commands.py 2011-03-31 15:13:30 +0000
149@@ -46,7 +46,7 @@
150 )
151 """)
152
153-from bzrlib.hooks import HookPoint, Hooks
154+from bzrlib.hooks import Hooks
155 # Compatibility - Option used to be in commands.
156 from bzrlib.option import Option
157 from bzrlib.plugin import disable_plugins, load_plugins
158@@ -775,30 +775,30 @@
159 These are all empty initially, because by default nothing should get
160 notified.
161 """
162- Hooks.__init__(self)
163- self.create_hook(HookPoint('extend_command',
164+ Hooks.__init__(self, "bzrlib.commands", "Command.hooks")
165+ self.add_hook('extend_command',
166 "Called after creating a command object to allow modifications "
167 "such as adding or removing options, docs etc. Called with the "
168- "new bzrlib.commands.Command object.", (1, 13), None))
169- self.create_hook(HookPoint('get_command',
170+ "new bzrlib.commands.Command object.", (1, 13))
171+ self.add_hook('get_command',
172 "Called when creating a single command. Called with "
173 "(cmd_or_None, command_name). get_command should either return "
174 "the cmd_or_None parameter, or a replacement Command object that "
175 "should be used for the command. Note that the Command.hooks "
176 "hooks are core infrastructure. Many users will prefer to use "
177 "bzrlib.commands.register_command or plugin_cmds.register_lazy.",
178- (1, 17), None))
179- self.create_hook(HookPoint('get_missing_command',
180+ (1, 17))
181+ self.add_hook('get_missing_command',
182 "Called when creating a single command if no command could be "
183 "found. Called with (command_name). get_missing_command should "
184 "either return None, or a Command object to be used for the "
185- "command.", (1, 17), None))
186- self.create_hook(HookPoint('list_commands',
187+ "command.", (1, 17))
188+ self.add_hook('list_commands',
189 "Called when enumerating commands. Called with a set of "
190 "cmd_name strings for all the commands found so far. This set "
191 " is safe to mutate - e.g. to remove a command. "
192 "list_commands should return the updated set of command names.",
193- (1, 17), None))
194+ (1, 17))
195
196 Command.hooks = CommandHooks()
197
198
199=== modified file 'bzrlib/hooks.py'
200--- bzrlib/hooks.py 2011-02-18 17:44:53 +0000
201+++ bzrlib/hooks.py 2011-03-31 15:13:30 +0000
202@@ -145,10 +145,10 @@
203 else:
204 callbacks = None
205 hookpoint = HookPoint(name=name, doc=doc, introduced=introduced,
206- deprecated=deprecated,
207- callbacks=callbacks)
208+ deprecated=deprecated, callbacks=callbacks)
209 self[name] = hookpoint
210
211+ @symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4)))
212 def create_hook(self, hook):
213 """Create a hook which can have callbacks registered for it.
214
215@@ -392,6 +392,8 @@
216 return '\n'.join(segments)
217
218
219+# Lazily registered hooks. Maps (module, name, hook_name) tuples
220+# to lists of tuples with objectgetters and names
221 _lazy_hooks = {}
222
223
224
225=== modified file 'bzrlib/info.py'
226--- bzrlib/info.py 2010-04-30 11:35:43 +0000
227+++ bzrlib/info.py 2011-03-31 15:13:30 +0000
228@@ -481,12 +481,11 @@
229 """Hooks for the info command."""
230
231 def __init__(self):
232- super(InfoHooks, self).__init__()
233- self.create_hook(_mod_hooks.HookPoint('repository',
234+ super(InfoHooks, self).__init__("bzrlib.info", "hooks")
235+ self.add_hook('repository',
236 "Invoked when displaying the statistics for a repository. "
237 "repository is called with a statistics dictionary as returned "
238- "by the repository and a file-like object to write to.", (1, 15),
239- None))
240+ "by the repository and a file-like object to write to.", (1, 15))
241
242
243 hooks = InfoHooks()
244
245=== modified file 'bzrlib/lock.py'
246--- bzrlib/lock.py 2010-05-11 08:36:16 +0000
247+++ bzrlib/lock.py 2011-03-31 15:13:30 +0000
248@@ -45,22 +45,22 @@
249 osutils,
250 trace,
251 )
252-from bzrlib.hooks import HookPoint, Hooks
253+from bzrlib.hooks import Hooks
254
255
256 class LockHooks(Hooks):
257
258 def __init__(self):
259- Hooks.__init__(self)
260- self.create_hook(HookPoint('lock_acquired',
261- "Called with a bzrlib.lock.LockResult when a physical lock is "
262- "acquired.", (1, 8), None))
263- self.create_hook(HookPoint('lock_released',
264- "Called with a bzrlib.lock.LockResult when a physical lock is "
265- "released.", (1, 8), None))
266- self.create_hook(HookPoint('lock_broken',
267- "Called with a bzrlib.lock.LockResult when a physical lock is "
268- "broken.", (1, 15), None))
269+ Hooks.__init__(self, "bzrlib.lock", "Lock.hooks")
270+ self.add_hook('lock_acquired',
271+ "Called with a bzrlib.lock.LockResult when a physical lock is "
272+ "acquired.", (1, 8))
273+ self.add_hook('lock_released',
274+ "Called with a bzrlib.lock.LockResult when a physical lock is "
275+ "released.", (1, 8))
276+ self.add_hook('lock_broken',
277+ "Called with a bzrlib.lock.LockResult when a physical lock is "
278+ "broken.", (1, 15))
279
280
281 class Lock(object):
282
283=== modified file 'bzrlib/merge.py'
284--- bzrlib/merge.py 2011-02-07 04:14:29 +0000
285+++ bzrlib/merge.py 2011-03-31 15:13:30 +0000
286@@ -62,8 +62,8 @@
287 class MergeHooks(hooks.Hooks):
288
289 def __init__(self):
290- hooks.Hooks.__init__(self)
291- self.create_hook(hooks.HookPoint('merge_file_content',
292+ hooks.Hooks.__init__(self, "bzrlib.merge", "Merger.hooks")
293+ self.add_hook('merge_file_content',
294 "Called with a bzrlib.merge.Merger object to create a per file "
295 "merge object when starting a merge. "
296 "Should return either None or a subclass of "
297@@ -73,7 +73,7 @@
298 "side has deleted the file and the other has changed it). "
299 "See the AbstractPerFileMerger API docs for details on how it is "
300 "used by merge.",
301- (2, 1), None))
302+ (2, 1))
303
304
305 class AbstractPerFileMerger(object):
306
307=== modified file 'bzrlib/merge_directive.py'
308--- bzrlib/merge_directive.py 2011-02-19 21:00:05 +0000
309+++ bzrlib/merge_directive.py 2011-03-31 15:13:30 +0000
310@@ -59,12 +59,12 @@
311 """Hooks for MergeDirective classes."""
312
313 def __init__(self):
314- hooks.Hooks.__init__(self)
315- self.create_hook(hooks.HookPoint('merge_request_body',
316+ hooks.Hooks.__init__(self, "bzrlib.merge_directive", "BaseMergeDirective.hooks")
317+ self.add_hook('merge_request_body',
318 "Called with a MergeRequestBodyParams when a body is needed for"
319 " a merge request. Callbacks must return a body. If more"
320 " than one callback is registered, the output of one callback is"
321- " provided to the next.", (1, 15, 0), False))
322+ " provided to the next.", (1, 15, 0))
323
324
325 class BaseMergeDirective(object):
326
327=== modified file 'bzrlib/msgeditor.py'
328--- bzrlib/msgeditor.py 2011-02-07 01:30:38 +0000
329+++ bzrlib/msgeditor.py 2011-03-31 15:13:30 +0000
330@@ -31,7 +31,7 @@
331 ui,
332 )
333 from bzrlib.errors import BzrError, BadCommitMessageEncoding
334-from bzrlib.hooks import HookPoint, Hooks
335+from bzrlib.hooks import Hooks
336
337
338 def _get_editor():
339@@ -302,8 +302,8 @@
340
341 These are all empty initially.
342 """
343- Hooks.__init__(self)
344- self.create_hook(HookPoint('commit_message_template',
345+ Hooks.__init__(self, "bzrlib.msgeditor", "hooks")
346+ self.add_hook('commit_message_template',
347 "Called when a commit message is being generated. "
348 "commit_message_template is called with the bzrlib.commit.Commit "
349 "object and the message that is known so far. "
350@@ -311,7 +311,7 @@
351 "could be the same as it was given. When there are multiple "
352 "hooks registered for commit_message_template, they are chained "
353 "with the result from the first passed into the second, and so "
354- "on.", (1, 10), None))
355+ "on.", (1, 10))
356
357
358 hooks = MessageEditorHooks()
359
360=== modified file 'bzrlib/mutabletree.py'
361--- bzrlib/mutabletree.py 2011-03-06 18:10:47 +0000
362+++ bzrlib/mutabletree.py 2011-03-31 15:13:30 +0000
363@@ -652,17 +652,17 @@
364 """Create the default hooks.
365
366 """
367- hooks.Hooks.__init__(self)
368- self.create_hook(hooks.HookPoint('start_commit',
369+ hooks.Hooks.__init__(self, "bzrlib.mutabletree", "MutableTree.hooks")
370+ self.add_hook('start_commit',
371 "Called before a commit is performed on a tree. The start commit "
372 "hook is able to change the tree before the commit takes place. "
373 "start_commit is called with the bzrlib.mutabletree.MutableTree "
374- "that the commit is being performed on.", (1, 4), None))
375- self.create_hook(hooks.HookPoint('post_commit',
376+ "that the commit is being performed on.", (1, 4))
377+ self.add_hook('post_commit',
378 "Called after a commit is performed on a tree. The hook is "
379 "called with a bzrlib.mutabletree.PostCommitHookParams object. "
380 "The mutable tree the commit was performed on is available via "
381- "the mutable_tree attribute of that object.", (2, 0), None))
382+ "the mutable_tree attribute of that object.", (2, 0))
383
384
385 # install the default hooks into the MutableTree class.
386
387=== modified file 'bzrlib/plugins/changelog_merge/__init__.py'
388--- bzrlib/plugins/changelog_merge/__init__.py 2011-03-15 07:56:42 +0000
389+++ bzrlib/plugins/changelog_merge/__init__.py 2011-03-31 15:13:30 +0000
390@@ -55,27 +55,17 @@
391
392 # Since we are a built-in plugin we share the bzrlib version
393 from bzrlib import version_info
394+from bzrlib.hooks import install_lazy_named_hook
395
396 # Put most of the code in a separate module that we lazy-import to keep the
397 # overhead of this plugin as minimal as possible.
398-from bzrlib.lazy_import import lazy_import
399-lazy_import(globals(), """
400-from bzrlib.plugins.changelog_merge import changelog_merge as _mod_changelog_merge
401-""")
402-
403-from bzrlib.merge import Merger
404-
405-
406 def changelog_merge_hook(merger):
407 """Merger.merge_file_content hook for GNU-format ChangeLog files."""
408- return _mod_changelog_merge.ChangeLogMerger(merger)
409-
410-
411-def install_hook():
412- Merger.hooks.install_named_hook(
413- 'merge_file_content', changelog_merge_hook, 'GNU ChangeLog file merge')
414-install_hook()
415-
416+ from bzrlib.plugins.changelog_merge.changelog_merge import ChangeLogMerger
417+ return ChangeLogMerger(merger)
418+
419+install_lazy_named_hook("bzrlib.merge", "Merger.hooks", "merge_file_content",
420+ changelog_merge_hook, 'GNU ChangeLog file merge')
421
422 def load_tests(basic_tests, module, loader):
423 testmod_names = [
424@@ -84,4 +74,3 @@
425 basic_tests.addTest(loader.loadTestsFromModuleNames(
426 ["%s.%s" % (__name__, tmn) for tmn in testmod_names]))
427 return basic_tests
428-
429
430=== modified file 'bzrlib/plugins/launchpad/lp_propose.py'
431--- bzrlib/plugins/launchpad/lp_propose.py 2011-01-19 16:57:38 +0000
432+++ bzrlib/plugins/launchpad/lp_propose.py 2011-03-31 15:13:30 +0000
433@@ -36,19 +36,12 @@
434 """Hooks for proposing a merge on Launchpad."""
435
436 def __init__(self):
437- hooks.Hooks.__init__(self)
438- self.create_hook(
439- hooks.HookPoint(
440- 'get_prerequisite',
441- "Return the prerequisite branch for proposing as merge.",
442- (2, 1), None),
443- )
444- self.create_hook(
445- hooks.HookPoint(
446- 'merge_proposal_body',
447- "Return an initial body for the merge proposal message.",
448- (2, 1), None),
449- )
450+ hooks.Hooks.__init__(self, "bzrlib.plugins.launchpad.lp_propose",
451+ "Proposer.hooks")
452+ self.add_hook('get_prerequisite',
453+ "Return the prerequisite branch for proposing as merge.", (2, 1))
454+ self.add_hook('merge_proposal_body',
455+ "Return an initial body for the merge proposal message.", (2, 1))
456
457
458 class Proposer(object):
459
460=== modified file 'bzrlib/plugins/news_merge/__init__.py'
461--- bzrlib/plugins/news_merge/__init__.py 2010-05-03 04:08:50 +0000
462+++ bzrlib/plugins/news_merge/__init__.py 2011-03-31 15:13:30 +0000
463@@ -33,26 +33,17 @@
464
465 # Since we are a built-in plugin we share the bzrlib version
466 from bzrlib import version_info
467-
468-# Put most of the code in a separate module that we lazy-import to keep the
469-# overhead of this plugin as minimal as possible.
470-from bzrlib.lazy_import import lazy_import
471-lazy_import(globals(), """
472-from bzrlib.plugins.news_merge import news_merge as _mod_news_merge
473-""")
474-
475-from bzrlib.merge import Merger
476+from bzrlib.hooks import install_lazy_named_hook
477
478
479 def news_merge_hook(merger):
480 """Merger.merge_file_content hook for bzr-format NEWS files."""
481- return _mod_news_merge.NewsMerger(merger)
482-
483-
484-def install_hook():
485- Merger.hooks.install_named_hook(
486- 'merge_file_content', news_merge_hook, 'NEWS file merge')
487-install_hook()
488+ from bzrlib.plugins.news_merge.news_merge import NewsMerger
489+ return NewsMerger(merger)
490+
491+
492+install_lazy_named_hook("bzrlib.merge", "Merger.hooks", "merge_file_content",
493+ news_merge_hook, "NEWS file merge")
494
495
496 def load_tests(basic_tests, module, loader):
497
498=== modified file 'bzrlib/smart/client.py'
499--- bzrlib/smart/client.py 2010-02-17 17:11:16 +0000
500+++ bzrlib/smart/client.py 2011-03-31 15:13:30 +0000
501@@ -194,12 +194,12 @@
502 class SmartClientHooks(hooks.Hooks):
503
504 def __init__(self):
505- hooks.Hooks.__init__(self)
506- self.create_hook(hooks.HookPoint('call',
507+ hooks.Hooks.__init__(self, "bzrlib.smart.client", "_SmartClient.hooks")
508+ self.add_hook('call',
509 "Called when the smart client is submitting a request to the "
510 "smart server. Called with a bzrlib.smart.client.CallHookParams "
511 "object. Streaming request bodies, and responses, are not "
512- "accessible.", None, None))
513+ "accessible.", None)
514
515
516 _SmartClient.hooks = SmartClientHooks()
517
518=== modified file 'bzrlib/smart/server.py'
519--- bzrlib/smart/server.py 2011-03-05 02:26:26 +0000
520+++ bzrlib/smart/server.py 2011-03-31 15:13:30 +0000
521@@ -22,7 +22,7 @@
522 import sys
523 import threading
524
525-from bzrlib.hooks import HookPoint, Hooks
526+from bzrlib.hooks import Hooks
527 from bzrlib import (
528 errors,
529 trace,
530@@ -239,21 +239,21 @@
531 These are all empty initially, because by default nothing should get
532 notified.
533 """
534- Hooks.__init__(self)
535- self.create_hook(HookPoint('server_started',
536+ Hooks.__init__(self, "bzrlib.smart.server", "SmartTCPServer.hooks")
537+ self.add_hook('server_started',
538 "Called by the bzr server when it starts serving a directory. "
539 "server_started is called with (backing urls, public url), "
540 "where backing_url is a list of URLs giving the "
541 "server-specific directory locations, and public_url is the "
542- "public URL for the directory being served.", (0, 16), None))
543- self.create_hook(HookPoint('server_started_ex',
544+ "public URL for the directory being served.", (0, 16))
545+ self.add_hook('server_started_ex',
546 "Called by the bzr server when it starts serving a directory. "
547 "server_started is called with (backing_urls, server_obj).",
548- (1, 17), None))
549- self.create_hook(HookPoint('server_stopped',
550+ (1, 17))
551+ self.add_hook('server_stopped',
552 "Called by the bzr server when it stops serving a directory. "
553 "server_stopped is called with the same parameters as the "
554- "server_started hook: (backing_urls, public_url).", (0, 16), None))
555+ "server_started hook: (backing_urls, public_url).", (0, 16))
556
557 SmartTCPServer.hooks = SmartServerHooks()
558
559
560=== modified file 'bzrlib/status.py'
561--- bzrlib/status.py 2011-01-31 22:09:46 +0000
562+++ bzrlib/status.py 2011-03-31 15:13:30 +0000
563@@ -379,23 +379,23 @@
564 These are all empty initially, because by default nothing should get
565 notified.
566 """
567- _mod_hooks.Hooks.__init__(self)
568- self.create_hook(_mod_hooks.HookPoint('post_status',
569+ _mod_hooks.Hooks.__init__(self, "bzrlib.status", "hooks")
570+ self.add_hook('post_status',
571 "Called with argument StatusHookParams after Bazaar has "
572 "displayed the status. StatusHookParams has the attributes "
573 "(old_tree, new_tree, to_file, versioned, show_ids, short, "
574 "verbose). The last four arguments correspond to the command "
575 "line options specified by the user for the status command. "
576 "to_file is the output stream for writing.",
577- (2, 3), None))
578- self.create_hook(_mod_hooks.HookPoint('pre_status',
579+ (2, 3))
580+ self.add_hook('pre_status',
581 "Called with argument StatusHookParams before Bazaar "
582 "displays the status. StatusHookParams has the attributes "
583 "(old_tree, new_tree, to_file, versioned, show_ids, short, "
584 "verbose). The last four arguments correspond to the command "
585 "line options specified by the user for the status command. "
586 "to_file is the output stream for writing.",
587- (2, 3), None))
588+ (2, 3))
589
590
591 class StatusHookParams(object):
592
593=== modified file 'bzrlib/tests/test_hooks.py'
594--- bzrlib/tests/test_hooks.py 2011-03-30 12:24:06 +0000
595+++ bzrlib/tests/test_hooks.py 2011-03-31 15:13:30 +0000
596@@ -39,39 +39,38 @@
597 class TestHooks(tests.TestCase):
598
599 def test_create_hook_first(self):
600- hooks = Hooks()
601+ hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
602 doc = ("Invoked after changing the tip of a branch object. Called with"
603 "a bzrlib.branch.PostChangeBranchTipParams object")
604 hook = HookPoint("post_tip_change", doc, (0, 15), None)
605- hooks.create_hook(hook)
606+ self.applyDeprecated(deprecated_in((2, 4)), hooks.create_hook, hook)
607 self.assertEqual(hook, hooks['post_tip_change'])
608
609 def test_create_hook_name_collision_errors(self):
610- hooks = Hooks()
611+ hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
612 doc = ("Invoked after changing the tip of a branch object. Called with"
613 "a bzrlib.branch.PostChangeBranchTipParams object")
614 hook = HookPoint("post_tip_change", doc, (0, 15), None)
615 hook2 = HookPoint("post_tip_change", None, None, None)
616- hooks.create_hook(hook)
617- self.assertRaises(errors.DuplicateKey, hooks.create_hook, hook2)
618+ self.applyDeprecated(deprecated_in((2, 4)), hooks.create_hook, hook)
619+ self.assertRaises(errors.DuplicateKey, self.applyDeprecated,
620+ deprecated_in((2, 4, 0)), hooks.create_hook, hook2)
621 self.assertEqual(hook, hooks['post_tip_change'])
622
623 def test_docs(self):
624 """docs() should return something reasonable about the Hooks."""
625 class MyHooks(Hooks):
626 pass
627- hooks = MyHooks()
628+ hooks = MyHooks("bzrlib.tests.test_hooks", "some_hooks")
629 hooks['legacy'] = []
630- hook1 = HookPoint('post_tip_change',
631+ hooks.add_hook('post_tip_change',
632 "Invoked after the tip of a branch changes. Called with "
633- "a ChangeBranchTipParams object.", (1, 4), None)
634- hook2 = HookPoint('pre_tip_change',
635+ "a ChangeBranchTipParams object.", (1, 4))
636+ hooks.add_hook('pre_tip_change',
637 "Invoked before the tip of a branch changes. Called with "
638 "a ChangeBranchTipParams object. Hooks should raise "
639 "TipChangeRejected to signal that a tip change is not permitted.",
640 (1, 6), None)
641- hooks.create_hook(hook1)
642- hooks.create_hook(hook2)
643 self.assertEqualDiff(
644 "MyHooks\n"
645 "-------\n"
646@@ -99,18 +98,18 @@
647 "signal that a tip change is not permitted.\n", hooks.docs())
648
649 def test_install_named_hook_raises_unknown_hook(self):
650- hooks = Hooks()
651+ hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
652 self.assertRaises(errors.UnknownHook, hooks.install_named_hook, 'silly',
653 None, "")
654
655 def test_install_named_hook_appends_known_hook(self):
656- hooks = Hooks()
657+ hooks = Hooks("bzrlib.tests.test_hooks", "some_hooks")
658 hooks['set_rh'] = []
659 hooks.install_named_hook('set_rh', None, "demo")
660 self.assertEqual(hooks['set_rh'], [None])
661
662 def test_install_named_hook_and_retrieve_name(self):
663- hooks = Hooks()
664+ hooks = Hooks("bzrlib.tests.test_hooks", "somehooks")
665 hooks['set_rh'] = []
666 hooks.install_named_hook('set_rh', None, "demo")
667 self.assertEqual("demo", hooks.get_hook_name(None))
668@@ -134,7 +133,7 @@
669 set_rh = lambda: None
670
671 def test_install_named_hook_lazy(self):
672- hooks = Hooks()
673+ hooks = Hooks("bzrlib.tests.hooks", "some_hooks")
674 hooks['set_rh'] = HookPoint("set_rh", "doc", (0, 15), None)
675 hooks.install_named_hook_lazy('set_rh', 'bzrlib.tests.test_hooks',
676 'TestHooks.set_rh', "demo")
677@@ -143,7 +142,7 @@
678 def test_install_named_hook_lazy_old(self):
679 # An exception is raised if a lazy hook is raised for
680 # an old style hook point.
681- hooks = Hooks()
682+ hooks = Hooks("bzrlib.tests.hooks", "some_hooks")
683 hooks['set_rh'] = []
684 self.assertRaises(errors.UnsupportedOperation,
685 hooks.install_named_hook_lazy,
686
687=== modified file 'bzrlib/tests/test_selftest.py'
688--- bzrlib/tests/test_selftest.py 2011-03-29 04:30:03 +0000
689+++ bzrlib/tests/test_selftest.py 2011-03-31 15:13:30 +0000
690@@ -1437,12 +1437,12 @@
691 # Note this test won't fail with hooks that the core library doesn't
692 # use - but it trigger with a plugin that adds hooks, so its still a
693 # useful warning in that case.
694- self.assertEqual(bzrlib.branch.BranchHooks(),
695- bzrlib.branch.Branch.hooks)
696- self.assertEqual(bzrlib.smart.server.SmartServerHooks(),
697+ self.assertEqual(bzrlib.branch.BranchHooks(), bzrlib.branch.Branch.hooks)
698+ self.assertEqual(
699+ bzrlib.smart.server.SmartServerHooks(),
700 bzrlib.smart.server.SmartTCPServer.hooks)
701- self.assertEqual(bzrlib.commands.CommandHooks(),
702- bzrlib.commands.Command.hooks)
703+ self.assertEqual(
704+ bzrlib.commands.CommandHooks(), bzrlib.commands.Command.hooks)
705
706 def test__gather_lsprof_in_benchmarks(self):
707 """When _gather_lsprof_in_benchmarks is on, accumulate profile data.
708
709=== modified file 'bzrlib/tests/transport_util.py'
710--- bzrlib/tests/transport_util.py 2011-01-26 19:34:58 +0000
711+++ bzrlib/tests/transport_util.py 2011-03-31 15:13:30 +0000
712@@ -47,7 +47,8 @@
713 """Dict-mapping hook name to a list of callables for transport hooks"""
714
715 def __init__(self):
716- super(TransportHooks, self).__init__()
717+ super(TransportHooks, self).__init__("bzrlib.tests.transport_util",
718+ "InstrumentedTransport.hooks")
719 # Invoked when the transport has just created a new connection.
720 # The api signature is (transport, connection, credentials)
721 self['_set_connection'] = []
722
723=== modified file 'bzrlib/version_info_formats/format_rio.py'
724--- bzrlib/version_info_formats/format_rio.py 2011-02-18 19:01:43 +0000
725+++ bzrlib/version_info_formats/format_rio.py 2011-03-31 15:13:30 +0000
726@@ -89,7 +89,7 @@
727 self.add_hook('revision',
728 "Invoked when adding information about a revision to the"
729 " RIO stanza that is printed. revision is called with a"
730- " revision object and a RIO stanza.", (1, 15), None)
731+ " revision object and a RIO stanza.", (1, 15))
732
733
734 RioVersionInfoBuilder.hooks = RioVersionInfoBuilderHooks()
735
736=== modified file 'doc/en/release-notes/bzr-2.4.txt'
737--- doc/en/release-notes/bzr-2.4.txt 2011-03-30 10:54:24 +0000
738+++ doc/en/release-notes/bzr-2.4.txt 2011-03-31 15:13:30 +0000
739@@ -56,6 +56,9 @@
740 .. Changes that may require updates in plugins or other code that uses
741 bzrlib.
742
743+* ``Hooks.create_hook`` is now deprecated in favour of ``Hooks.add_hook``.
744+ (Jelmer Vernooij)
745+
746 Internals
747 *********
748