Skip to content

Commit

Permalink
Merge 1213bb6 into d378fc5
Browse files Browse the repository at this point in the history
  • Loading branch information
mdickinson committed Dec 18, 2014
2 parents d378fc5 + 1213bb6 commit 8246785
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 23 deletions.
35 changes: 35 additions & 0 deletions traits/testing/tests/test_unittest_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,23 @@
#------------------------------------------------------------------------------
import threading
import time
import warnings

from traits import _py2to3

from traits.testing.unittest_tools import unittest
from traits.api import (Bool, Event, Float, HasTraits, Int, List,
on_trait_change)
from traits.testing.api import UnittestTools
from traits.util.api import deprecated


@deprecated("This function is outdated. Use 'shiny' instead!")
def old_and_dull():
""" A deprecated function, for use in assertDeprecated tests.
"""
pass


class TestObject(HasTraits):
Expand Down Expand Up @@ -360,6 +370,31 @@ def condition(a_object):
timeout=10.0,
)

def test_assert_deprecated(self):
with self.assertDeprecated():
old_and_dull()

def test_assert_deprecated_failures(self):
with self.assertRaises(self.failureException):
with self.assertDeprecated():
pass

def test_assert_deprecated_when_warning_already_issued(self):
# Exercise a problematic case where previous calls to a function or
# method that issues a DeprecationWarning have already polluted the
# __warningregistry__. For this, we need a single call-point to
# old_and_dull, since distinct call-points have separate entries in
# __warningregistry__.
def old_and_dull_caller():
old_and_dull()

# Pollute the registry by pre-calling the function.
old_and_dull_caller()

# Check that we can still detect the DeprecationWarning.
with self.assertDeprecated():
old_and_dull_caller()


if __name__ == '__main__':
unittest.main()
26 changes: 25 additions & 1 deletion traits/testing/unittest_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@

import contextlib
import threading
import sys
import warnings

from traits.api import (Any, Event, HasStrictTraits, Instance, Int, List,
Property, Str)
from traits.util.async_trait_wait import wait_for_condition

# Compatibility layer for Python 2.6: try loading unittest2
import sys
from traits import _py2to3
if sys.version_info[:2] == (2, 6):
import unittest2 as unittest
Expand Down Expand Up @@ -439,3 +440,26 @@ def assertEventuallyTrue(self, obj, trait, condition, timeout=5.0):
self.fail(
"Timed out waiting for condition. "
"At timeout, condition was {0}.".format(condition_at_timeout))

@contextlib.contextmanager
def assertDeprecated(self):
"""
Assert that the code inside the with block is deprecated. Intended
for testing uses of traits.util.deprecated.deprecated.
"""
# Ugly hack copied from the core Python code (see
# Lib/test/test_support.py) to reset the warnings registry
# for the module making use of this context manager.
#
# Note that this hack is unnecessary in Python 3.4 and later; see
# http://bugs.python.org/issue4180 for the background.
registry = sys._getframe(2).f_globals.get('__warningregistry__')
if registry:
registry.clear()

with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always', DeprecationWarning)
yield w
self.assertGreater(len(w), 0, msg="Expected a DeprecationWarning, "
"but none was issued")
37 changes: 15 additions & 22 deletions traits/util/deprecated.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
""" A decorator for marking methods/functions as deprecated. """
#------------------------------------------------------------------------------
# Copyright (c) 2005-2014, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in /LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
# Thanks for using Enthought open source!
#------------------------------------------------------------------------------

""" A decorator for marking methods/functions as deprecated. """

# Standard library imports.
import logging

# We only warn about each function or method once!
_cache = {}
import functools
import warnings


def deprecated(message):
Expand All @@ -16,28 +24,13 @@ def deprecated(message):
def decorator(fn):
""" A decorator for marking methods/functions as deprecated. """

@functools.wraps(fn)
def wrapper(*args, **kw):
""" The method/function wrapper. """

global _cache

module_name = fn.__module__
function_name = fn.__name__

if (module_name, function_name) not in _cache:
logging.getLogger(module_name).warning(
'DEPRECATED: %s.%s, %s' % (
module_name, function_name, message
)
)

_cache[(module_name, function_name)] = True

warnings.warn(message, DeprecationWarning, stacklevel=2)
return fn(*args, **kw)

wrapper.__doc__ = fn.__doc__
wrapper.__name__ = fn.__name__

return wrapper

return decorator
Expand Down

0 comments on commit 8246785

Please sign in to comment.