Merge lp:~jelmer/bzr/lazy-registries into lp:bzr

Proposed by Jelmer Vernooij
Status: Rejected
Rejected by: Jelmer Vernooij
Proposed branch: lp:~jelmer/bzr/lazy-registries
Merge into: lp:bzr
Diff against target: 1012 lines (+232/-101)
40 files modified
bzrlib/branch.py (+8/-4)
bzrlib/bugtracker.py (+1/-1)
bzrlib/bzrdir.py (+2/-1)
bzrlib/chk_map.py (+2/-1)
bzrlib/commands.py (+4/-3)
bzrlib/config.py (+7/-4)
bzrlib/conflicts.py (+2/-2)
bzrlib/controldir.py (+10/-6)
bzrlib/diff.py (+1/-1)
bzrlib/directory_service.py (+4/-2)
bzrlib/filters/__init__.py (+3/-1)
bzrlib/foreign.py (+2/-1)
bzrlib/help_topics/__init__.py (+1/-1)
bzrlib/hooks.py (+1/-1)
bzrlib/log.py (+5/-3)
bzrlib/mail_client.py (+2/-1)
bzrlib/merge.py (+1/-1)
bzrlib/merge_directive.py (+2/-1)
bzrlib/option.py (+2/-2)
bzrlib/plugins/launchpad/__init__.py (+11/-12)
bzrlib/plugins/netrc_credential_store/__init__.py (+2/-1)
bzrlib/plugins/po_merge/__init__.py (+2/-2)
bzrlib/plugins/weave_fmt/__init__.py (+3/-3)
bzrlib/registry.py (+80/-24)
bzrlib/remote.py (+3/-2)
bzrlib/repository.py (+4/-2)
bzrlib/revisionspec.py (+1/-1)
bzrlib/send.py (+1/-1)
bzrlib/serializer.py (+1/-1)
bzrlib/smart/request.py (+1/-1)
bzrlib/tag.py (+1/-1)
bzrlib/tests/__init__.py (+3/-2)
bzrlib/tests/test_foreign.py (+1/-1)
bzrlib/tests/test_registry.py (+40/-1)
bzrlib/transform.py (+1/-1)
bzrlib/transport/__init__.py (+4/-2)
bzrlib/version_info_formats/__init__.py (+2/-2)
bzrlib/versionedfile.py (+1/-1)
bzrlib/workingtree.py (+6/-3)
doc/en/release-notes/bzr-2.6.txt (+4/-0)
To merge this branch: bzr merge lp:~jelmer/bzr/lazy-registries
Reviewer Review Type Date Requested Status
Vincent Ladeuil Approve
Review via email: mp+99913@code.launchpad.net

This proposal supersedes a proposal from 2012-03-16.

Commit message

Allow lazy registration in registries without loading the registry itself.

Description of the change

Allow lazy registration of entries in registries.

This allows plugins to significantly reduce the amount of code they have to import.

For example, in bzr-git, bzr-svn and bzr-hg this means we can drop imports of:

* bzrlib.directory_service
* bzrlib.send
* bzrlib.diff
* bzrlib.foreign
* bzrlib.help_topics

In e.g. bzr-search we can drop bzrlib.smart.request and bzrlib.log

In bzr-xmloutput, bzrlib.log

Etc.

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

Nice one.

I think I'm not comfortable with two specifics points:

- you've added a feature to Registry, I think it would be clearer to create
  a new class instead,

- the way it works is magical for people that don't know how lazy loading
  works, a few comments or docstrings should address that.

565 +RegistryEntry = collections.namedtuple('RegistryEntry', 'objgetter info help')

Good addition but Worth a docstring.

583 + if module is not None and member_name is not None:

This is the line that conflates two classes into a single one for a benefit
that is not clear to me.

688 +# Lazily registered registries. Maps (module, registry_name, name,
689 +# entry_module, entry_name) -> (objgetter, info, help)
690 +_lazy_registries = {}

This is where you should explain part of the magic.

712 + obj_getter = _LazyObjectGetter(entry_module, entry_name)
713 + registry_dict[key] = RegistryEntry(obj_getter, info, help)

And this is the othe place where the magic takes place (truth is there is
yet another place where the magic occurs but it won't appear that magical if
you use a different class). Someone not knowing about lazy loading and
obj_getter is likely to be completely lost ;)

review: Needs Fixing
Revision history for this message
Jelmer Vernooij (jelmer) wrote : Posted in a previous version of this proposal

Am 29/03/12 10:27, schrieb Vincent Ladeuil:
> Review: Needs Fixing
>
> Nice one.
>
> I think I'm not comfortable with two specifics points:
>
> - you've added a feature to Registry, I think it would be clearer to create
> a new class instead,
If we add a new class, then that means that any users of registries
would either have to stick with the old implementation *or* be converted
to the new one. Adding it to the current class just allows us to update
the sites and then plugins can use either the lazy registration or
non-lazy registration as they see fit. We wouldn't have to immediately
update all plugins, their existing calls would still just work.
>
> - the way it works is magical for people that don't know how lazy loading
> works, a few comments or docstrings should address that.
>
> 565 +RegistryEntry = collections.namedtuple('RegistryEntry', 'objgetter info help')
>
> Good addition but Worth a docstring.
Fixed.
>
> 583 + if module is not None and member_name is not None:
>
> This is the line that conflates two classes into a single one for a benefit
> that is not clear to me.
If module is not set, then the Registry() object only allows for direct
registration (i.e. importing the object itself and calling
install_named_hook or install_lazy_named_hook on it). If
module/member_name is set, then it also supports install_lazy_hook() *in
addition* to the other methods.

I've added a bit of documentation to the Registry docstring.

>
> 688 +# Lazily registered registries. Maps (module, registry_name, name,
> 689 +# entry_module, entry_name) -> (objgetter, info, help)
> 690 +_lazy_registries = {}
>
> This is where you should explain part of the magic.
>
> 712 + obj_getter = _LazyObjectGetter(entry_module, entry_name)
> 713 + registry_dict[key] = RegistryEntry(obj_getter, info, help)
>
> And this is the othe place where the magic takes place (truth is there is
> yet another place where the magic occurs but it won't appear that magical if
> you use a different class). Someone not knowing about lazy loading and
> obj_getter is likely to be completely lost ;)
I've updated the comments.

Cheers,

Jelmer

Revision history for this message
Vincent Ladeuil (vila) wrote :

> If we add a new class, then that means that any users of registries would
> either have to stick with the old implementation *or* be converted to the
> new one.

Hmm. That's true.

On the other hand it means we will never have a clean cut nor a clean
implementation because plugins have no incentive to use the new one, no
deprecation warning here, no nothing.

Not worth blocking this one but I'm always a bit worried when we add more
cruft without a clear path to get rid of it :-/

review: Approve
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

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

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

sent to pqm by email

Revision history for this message
John A Meinel (jameinel) wrote :

sent to pqm by email

Revision history for this message
John A Meinel (jameinel) wrote :

sent to pqm by email

Revision history for this message
Martin Packman (gz) wrote :

