Mercurial > public > mercurial-scm > hg
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) |