[devel at bb.net] Use of module wrapping in bug2340
Vladimir Rutsky
rutsky.vladimir at gmail.com
Wed Feb 3 02:29:35 UTC 2016
Hello!
During "slave"->"worker" transition in bug 2340 names such as
buildbot.locks.SlaveLock
will be renamed to "worker"-based names, e.g. buildbot.locks.WorkerLock.
For some classes fallback will be provided, e.g.
buildbot.locks.SlaveLock will still
be available in 0.9.0, however it's use will emit deprecation warning.
My initial fallback implementation idea (that I expressed in PR #1943 [1])
were based on an opinion, that Python module replacement in sys.modules
is a terrible hack
and should be avoided at all costs.
So to add fallback for buildbot.locks.SlaveLock I added dummy class via
wrapper
that were named SlaveLock, inherited from WorkerLock and has overriden
__new__
to emitted warning, when SlaveLock is *instantiated*.
Effectively:
class WorkerLock:
...
class SlaveLock(WorkerLock):
def __new__(cls, *args, **kwargs):
# Raise warning here
return cls.__new__(instance_cls)
To add fallback for a function I added dummy function that emitted warning
*when called* and forwarded all arguments to the wrapped function.
Effectively:
def enforceChosenWorker(bldr, workerforbuilder, breq):
...
def enforceChosenSlave(*args, **kwargs):
# Raise warning here
return enforceChosenWorker(*args, **kwargs)
Recently I noticed that Twisted already has helper for deprecating
module attributes [2]:
deprecatedModuleAttributes().
Twisted does it by replacing module in sys.modules with custom proxy
object that
emits warnings when deprecated attribute is accessed.
I want to refactor my fallback helpers to use Twisted's approach (I will
to use
deprecatedModuleAttributes in my wrappers) and interested in other
developers
opinions regarding Twisted's approach.
Pros of using module proxy:
1. Function or class *access* will raise warning.
This is the only option to raise warnings in some cases, e.g. in case if
user catches
BuildSlaveTooOldError in his code (that class is never instantiated in
user code).
Cons of using module proxy:
1. It's a hack that may lead to unexpected behaviour.
If Twisted developers uses it I want to believe that this is not so
terrible hack,
but at least cctrial has some issues on such modules [3]
(module proxy can not be reloaded).
2. It may make run code slower (insignificantly, IMO).
3. It doesn't scale. If anyone else will decide to replace module with
it's own
wrapper it may result in a conflict.
4. It will emit warnings if star imports are used, even if no
"slave"-named objects
are actually used (e.g. `from buildbot.interfaces import *` will emit
warning).
Which implementation is more preferable?
I like module replacement approach, but afraid of star imports in the
client code
(star import from buildbot.plugins *will* work properly without warnings
with my
current implementation of fallback in plugins, but not from other modules).
Switch implementation it's not a problem (API of my helpers will not
change,
only their implementation).
[1] https://github.com/buildbot/buildbot/pull/1943
[2]
https://twistedmatrix.com/documents/9.0.0/api/twisted.python.deprecate.html
[3] https://github.com/tardyp/cctrial/issues/4
Regards,
Vladimir Rutsky
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.buildbot.net/pipermail/devel/attachments/20160203/9685dc07/attachment.html>
More information about the devel
mailing list