What is the failure PQM was giving on this branch?

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bzrlib/branch.py'
--- bzrlib/branch.py 2012-03-29 12:27:52 +0000
+++ bzrlib/branch.py 2012-03-31 14:09:30 +0000
@@ -2325,8 +2325,10 @@
2325class BranchFormatRegistry(controldir.ControlComponentFormatRegistry):2325class BranchFormatRegistry(controldir.ControlComponentFormatRegistry):
2326 """Branch format registry."""2326 """Branch format registry."""
23272327
2328 def __init__(self, other_registry=None):2328 def __init__(self, module_name=None, member_name=None,
2329 super(BranchFormatRegistry, self).__init__(other_registry)2329 other_registry=None):
2330 super(BranchFormatRegistry, self).__init__(module_name, member_name,
2331 other_registry)
2330 self._default_format = None2332 self._default_format = None
23312333
2332 def set_default(self, format):2334 def set_default(self, format):
@@ -2336,7 +2338,8 @@
2336 return self._default_format2338 return self._default_format
23372339
23382340
2339network_format_registry = registry.FormatRegistry()2341network_format_registry = registry.FormatRegistry("bzrlib.branch",
2342 "network_format_registry")
2340"""Registry of formats indexed by their network name.2343"""Registry of formats indexed by their network name.
23412344
2342The network name for a branch format is an identifier that can be used when2345The network name for a branch format is an identifier that can be used when
@@ -2344,7 +2347,8 @@
2344BranchFormat.network_name() for more detail.2347BranchFormat.network_name() for more detail.
2345"""2348"""
23462349
2347format_registry = BranchFormatRegistry(network_format_registry)2350format_registry = BranchFormatRegistry("bzrlib.branch", "format_registry",
2351 network_format_registry)
23482352
23492353
2350# formats which have no format string are not discoverable2354# formats which have no format string are not discoverable
23512355
=== modified file 'bzrlib/bugtracker.py'
--- bzrlib/bugtracker.py 2011-12-18 12:46:49 +0000
+++ bzrlib/bugtracker.py 2012-03-31 14:09:30 +0000
@@ -174,7 +174,7 @@
174 return _bugs_help174 return _bugs_help
175175
176176
177tracker_registry = TrackerRegistry()177tracker_registry = TrackerRegistry("bzrlib.bugtracker", "tracker_registry")
178"""Registry of bug trackers."""178"""Registry of bug trackers."""
179179
180180
181181
=== modified file 'bzrlib/bzrdir.py'
--- bzrlib/bzrdir.py 2012-03-29 12:27:52 +0000
+++ bzrlib/bzrdir.py 2012-03-31 14:09:30 +0000
@@ -1226,7 +1226,8 @@
1226class BzrProber(controldir.Prober):1226class BzrProber(controldir.Prober):
1227 """Prober for formats that use a .bzr/ control directory."""1227 """Prober for formats that use a .bzr/ control directory."""
12281228
1229 formats = registry.FormatRegistry(controldir.network_format_registry)1229 formats = registry.FormatRegistry("bzrlib.bzrdir", "BzrProber.formats",
1230 controldir.network_format_registry)
1230 """The known .bzr formats."""1231 """The known .bzr formats."""
12311232
1232 @classmethod1233 @classmethod
12331234
=== modified file 'bzrlib/chk_map.py'
--- bzrlib/chk_map.py 2011-12-19 13:23:58 +0000
+++ bzrlib/chk_map.py 2012-03-31 14:09:30 +0000
@@ -99,7 +99,8 @@
99 return '\x00'.join(key)99 return '\x00'.join(key)
100100
101101
102search_key_registry = registry.Registry()102search_key_registry = registry.Registry("bzrlib.chk_map",
103 "search_key_registry")
103search_key_registry.register('plain', _search_key_plain)104search_key_registry.register('plain', _search_key_plain)
104105
105106
106107
=== modified file 'bzrlib/commands.py'
--- bzrlib/commands.py 2012-03-13 17:25:29 +0000
+++ bzrlib/commands.py 2012-03-31 14:09:30 +0000
@@ -75,8 +75,8 @@
75 about the builtin they're decorating.75 about the builtin they're decorating.
76 """76 """
7777
78 def __init__(self):78 def __init__(self, module_name=None, member_name=None):
79 registry.Registry.__init__(self)79 registry.Registry.__init__(self, module_name, member_name)
80 self.overridden_registry = None80 self.overridden_registry = None
81 # map from aliases to the real command that implements the name81 # map from aliases to the real command that implements the name
82 self._alias_dict = {}82 self._alias_dict = {}
@@ -1300,4 +1300,5 @@
1300 for key, provider in self.iteritems():1300 for key, provider in self.iteritems():
1301 yield provider1301 yield provider
13021302
1303command_providers_registry = ProvidersRegistry()1303command_providers_registry = ProvidersRegistry("bzrlib.commands",
1304 "command_providers_registry")
13041305
=== modified file 'bzrlib/config.py'
--- bzrlib/config.py 2012-03-29 12:27:52 +0000
+++ bzrlib/config.py 2012-03-31 14:09:30 +0000
@@ -2098,7 +2098,8 @@
2098 info=fallback, override_existing=override_existing)2098 info=fallback, override_existing=override_existing)
20992099
21002100
2101credential_store_registry = CredentialStoreRegistry()2101credential_store_registry = CredentialStoreRegistry("bzrlib.config",
2102 "credential_store_registry")
21022103
21032104
2104class CredentialStore(object):2105class CredentialStore(object):
@@ -2574,7 +2575,7 @@
2574 return the_help2575 return the_help
25752576
25762577
2577option_registry = OptionRegistry()2578option_registry = OptionRegistry("bzrlib.config", "option_registry")
25782579
25792580
2580# Registered options in lexicographical order2581# Registered options in lexicographical order
@@ -4176,9 +4177,11 @@
4176# The registered object should be a callable receiving a test instance4177# The registered object should be a callable receiving a test instance
4177# parameter (inheriting from tests.TestCaseWithTransport) and returning a Store4178# parameter (inheriting from tests.TestCaseWithTransport) and returning a Store
4178# object.4179# object.
4179test_store_builder_registry = registry.Registry()4180test_store_builder_registry = registry.Registry("bzrlib.config",
4181 "test_store_builder_registry")
41804182
4181# The registered object should be a callable receiving a test instance4183# The registered object should be a callable receiving a test instance
4182# parameter (inheriting from tests.TestCaseWithTransport) and returning a Stack4184# parameter (inheriting from tests.TestCaseWithTransport) and returning a Stack
4183# object.4185# object.
4184test_stack_builder_registry = registry.Registry()4186test_stack_builder_registry = registry.Registry("bzrlib.config",
4187 "test_stack_builder_registry")
41854188
=== modified file 'bzrlib/conflicts.py'
--- bzrlib/conflicts.py 2012-01-16 14:45:48 +0000
+++ bzrlib/conflicts.py 2012-03-31 14:09:30 +0000
@@ -78,8 +78,8 @@
78 self.outf.write(unicode(conflict) + '\n')78 self.outf.write(unicode(conflict) + '\n')
7979
8080
81resolve_action_registry = registry.Registry()81resolve_action_registry = registry.Registry("bzrlib.conflicts",
8282 "resolve_action_registry")
8383
84resolve_action_registry.register(84resolve_action_registry.register(
85 'done', 'done', 'Marks the conflict as resolved.')85 'done', 'done', 'Marks the conflict as resolved.')
8686
=== modified file 'bzrlib/controldir.py'
--- bzrlib/controldir.py 2012-02-14 17:22:37 +0000
+++ bzrlib/controldir.py 2012-03-31 14:09:30 +0000
@@ -904,8 +904,10 @@
904class ControlComponentFormatRegistry(registry.FormatRegistry):904class ControlComponentFormatRegistry(registry.FormatRegistry):
905 """A registry for control components (branch, workingtree, repository)."""905 """A registry for control components (branch, workingtree, repository)."""
906906
907 def __init__(self, other_registry=None):907 def __init__(self, module_name=None, member_name=None,
908 super(ControlComponentFormatRegistry, self).__init__(other_registry)908 other_registry=None):
909 super(ControlComponentFormatRegistry, self).__init__(module_name,
910 member_name, other_registry)
909 self._extra_formats = []911 self._extra_formats = []
910912
911 def register(self, format):913 def register(self, format):
@@ -1290,11 +1292,11 @@
1290 e.g. BzrDirMeta1 with weave repository. Also, it's more user-oriented.1292 e.g. BzrDirMeta1 with weave repository. Also, it's more user-oriented.
1291 """1293 """
12921294
1293 def __init__(self):1295 def __init__(self, module_name=None, member_name=None):
1294 """Create a ControlDirFormatRegistry."""1296 """Create a ControlDirFormatRegistry."""
1295 self._aliases = set()1297 self._aliases = set()
1296 self._registration_order = list()1298 self._registration_order = list()
1297 super(ControlDirFormatRegistry, self).__init__()1299 super(ControlDirFormatRegistry, self).__init__(module_name, member_name)
12981300
1299 def aliases(self):1301 def aliases(self):
1300 """Return a set of the format names which are aliases."""1302 """Return a set of the format names which are aliases."""
@@ -1449,9 +1451,11 @@
1449# Please register new formats after old formats so that formats1451# Please register new formats after old formats so that formats
1450# appear in chronological order and format descriptions can build1452# appear in chronological order and format descriptions can build
1451# on previous ones.1453# on previous ones.
1452format_registry = ControlDirFormatRegistry()1454format_registry = ControlDirFormatRegistry("bzrlib.controldir",
1455 "format_registry")
14531456
1454network_format_registry = registry.FormatRegistry()1457network_format_registry = registry.FormatRegistry("bzrlib.controldir",
1458 "network_format_registry")
1455"""Registry of formats indexed by their network name.1459"""Registry of formats indexed by their network name.
14561460
1457The network name for a ControlDirFormat is an identifier that can be used when1461The network name for a ControlDirFormat is an identifier that can be used when
14581462
=== modified file 'bzrlib/diff.py'
--- bzrlib/diff.py 2011-12-18 12:46:49 +0000
+++ bzrlib/diff.py 2012-03-31 14:09:30 +0000
@@ -1039,5 +1039,5 @@
1039 raise errors.NoDiffFound(error_path)1039 raise errors.NoDiffFound(error_path)
10401040
10411041
1042format_registry = Registry()1042format_registry = Registry("bzrlib.diff", "format_registry")
1043format_registry.register('default', DiffTree)1043format_registry.register('default', DiffTree)
10441044
=== modified file 'bzrlib/directory_service.py'
--- bzrlib/directory_service.py 2012-03-21 13:22:09 +0000
+++ bzrlib/directory_service.py 2012-03-31 14:09:30 +0000
@@ -65,7 +65,8 @@
65 service, name = match65 service, name = match
66 return service().look_up(name, url)66 return service().look_up(name, url)
6767
68directories = DirectoryServiceRegistry()68directories = DirectoryServiceRegistry("bzrlib.directory_service",
69 "directories")
6970
70class AliasDirectory(object):71class AliasDirectory(object):
71 """Directory lookup for locations associated with a branch.72 """Directory lookup for locations associated with a branch.
@@ -74,7 +75,8 @@
74 supported. On error, a subclass of DirectoryLookupFailure will be raised.75 supported. On error, a subclass of DirectoryLookupFailure will be raised.
75 """76 """
7677
77 branch_aliases = registry.Registry()78 branch_aliases = registry.Registry("bzrlib.directory_service",
79 "AliasDirectory.branch_aliases")
78 branch_aliases.register('parent', lambda b: b.get_parent(),80 branch_aliases.register('parent', lambda b: b.get_parent(),
79 help="The parent of this branch.")81 help="The parent of this branch.")
80 branch_aliases.register('submit', lambda b: b.get_submit_branch(),82 branch_aliases.register('submit', lambda b: b.get_submit_branch(),
8183
=== modified file 'bzrlib/filters/__init__.py'
--- bzrlib/filters/__init__.py 2012-03-29 14:54:16 +0000
+++ bzrlib/filters/__init__.py 2012-03-31 14:09:30 +0000
@@ -191,7 +191,9 @@
191191
192192
193# The registry of filter stacks indexed by name.193# The registry of filter stacks indexed by name.
194filter_stacks_registry = registry.Registry()194# See register_filter_stack_map for details on the registered values.
195filter_stacks_registry = registry.Registry(
196 "bzrlib.filters", "filter_stacks_registry")
195197
196198
197# Cache of preferences -> stack199# Cache of preferences -> stack
198200
=== modified file 'bzrlib/foreign.py'
--- bzrlib/foreign.py 2012-01-18 14:09:19 +0000
+++ bzrlib/foreign.py 2012-03-31 14:09:30 +0000
@@ -188,7 +188,8 @@
188 return foreign_vcs.mapping_registry.revision_id_bzr_to_foreign(revid)188 return foreign_vcs.mapping_registry.revision_id_bzr_to_foreign(revid)
189189
190190
191foreign_vcs_registry = ForeignVcsRegistry()191foreign_vcs_registry = ForeignVcsRegistry("bzrlib.foreign",
192 "foreign_vcs_registry")
192193
193194
194class ForeignRepository(Repository):195class ForeignRepository(Repository):
195196
=== modified file 'bzrlib/help_topics/__init__.py'
--- bzrlib/help_topics/__init__.py 2012-03-15 15:36:12 +0000
+++ bzrlib/help_topics/__init__.py 2012-03-31 14:09:30 +0000
@@ -118,7 +118,7 @@
118 return result118 return result
119119
120120
121topic_registry = HelpTopicRegistry()121topic_registry = HelpTopicRegistry("bzrlib.help_topics", "topic_registry")
122122
123123
124#----------------------------------------------------124#----------------------------------------------------
125125
=== modified file 'bzrlib/hooks.py'
--- bzrlib/hooks.py 2012-03-14 08:34:10 +0000
+++ bzrlib/hooks.py 2012-03-31 14:09:30 +0000
@@ -90,7 +90,7 @@
90 'MergeDirectiveHooks'),90 'MergeDirectiveHooks'),
91 )91 )
9292
93known_hooks = KnownHooksRegistry()93known_hooks = KnownHooksRegistry("bzrlib.hooks", "known_hooks")
94for (_hook_module, _hook_attribute, _hook_class) in _builtin_known_hooks:94for (_hook_module, _hook_attribute, _hook_class) in _builtin_known_hooks:
95 known_hooks.register_lazy_hook(_hook_module, _hook_attribute, _hook_class)95 known_hooks.register_lazy_hook(_hook_module, _hook_attribute, _hook_class)
96del _builtin_known_hooks, _hook_module, _hook_attribute, _hook_class96del _builtin_known_hooks, _hook_module, _hook_attribute, _hook_class
9797
=== modified file 'bzrlib/log.py'
--- bzrlib/log.py 2012-03-14 11:30:42 +0000
+++ bzrlib/log.py 2012-03-31 14:09:30 +0000
@@ -1789,7 +1789,8 @@
1789 return self.get(c.get('log_format'))1789 return self.get(c.get('log_format'))
17901790
17911791
1792log_formatter_registry = LogFormatterRegistry()1792log_formatter_registry = LogFormatterRegistry("bzrlib.log",
1793 "log_formatter_registry")
17931794
17941795
1795log_formatter_registry.register('short', ShortLogFormatter,1796log_formatter_registry.register('short', ShortLogFormatter,
@@ -1834,7 +1835,7 @@
1834 return [rev.committer]1835 return [rev.committer]
18351836
18361837
1837author_list_registry = registry.Registry()1838author_list_registry = registry.Registry("bzrlib.log", "author_list_registry")
18381839
1839author_list_registry.register('all', author_list_all,1840author_list_registry.register('all', author_list_all,
1840 'All authors')1841 'All authors')
@@ -2100,7 +2101,8 @@
2100 return None2101 return None
21012102
21022103
2103properties_handler_registry = registry.Registry()2104properties_handler_registry = registry.Registry("bzrlib.log",
2105 "properties_handler_registry")
21042106
2105# Use the properties handlers to print out bug information if available2107# Use the properties handlers to print out bug information if available
2106def _bugs_properties_handler(revision):2108def _bugs_properties_handler(revision):
21072109
=== modified file 'bzrlib/mail_client.py'
--- bzrlib/mail_client.py 2012-02-01 19:55:27 +0000
+++ bzrlib/mail_client.py 2012-03-31 14:09:30 +0000
@@ -33,7 +33,8 @@
33 registry33 registry
34 )34 )
3535
36mail_client_registry = registry.Registry()36mail_client_registry = registry.Registry("bzrlib.mail_client",
37 "mail_client_registry")
3738
3839
39class MailClient(object):40class MailClient(object):
4041
=== modified file 'bzrlib/merge.py'
--- bzrlib/merge.py 2012-03-14 09:30:48 +0000
+++ bzrlib/merge.py 2012-03-31 14:09:30 +0000
@@ -1956,7 +1956,7 @@
1956 return merger.do_merge()1956 return merger.do_merge()
19571957
19581958
1959merge_type_registry = registry.Registry()1959merge_type_registry = registry.Registry("bzrlib.merge", "merge_type_registry")
1960merge_type_registry.register('diff3', Diff3Merger,1960merge_type_registry.register('diff3', Diff3Merger,
1961 "Merge using external diff3.")1961 "Merge using external diff3.")
1962merge_type_registry.register('lca', LCAMerger,1962merge_type_registry.register('lca', LCAMerger,
19631963
=== modified file 'bzrlib/merge_directive.py'
--- bzrlib/merge_directive.py 2012-02-07 00:49:58 +0000
+++ bzrlib/merge_directive.py 2012-03-31 14:09:30 +0000
@@ -674,7 +674,8 @@
674 registry.Registry.register(self, format_string, directive)674 registry.Registry.register(self, format_string, directive)
675675
676676
677_format_registry = MergeDirectiveFormatRegistry()677_format_registry = MergeDirectiveFormatRegistry("bzrlib.merge_directive",
678 "_format_registry")
678_format_registry.register(MergeDirective)679_format_registry.register(MergeDirective)
679_format_registry.register(MergeDirective2)680_format_registry.register(MergeDirective2)
680# 0.19 never existed. It got renamed to 0.90. But by that point, there were681# 0.19 never existed. It got renamed to 0.90. But by that point, there were
681682
=== modified file 'bzrlib/option.py'
--- bzrlib/option.py 2011-12-18 12:46:49 +0000
+++ bzrlib/option.py 2012-03-31 14:09:30 +0000
@@ -370,7 +370,7 @@
370 RegistryOption constructor. Any other keyword arguments are treated370 RegistryOption constructor. Any other keyword arguments are treated
371 as values for the option, and their value is treated as the help.371 as values for the option, and their value is treated as the help.
372 """372 """
373 reg = _mod_registry.Registry()373 reg = _mod_registry.Registry(None, None)
374 for name, switch_help in sorted(kwargs.items()):374 for name, switch_help in sorted(kwargs.items()):
375 name = name.replace('_', '-')375 name = name.replace('_', '-')
376 reg.register(name, name, help=switch_help)376 reg.register(name, name, help=switch_help)
@@ -570,6 +570,6 @@
570 type=str,570 type=str,
571 help='Display timezone as local, original, or utc.')571 help='Display timezone as local, original, or utc.')
572572
573diff_writer_registry = _mod_registry.Registry()573diff_writer_registry = _mod_registry.Registry("bzrlib.option", "diff_writer_registry")
574diff_writer_registry.register('plain', lambda x: x, 'Plaintext diff output.')574diff_writer_registry.register('plain', lambda x: x, 'Plaintext diff output.')
575diff_writer_registry.default_key = 'plain'575diff_writer_registry.default_key = 'plain'
576576
=== modified file 'bzrlib/plugins/launchpad/__init__.py'
--- bzrlib/plugins/launchpad/__init__.py 2012-03-10 19:11:06 +0000
+++ bzrlib/plugins/launchpad/__init__.py 2012-03-31 14:09:30 +0000
@@ -53,8 +53,8 @@
53from bzrlib.commands import (53from bzrlib.commands import (
54 plugin_cmds,54 plugin_cmds,
55 )55 )
56from bzrlib.directory_service import directories56from bzrlib.hooks import install_lazy_named_hook
57from bzrlib.help_topics import topic_registry57from bzrlib.registry import register_lazy
5858
59for klsname, aliases in [59for klsname, aliases in [
60 ("cmd_register_branch", []),60 ("cmd_register_branch", []),
@@ -68,16 +68,15 @@
6868
6969
70def _register_directory():70def _register_directory():
71 directories.register_lazy('lp:', 'bzrlib.plugins.launchpad.lp_directory',71 register_lazy("bzrlib.directory_service", "directories", 'lp:',
72 'LaunchpadDirectory',72 'bzrlib.plugins.launchpad.lp_directory', 'LaunchpadDirectory',
73 'Launchpad-based directory service',)73 'Launchpad-based directory service',)
74 directories.register_lazy(74 register_lazy("bzrlib.directory_service", "directories",
75 'debianlp:', 'bzrlib.plugins.launchpad.lp_directory',75 'debianlp:', 'bzrlib.plugins.launchpad.lp_directory',
76 'LaunchpadDirectory',76 'LaunchpadDirectory',
77 'debianlp: shortcut')77 'debianlp: shortcut')
78 directories.register_lazy(78 register_lazy("bzrlib.directory_service", "directories", 'ubuntu:',
79 'ubuntu:', 'bzrlib.plugins.launchpad.lp_directory',79 'bzrlib.plugins.launchpad.lp_directory', 'LaunchpadDirectory',
80 'LaunchpadDirectory',
81 'ubuntu: shortcut')80 'ubuntu: shortcut')
8281
83_register_directory()82_register_directory()
@@ -132,7 +131,7 @@
132131
133132
134def _register_hooks():133def _register_hooks():
135 _mod_branch.Branch.hooks.install_named_hook('open',134 install_lazy_named_hook("bzrlib.branch", "Branch.hooks", 'open',
136 _check_is_up_to_date, 'package-branch-up-to-date')135 _check_is_up_to_date, 'package-branch-up-to-date')
137136
138137
@@ -184,8 +183,8 @@
184183
185For more information see http://help.launchpad.net/184For more information see http://help.launchpad.net/
186"""185"""
187topic_registry.register('launchpad',186register_lazy('bzrlib.help_topics', 'topic_registry', 'launchpad',
188 _launchpad_help,187 "bzrlib.plugins.launchpad", "_launchpad_help",
189 'Using Bazaar with Launchpad.net')188 'Using Bazaar with Launchpad.net')
190189
191_mod_config.option_registry.register(190_mod_config.option_registry.register(
192191
=== modified file 'bzrlib/plugins/netrc_credential_store/__init__.py'
--- bzrlib/plugins/netrc_credential_store/__init__.py 2011-12-18 12:46:49 +0000
+++ bzrlib/plugins/netrc_credential_store/__init__.py 2012-03-31 14:09:30 +0000
@@ -25,6 +25,7 @@
25 config,25 config,
26 lazy_import,26 lazy_import,
27 )27 )
28from bzrlib.registry import register_lazy
2829
29lazy_import.lazy_import(globals(), """30lazy_import.lazy_import(globals(), """
30import errno31import errno
@@ -62,7 +63,7 @@
62 return password63 return password
6364
6465
65config.credential_store_registry.register_lazy(66register_lazy("bzrlib.config", "credential_store_registry",
66 'netrc', __name__, 'NetrcCredentialStore', help=__doc__)67 'netrc', __name__, 'NetrcCredentialStore', help=__doc__)
6768
6869
6970
=== modified file 'bzrlib/plugins/po_merge/__init__.py'
--- bzrlib/plugins/po_merge/__init__.py 2011-12-20 22:09:13 +0000
+++ bzrlib/plugins/po_merge/__init__.py 2012-03-31 14:09:30 +0000
@@ -54,15 +54,15 @@
54"""54"""
5555
56from bzrlib import (56from bzrlib import (
57 config,
58 # Since we are a built-in plugin we share the bzrlib version57 # Since we are a built-in plugin we share the bzrlib version
59 version_info,58 version_info,
60 )59 )
61from bzrlib.hooks import install_lazy_named_hook60from bzrlib.hooks import install_lazy_named_hook
61from bzrlib.registry import register_lazy
6262
6363
64def register_lazy_option(key, member):64def register_lazy_option(key, member):
65 config.option_registry.register_lazy(65 register_lazy("bzrlib.config", "option_registry",
66 key, 'bzrlib.plugins.po_merge.po_merge', member)66 key, 'bzrlib.plugins.po_merge.po_merge', member)
6767
6868
6969
=== modified file 'bzrlib/plugins/weave_fmt/__init__.py'
--- bzrlib/plugins/weave_fmt/__init__.py 2011-12-18 12:46:49 +0000
+++ bzrlib/plugins/weave_fmt/__init__.py 2012-03-31 14:09:30 +0000
@@ -28,9 +28,9 @@
28 branch as _mod_branch,28 branch as _mod_branch,
29 controldir,29 controldir,
30 repository as _mod_repository,30 repository as _mod_repository,
31 serializer,
32 workingtree as _mod_workingtree,31 workingtree as _mod_workingtree,
33 )32 )
33from bzrlib.registry import register_lazy
34from bzrlib.bzrdir import (34from bzrlib.bzrdir import (
35 BzrProber,35 BzrProber,
36 register_metadir,36 register_metadir,
@@ -114,8 +114,8 @@
114 'bzrlib.plugins.weave_fmt.workingtree',114 'bzrlib.plugins.weave_fmt.workingtree',
115 'WorkingTreeFormat2')115 'WorkingTreeFormat2')
116116
117serializer.format_registry.register_lazy('4', 'bzrlib.plugins.weave_fmt.xml4',117register_lazy("bzrlib.serializer", "format_registry", '4',
118 'serializer_v4')118 'bzrlib.plugins.weave_fmt.xml4', 'serializer_v4')
119119
120def load_tests(basic_tests, module, loader):120def load_tests(basic_tests, module, loader):
121 testmod_names = [121 testmod_names = [
122122
=== modified file 'bzrlib/registry.py'
--- bzrlib/registry.py 2011-12-19 13:23:58 +0000
+++ bzrlib/registry.py 2012-03-31 14:09:30 +0000
@@ -18,6 +18,8 @@
1818
19from __future__ import absolute_import19from __future__ import absolute_import
2020
21import collections
22
21from bzrlib.pyutils import get_named_object23from bzrlib.pyutils import get_named_object
2224
2325
@@ -81,6 +83,16 @@
81 self._module_name, self._member_name, self._imported)83 self._module_name, self._member_name, self._imported)
8284
8385
86"""\
87Entry in a registry
88
89:ivar objgetter: _ObjectGetter instance which can provide the actual object
90:ivar info: Info object (registry-dependent)
91:ivar help: Help string
92"""
93RegistryEntry = collections.namedtuple('RegistryEntry', 'objgetter info help')
94
95
84class Registry(object):96class Registry(object):
85 """A class that registers objects to a name.97 """A class that registers objects to a name.
8698
@@ -97,13 +109,23 @@
97 will return the entry for the default key.109 will return the entry for the default key.
98 """110 """
99111
100 def __init__(self):112 def __init__(self, module=None, member_name=None):
101 """Create a new Registry."""113 """Create a new Registry.
114
115 :param module: Optional module registry is present in. Used
116 for lazy registration.
117 :param member_name: Optional member_name of registry in module. Used
118 for lazy registration.
119
120 If module and member_name aren't specified, then lazy registration is
121 not supported.
122 """
102 self._default_key = None123 self._default_key = None
103 # Map from key => (is_lazy, info)124 # Map from key => (is_lazy, info)
104 self._dict = {}125 if module is not None and member_name is not None:
105 self._help_dict = {}126 self._dict = _lazy_registries.setdefault((module, member_name), {})
106 self._info_dict = {}127 else:
128 self._dict = {}
107129
108 def register(self, key, obj, help=None, info=None,130 def register(self, key, obj, help=None, info=None,
109 override_existing=False):131 override_existing=False):
@@ -125,8 +147,7 @@
125 if not override_existing:147 if not override_existing:
126 if key in self._dict:148 if key in self._dict:
127 raise KeyError('Key %r already registered' % key)149 raise KeyError('Key %r already registered' % key)
128 self._dict[key] = _ObjectGetter(obj)150 self._dict[key] = RegistryEntry(_ObjectGetter(obj), info, help)
129 self._add_help_and_info(key, help=help, info=info)
130151
131 def register_lazy(self, key, module_name, member_name,152 def register_lazy(self, key, module_name, member_name,
132 help=None, info=None,153 help=None, info=None,
@@ -149,13 +170,8 @@
149 if not override_existing:170 if not override_existing:
150 if key in self._dict:171 if key in self._dict:
151 raise KeyError('Key %r already registered' % key)172 raise KeyError('Key %r already registered' % key)
152 self._dict[key] = _LazyObjectGetter(module_name, member_name)173 self._dict[key] = RegistryEntry(
153 self._add_help_and_info(key, help=help, info=info)174 _LazyObjectGetter(module_name, member_name), info, help)
154
155 def _add_help_and_info(self, key, help=None, info=None):
156 """Add the help and information about this key"""
157 self._help_dict[key] = help
158 self._info_dict[key] = info
159175
160 def get(self, key=None):176 def get(self, key=None):
161 """Return the object register()'ed to the given key.177 """Return the object register()'ed to the given key.
@@ -174,7 +190,7 @@
174 :raises AttributeError: If registered lazily, and the module does not190 :raises AttributeError: If registered lazily, and the module does not
175 contain the registered member.191 contain the registered member.
176 """192 """
177 return self._dict[self._get_key_or_default(key)].get_obj()193 return self._dict[self._get_key_or_default(key)].objgetter.get_obj()
178194
179 def _get_module(self, key):195 def _get_module(self, key):
180 """Return the module the object will be or was loaded from.196 """Return the module the object will be or was loaded from.
@@ -182,7 +198,7 @@
182 :param key: The key to obtain the module for.198 :param key: The key to obtain the module for.
183 :return: The name of the module199 :return: The name of the module
184 """200 """
185 return self._dict[key].get_module()201 return self._dict[key].objgetter.get_module()
186202
187 def get_prefix(self, fullname):203 def get_prefix(self, fullname):
188 """Return an object whose key is a prefix of the supplied value.204 """Return an object whose key is a prefix of the supplied value.
@@ -206,14 +222,14 @@
206222
207 def get_help(self, key=None):223 def get_help(self, key=None):
208 """Get the help text associated with the given key"""224 """Get the help text associated with the given key"""
209 the_help = self._help_dict[self._get_key_or_default(key)]225 the_help = self._dict[self._get_key_or_default(key)].help
210 if callable(the_help):226 if callable(the_help):
211 return the_help(self, key)227 return the_help(self, key)
212 return the_help228 return the_help
213229
214 def get_info(self, key=None):230 def get_info(self, key=None):
215 """Get the extra information associated with the given key"""231 """Get the extra information associated with the given key"""
216 return self._info_dict[self._get_key_or_default(key)]232 return self._dict[self._get_key_or_default(key)].info
217233
218 def remove(self, key):234 def remove(self, key):
219 """Remove a registered entry.235 """Remove a registered entry.
@@ -230,14 +246,14 @@
230 return sorted(self._dict.keys())246 return sorted(self._dict.keys())
231247
232 def iteritems(self):248 def iteritems(self):
233 for key, getter in self._dict.iteritems():249 for key, entry in self._dict.iteritems():
234 yield key, getter.get_obj()250 yield key, entry.objgetter.get_obj()
235251
236 def items(self):252 def items(self):
237 # We should not use the iteritems() implementation below (see bug253 # We should not use the iteritems() implementation below (see bug
238 # #430510)254 # #430510)
239 return sorted([(key, getter.get_obj())255 return sorted([(key, entry.objgetter.get_obj())
240 for key, getter in self._dict.items()])256 for key, entry in self._dict.items()])
241257
242 def _set_default_key(self, key):258 def _set_default_key(self, key):
243 if not self._dict.has_key(key):259 if not self._dict.has_key(key):
@@ -256,8 +272,9 @@
256class FormatRegistry(Registry):272class FormatRegistry(Registry):
257 """Registry specialised for handling formats."""273 """Registry specialised for handling formats."""
258274
259 def __init__(self, other_registry=None):275 def __init__(self, module_name=None, member_name=None,
260 Registry.__init__(self)276 other_registry=None):
277 Registry.__init__(self, module_name, member_name)
261 self._other_registry = other_registry278 self._other_registry = other_registry
262279
263 def register(self, key, obj, help=None, info=None,280 def register(self, key, obj, help=None, info=None,
@@ -289,3 +306,42 @@
289 if callable(r):306 if callable(r):
290 r = r()307 r = r()
291 return r308 return r
309
310
311# Lazily registered registries.
312# Maps (module, registry_member_name) -> registry_dict
313#
314# A registry dict maps a key to a RegistryEntry
315#
316# A Registry is associated with either its own private dictionary or
317# a dictionary based in _lazy_registries, if a module name and member name
318# were specified during its creation.
319#
320# The internal registry dictionaries live here so entries can be added
321# without having to load the actual registry.
322_lazy_registries = {}
323
324
325def register_lazy(registry_module, registry_name, key, entry_module,
326 entry_name, help=None, info=None, override_existing=False):
327 """Lazily register an entry in a registry that's not yet loaded.
328
329 :param registry_module: Name of the module in which the registry lives
330 :param registry_name: Python name of the registry
331 :param key: Key of the entry in the registry
332 :param entry_module: Module name for the entry
333 :param entry_name: Python name of the entry
334 :param info: Optional info object
335 :param help: Optional help description
336 :param override_existing: Whether to allow overriding existing
337 entries
338 """
339 # Find the internal registry dict for the specified registry.
340 registry_dict = _lazy_registries.setdefault(
341 (registry_module, registry_name), {})
342 if not override_existing:
343 if key in registry_dict:
344 raise KeyError('Key %r already registered' % key)
345 obj_getter = _LazyObjectGetter(entry_module, entry_name)
346 # Add the entry to the registry dict.
347 registry_dict[key] = RegistryEntry(obj_getter, info, help)
292348
=== modified file 'bzrlib/remote.py'
--- bzrlib/remote.py 2012-03-14 14:17:48 +0000
+++ bzrlib/remote.py 2012-03-31 14:09:30 +0000
@@ -4139,8 +4139,9 @@
4139 tar.extract(tarinfo, to_dir)4139 tar.extract(tarinfo, to_dir)
41404140
41414141
4142error_translators = registry.Registry()4142error_translators = registry.Registry("bzrlib.remote", "error_translators")
4143no_context_error_translators = registry.Registry()4143no_context_error_translators = registry.Registry("bzrlib.remote",
4144 "no_context_error_translators")
41444145
41454146
4146def _translate_error(err, **context):4147def _translate_error(err, **context):
41474148
=== modified file 'bzrlib/repository.py'
--- bzrlib/repository.py 2012-03-29 12:27:52 +0000
+++ bzrlib/repository.py 2012-03-31 14:09:30 +0000
@@ -1324,7 +1324,8 @@
1324 return controldir.format_registry.make_bzrdir('default').repository_format1324 return controldir.format_registry.make_bzrdir('default').repository_format
13251325
13261326
1327network_format_registry = registry.FormatRegistry()1327network_format_registry = registry.FormatRegistry("bzrlib.repository",
1328 "network_format_registry")
1328"""Registry of formats indexed by their network name.1329"""Registry of formats indexed by their network name.
13291330
1330The network name for a repository format is an identifier that can be used when1331The network name for a repository format is an identifier that can be used when
@@ -1333,7 +1334,8 @@
1333"""1334"""
13341335
13351336
1336format_registry = RepositoryFormatRegistry(network_format_registry)1337format_registry = RepositoryFormatRegistry("bzrlib.repository",
1338 "format_registry", network_format_registry)
1337"""Registry of formats, indexed by their BzrDirMetaFormat format string.1339"""Registry of formats, indexed by their BzrDirMetaFormat format string.
13381340
1339This can contain either format instances themselves, or classes/factories that1341This can contain either format instances themselves, or classes/factories that
13401342
=== modified file 'bzrlib/revisionspec.py'
--- bzrlib/revisionspec.py 2011-12-19 10:58:39 +0000
+++ bzrlib/revisionspec.py 2012-03-31 14:09:30 +0000
@@ -992,7 +992,7 @@
992RevisionSpec_dwim.append_possible_revspec(RevisionSpec_date)992RevisionSpec_dwim.append_possible_revspec(RevisionSpec_date)
993RevisionSpec_dwim.append_possible_revspec(RevisionSpec_branch)993RevisionSpec_dwim.append_possible_revspec(RevisionSpec_branch)
994994
995revspec_registry = registry.Registry()995revspec_registry = registry.Registry("bzrlib.revisionspec", "revspec_registry")
996def _register_revspec(revspec):996def _register_revspec(revspec):
997 revspec_registry.register(revspec.prefix, revspec)997 revspec_registry.register(revspec.prefix, revspec)
998998
999999
=== modified file 'bzrlib/send.py'
--- bzrlib/send.py 2012-02-01 19:18:09 +0000
+++ bzrlib/send.py 2012-03-31 14:09:30 +0000
@@ -35,7 +35,7 @@
35 )35 )
3636
3737
38format_registry = registry.Registry()38format_registry = registry.Registry("bzrlib.send", "format_registry")
3939
4040
41def send(target_branch, revision, public_branch, remember,41def send(target_branch, revision, public_branch, remember,
4242
=== modified file 'bzrlib/serializer.py'
--- bzrlib/serializer.py 2011-12-19 13:23:58 +0000
+++ bzrlib/serializer.py 2012-03-31 14:09:30 +0000
@@ -92,7 +92,7 @@
92 """Registry for serializer objects"""92 """Registry for serializer objects"""
9393
9494
95format_registry = SerializerRegistry()95format_registry = SerializerRegistry("bzrlib.serializer", "format_registry")
96format_registry.register_lazy('5', 'bzrlib.xml5', 'serializer_v5')96format_registry.register_lazy('5', 'bzrlib.xml5', 'serializer_v5')
97format_registry.register_lazy('6', 'bzrlib.xml6', 'serializer_v6')97format_registry.register_lazy('6', 'bzrlib.xml6', 'serializer_v6')
98format_registry.register_lazy('7', 'bzrlib.xml7', 'serializer_v7')98format_registry.register_lazy('7', 'bzrlib.xml7', 'serializer_v7')
9999
=== modified file 'bzrlib/smart/request.py'
--- bzrlib/smart/request.py 2012-02-23 23:26:35 +0000
+++ bzrlib/smart/request.py 2012-03-31 14:09:30 +0000
@@ -521,7 +521,7 @@
521# mutate State is updated in a way that replaying that request results in a521# mutate State is updated in a way that replaying that request results in a
522# different state. For example 'append' writes more bytes to a given522# different state. For example 'append' writes more bytes to a given
523# file. If append succeeds, it moves the file pointer.523# file. If append succeeds, it moves the file pointer.
524request_handlers = registry.Registry()524request_handlers = registry.Registry("bzrlib.smart.request", "request_handlers")
525request_handlers.register_lazy(525request_handlers.register_lazy(
526 'append', 'bzrlib.smart.vfs', 'AppendRequest', info='mutate')526 'append', 'bzrlib.smart.vfs', 'AppendRequest', info='mutate')
527request_handlers.register_lazy(527request_handlers.register_lazy(
528528
=== modified file 'bzrlib/tag.py'
--- bzrlib/tag.py 2011-12-19 13:23:58 +0000
+++ bzrlib/tag.py 2012-03-31 14:09:30 +0000
@@ -421,7 +421,7 @@
421 tags.sort(key=lambda x: timestamps[x[1]])421 tags.sort(key=lambda x: timestamps[x[1]])
422422
423423
424tag_sort_methods = Registry()424tag_sort_methods = Registry("bzrlib.tag", "tag_sort_methods")
425tag_sort_methods.register("natural", sort_natural,425tag_sort_methods.register("natural", sort_natural,
426 'Sort numeric substrings as numbers. (default)')426 'Sort numeric substrings as numbers. (default)')
427tag_sort_methods.register("alpha", sort_alpha, 'Sort tags lexicographically.')427tag_sort_methods.register("alpha", sort_alpha, 'Sort tags lexicographically.')
428428
=== modified file 'bzrlib/tests/__init__.py'
--- bzrlib/tests/__init__.py 2012-03-13 09:07:18 +0000
+++ bzrlib/tests/__init__.py 2012-03-31 14:09:30 +0000
@@ -3328,7 +3328,7 @@
33283328
33293329
3330# A registry where get() returns a suite decorator.3330# A registry where get() returns a suite decorator.
3331parallel_registry = registry.Registry()3331parallel_registry = registry.Registry("bzrlib.tests", "parallel_registry")
33323332
33333333
3334def fork_decorator(suite):3334def fork_decorator(suite):
@@ -3884,7 +3884,8 @@
3884 return '.'.join(parts)3884 return '.'.join(parts)
38853885
38863886
3887test_prefix_alias_registry = TestPrefixAliasRegistry()3887test_prefix_alias_registry = TestPrefixAliasRegistry("bzrlib.tests",
3888 "test_prefix_alias_registry")
3888"""Registry of test prefix aliases."""3889"""Registry of test prefix aliases."""
38893890
38903891
38913892
=== modified file 'bzrlib/tests/test_foreign.py'
--- bzrlib/tests/test_foreign.py 2012-02-23 19:45:15 +0000
+++ bzrlib/tests/test_foreign.py 2012-03-31 14:09:30 +0000
@@ -76,7 +76,7 @@
76 """76 """
7777
78 def __init__(self):78 def __init__(self):
79 self.mapping_registry = DummyForeignVcsMappingRegistry()79 self.mapping_registry = DummyForeignVcsMappingRegistry(None, None)
80 self.mapping_registry.register("v1", DummyForeignVcsMapping(self),80 self.mapping_registry.register("v1", DummyForeignVcsMapping(self),
81 "Version 1")81 "Version 1")
82 self.abbreviation = "dummy"82 self.abbreviation = "dummy"
8383
=== modified file 'bzrlib/tests/test_registry.py'
--- bzrlib/tests/test_registry.py 2012-01-25 21:13:15 +0000
+++ bzrlib/tests/test_registry.py 2012-03-31 14:09:30 +0000
@@ -22,6 +22,7 @@
22from bzrlib import (22from bzrlib import (
23 branch,23 branch,
24 osutils,24 osutils,
25 pyutils,
25 registry,26 registry,
26 tests,27 tests,
27 )28 )
@@ -238,7 +239,7 @@
238 # We peek under the covers because the alternative is to use lazy239 # We peek under the covers because the alternative is to use lazy
239 # registration and create a module that can reference our test registry240 # registration and create a module that can reference our test registry
240 # it's too much work for such a corner case -- vila 090916241 # it's too much work for such a corner case -- vila 090916
241 self.registry._dict['hacky'] = InvasiveGetter(None)242 self.registry._dict['hacky'] = registry.RegistryEntry(InvasiveGetter(None), None, None)
242243
243 def _iter_them(self, iter_func_name):244 def _iter_them(self, iter_func_name):
244 iter_func = getattr(self.registry, iter_func_name, None)245 iter_func = getattr(self.registry, iter_func_name, None)
@@ -354,3 +355,41 @@
354 a_registry.register("obj", AThing())355 a_registry.register("obj", AThing())
355 self.assertEquals("bzrlib.tests.test_registry",356 self.assertEquals("bzrlib.tests.test_registry",
356 a_registry._get_module("obj"))357 a_registry._get_module("obj"))
358
359
360
361class TestLazyRegistry(tests.TestCase):
362 """Test bzrlib.registry.register_lazy."""
363
364 def test_valid_lazy_registries(self):
365 # Make sure that all the registered lazy hooks are referring to existing
366 # hook points which allow lazy registration.
367 for key, registry_dict in registry._lazy_registries.iteritems():
368 (module_name, member_name) = key
369 obj = pyutils.get_named_object(module_name, member_name)
370 self.assertIsInstance(obj, registry.Registry)
371 self.assertIsInstance(registry_dict, dict)
372 self.assertIs(obj._dict, registry_dict)
373
374 def test_register_lazy(self):
375 # A lazily registered entry shows up if the registry is later created
376 registry.register_lazy("bzrlib.tests.test_registry", "SomeRegistry",
377 "myname", "bzrlib.tests.test_registry", "TestLazyRegistry",
378 help="HELLUP!", info="Informatief")
379 a_registry = registry.Registry("bzrlib.tests.test_registry", "SomeRegistry")
380 self.addCleanup(registry._lazy_registries.__delitem__,
381 ("bzrlib.tests.test_registry", "SomeRegistry"))
382 self.assertEquals([("myname", TestLazyRegistry)], a_registry.items())
383
384 def test_register_lazy_dupe(self):
385 # Two registry entries can't be registered with the same name
386 registry.register_lazy("bzrlib.tests.test_registry", "SomeRegistry",
387 "myname", "bzrlib.tests.test_registry", "TestLazyRegistry")
388 self.addCleanup(registry._lazy_registries.__delitem__,
389 ("bzrlib.tests.test_registry", "SomeRegistry"))
390 self.assertRaises(KeyError,
391 registry.register_lazy, "bzrlib.tests.test_registry", "SomeRegistry",
392 "myname", "bzrlib.tests.test_registry", "TestLazyRegistry")
393 registry.register_lazy("bzrlib.tests.test_registry", "SomeRegistry",
394 "myname", "bzrlib.tests.test_registry", "TestLazyRegistry",
395 override_existing=True)
357396
=== modified file 'bzrlib/transform.py'
--- bzrlib/transform.py 2012-03-14 10:17:12 +0000
+++ bzrlib/transform.py 2012-03-31 14:09:30 +0000
@@ -1461,7 +1461,7 @@
1461 raise OrphaningForbidden('never')1461 raise OrphaningForbidden('never')
14621462
14631463
1464orphaning_registry = registry.Registry()1464orphaning_registry = registry.Registry("bzrlib.transform", "orphaning_registry")
1465orphaning_registry.register(1465orphaning_registry.register(
1466 'conflict', refuse_orphan,1466 'conflict', refuse_orphan,
1467 'Leave orphans in place and create a conflict on the directory.')1467 'Leave orphans in place and create a conflict on the directory.')
14681468
=== modified file 'bzrlib/transport/__init__.py'
--- bzrlib/transport/__init__.py 2012-03-13 17:25:29 +0000
+++ bzrlib/transport/__init__.py 2012-03-31 14:09:30 +0000
@@ -123,7 +123,8 @@
123 self.register(key, [], help)123 self.register(key, [], help)
124124
125125
126transport_list_registry = TransportListRegistry()126transport_list_registry = TransportListRegistry("bzrlib.transport",
127 "transport_list_registry")
127128
128129
129def register_transport_proto(prefix, help=None, info=None,130def register_transport_proto(prefix, help=None, info=None,
@@ -1890,7 +1891,8 @@
1890 'HintingSSHTransport')1891 'HintingSSHTransport')
18911892
18921893
1893transport_server_registry = registry.Registry()1894transport_server_registry = registry.Registry("bzrlib.transport",
1895 "transport_server_registry")
1894transport_server_registry.register_lazy('bzr', 'bzrlib.smart.server',1896transport_server_registry.register_lazy('bzr', 'bzrlib.smart.server',
1895 'serve_bzr', help="The Bazaar smart server protocol over TCP. (default port: 4155)")1897 'serve_bzr', help="The Bazaar smart server protocol over TCP. (default port: 4155)")
1896transport_server_registry.default_key = 'bzr'1898transport_server_registry.default_key = 'bzr'
18971899
=== modified file 'bzrlib/version_info_formats/__init__.py'
--- bzrlib/version_info_formats/__init__.py 2011-12-30 13:02:27 +0000
+++ bzrlib/version_info_formats/__init__.py 2012-03-31 14:09:30 +0000
@@ -186,8 +186,8 @@
186 raise NotImplementedError(VersionInfoBuilder.generate)186 raise NotImplementedError(VersionInfoBuilder.generate)
187187
188188
189format_registry = registry.Registry()189format_registry = registry.Registry("bzrlib.version_info_formats",
190190 "format_registry")
191191
192format_registry.register_lazy(192format_registry.register_lazy(
193 'rio',193 'rio',
194194
=== modified file 'bzrlib/versionedfile.py'
--- bzrlib/versionedfile.py 2011-12-19 13:23:58 +0000
+++ bzrlib/versionedfile.py 2012-03-31 14:09:30 +0000
@@ -45,7 +45,7 @@
45from bzrlib.textmerge import TextMerge45from bzrlib.textmerge import TextMerge
4646
4747
48adapter_registry = Registry()48adapter_registry = Registry("bzrlib.versionedfile", "adapter_registry")
49adapter_registry.register_lazy(('knit-delta-gz', 'fulltext'), 'bzrlib.knit',49adapter_registry.register_lazy(('knit-delta-gz', 'fulltext'), 'bzrlib.knit',
50 'DeltaPlainToFullText')50 'DeltaPlainToFullText')
51adapter_registry.register_lazy(('knit-ft-gz', 'fulltext'), 'bzrlib.knit',51adapter_registry.register_lazy(('knit-ft-gz', 'fulltext'), 'bzrlib.knit',
5252
=== modified file 'bzrlib/workingtree.py'
--- bzrlib/workingtree.py 2012-03-29 12:27:52 +0000
+++ bzrlib/workingtree.py 2012-03-31 14:09:30 +0000
@@ -2998,8 +2998,10 @@
2998class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):2998class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
2999 """Registry for working tree formats."""2999 """Registry for working tree formats."""
30003000
3001 def __init__(self, other_registry=None):3001 def __init__(self, module_name=None, member_name=None,
3002 super(WorkingTreeFormatRegistry, self).__init__(other_registry)3002 other_registry=None):
3003 super(WorkingTreeFormatRegistry, self).__init__(module_name,
3004 member_name, other_registry)
3003 self._default_format = None3005 self._default_format = None
3004 self._default_format_key = None3006 self._default_format_key = None
30053007
@@ -3021,7 +3023,8 @@
3021 self._default_format = None3023 self._default_format = None
30223024
30233025
3024format_registry = WorkingTreeFormatRegistry()3026format_registry = WorkingTreeFormatRegistry("bzrlib.workingtree",
3027 "format_registry")
30253028
30263029
3027class WorkingTreeFormat(controldir.ControlComponentFormat):3030class WorkingTreeFormat(controldir.ControlComponentFormat):
30283031
=== modified file 'doc/en/release-notes/bzr-2.6.txt'
--- doc/en/release-notes/bzr-2.6.txt 2012-03-30 02:23:41 +0000
+++ doc/en/release-notes/bzr-2.6.txt 2012-03-31 14:09:30 +0000
@@ -157,6 +157,10 @@
157* New method ``Repository.verify_revision_signatures``.157* New method ``Repository.verify_revision_signatures``.
158 (Jelmer Vernooij)158 (Jelmer Vernooij)
159159
160* New function ``bzrlib.registry.register_lazy`` which can
161 register new keys into registries before they are loaded.
162 (Jelmer Vernooij)
163
160* New configuration option class ``RegistryOption`` which is backed164* New configuration option class ``RegistryOption`` which is backed
161 onto a registry. (Jelmer Vernooij)165 onto a registry. (Jelmer Vernooij)
162166