Add 3.6 to the list of Python versions that Travis/tox will exercise. Also, switch the pypy3 target to version 3.3 (since pkg_resources is not supported anymore on 3.2).
A previous change added some logic so that when monkeypatching a
staticmethod the old_value was restored as a staticmethod. There was an
issue where the determination of whether or not a method should be
static was incorrectly checking the new function not the one to be
replaced. That caused an unintended side-effect that in order to patch
an instance method of a class the new function needed to be an instance
method of a class.
This change now reworks the semantics of MonkeyPatch to address that
issue and at the same time be explicit about how it should work in a
large number of different cases. The rule is simple and provides great
flexibility. Given a callable bar to be patched on to foo bar will be
called with any bound arguments first and then arguments of foo
appended. This is easier to visualize. Given:
class C(object):
@classmethod
def foo(cls, arg):
pass
class D(object):
@classmethod
def bar(cls, tgtcls, arg):
pass
def baz(cls, arg):
pass
MonkeyPatch('...C.foo', D.bar) will result in C.foo(1) calling bar like
bar(D, C, 1) because cls on bar was already bound to D when patching.
And MonkeyPatch('...C.foo', baz) will result in baz being called with
baz(C, 1).
In Python setattr(Class, name, func) automatically converts a function
into an instancemethod. To keep type(Class.func) as function,
staticmethod(func) must be applied explicitly.
This was previously fixed for Python 2 when cleaning up the patched
function but Python 3 needs the same handling.
When patching a function it was being converted to an instancemethod for
both Python 2 and 3 and this has now been fixed. This is a breaking
change as it was previously acceptable to patch a staticmethod with an
instancemethod.
The test for this case was updated to correctly check both cases. The
patched function is called as both Class.function() and
Class().function(), and then called again after the cleanup has occurred
resetting the function to its original state. The Class().function()
check is important because the method does not become bound until the
class it is defined on is instantiated.
Sem-Ver: api-break
When using the FakeLogger, have mis-formatted logging messages raise an
exception.
Normally when using the logging module, mis-formatted logging messages
will not raise an exception. Instead the exception will be printed but
not raised.
Change this behavior so that mis-formatted log messages can be caught
during unit-testing.
Closes-Bug: #1503049
Change-Id: I8d3e94d131289300ae020eb1d63306489e986335
Fixture.setUp should no longer be overridden in subclasses. Instead
override _setUp. This permits the Fixture base class to detect failures
during _setUp and trigger any registered cleanups, attach any details
to the failure exception and propogate that to callers.
(Robert Collins, #1456361, #1456353)
Capturing the warnings module output (which is typically used
for deprecating code or functions or modules) is quite useful and
is a frequent operation that can be required to perform. So provide
a fixture that is similar (but not the same) as the warnings
``catch_warnings`` context manager that can be used to gather all
warnings emitted and allows people to later analyze them to ensure
they are as they expect.
Provide tox configuration to make it easy to run tests locally against
different python environments without have to install dependencies
into the system. The default env is left at py27 only for
compatibility, however tox -e py33 and tox -e py34 will work fine with
this in place.
PEP 475 led to ``time.sleep()`` not being interrupted when a received signal
handler eats the signal (rather than raising an exception). (Robert Collins)
When working on OpenStack in tree functional test things like the
context information is extremely useful to have access to. This relies
on using custom log formatter, which currently can't be done in
fixtures.
The creates an additional optional parameter for FakeLogger to specify
this.
The logging fixture is extremely useful to be used a temp buffer for
collecting log messages into a buffer, and only decide if we're going
to emit them after some event in the future (like the failure or
success of some future criteria). However, in it's current form we are
not given access to the datefmt variable of the underlying Formatter,
which means we always end up with the default python time string for
%(asctime), which looks incorrectly localized many places.
This merely adds the ability to pass the datefmt param through to the
Formatter.
Signed-off-by: Sean Dague <sean@dague.net>