comparison mercurial/extensions.py @ 11402:367ce8514da0

extensions: recommend against using wrapfunction for repo methods Instead, all extensions should use the "dynamic subclass" trick: subclass repo.__class__ and then replace repo.__class__ with your new subclass. This avoids conflicts that happen when one extension uses wrapfunction and another uses subclassing to extend the same method of localrepository.
author Greg Ward <greg-hg@gerg.ca>
date Tue, 15 Jun 2010 13:04:22 -0400
parents de1e7099d100
children bbdf1fb1d3e3
comparison
equal deleted inserted replaced
11401:3bc892f740d6 11402:367ce8514da0
122 newentry[0] = wrap 122 newentry[0] = wrap
123 table[key] = tuple(newentry) 123 table[key] = tuple(newentry)
124 return entry 124 return entry
125 125
126 def wrapfunction(container, funcname, wrapper): 126 def wrapfunction(container, funcname, wrapper):
127 '''Wrap the function named funcname in container
128
129 It is replacing with your wrapper. The container is typically a
130 module, class, or instance.
131
132 The wrapper will be called like
133
134 wrapper(orig, *args, **kwargs)
135
136 where orig is the original (wrapped) function, and *args, **kwargs
137 are the arguments passed to it.
138
139 Wrapping methods of the repository object is not recommended since
140 it conflicts with extensions that extend the repository by
141 subclassing. All extensions that need to extend methods of
142 localrepository should use this subclassing trick: namely,
143 reposetup() should look like
144
145 def reposetup(ui, repo):
146 class myrepo(repo.__class__):
147 def whatever(self, *args, **kwargs):
148 [...extension stuff...]
149 super(myrepo, self).whatever(*args, **kwargs)
150 [...extension stuff...]
151
152 repo.__class__ = myrepo
153
154 In general, combining wrapfunction() with subclassing does not
155 work. Since you cannot control what other extensions are loaded by
156 your end users, you should play nicely with others by using the
157 subclass trick.
158 '''
127 def wrap(*args, **kwargs): 159 def wrap(*args, **kwargs):
128 return wrapper(origfn, *args, **kwargs) 160 return wrapper(origfn, *args, **kwargs)
129 161
130 origfn = getattr(container, funcname) 162 origfn = getattr(container, funcname)
131 setattr(container, funcname, wrap) 163 setattr(container, funcname, wrap)