Emit a DeprecationWarning rather than log a message

When used as a library we really don't know how logging will be
configured in the calling application so we shouldn't be logging our own
messages. Instead the standard way to signal deprecation is via a
DeprecationWarning.

Change the WARN enforcement to emit a warning instead of logging.

Resolves: #1
This commit is contained in:
Jamie Lennox 2016-01-14 12:25:04 +11:00
parent 6cf6726813
commit fc43875e6d
4 changed files with 13 additions and 23 deletions

@ -126,8 +126,8 @@ This behaviour will work with the `positional.method` and
>>> MyClass.my_method(10, kwonly1=20) # Ok.
For compatibility reasons you may wish to not always raise an exception so
a WARN mode is available. Rather than raise an exception a warning message
will be logged:
a WARN mode is available. Rather than raise an exception a warning will be
emitted.
.. code:: python
@ -138,7 +138,7 @@ will be logged:
Available modes are:
- positional.EXCEPT - the default, raise an exception.
- positional.WARN - log a warning on mistake.
- positional.WARN - emit a warning.
.. |Build Status| image:: https://travis-ci.org/morganfainberg/positional.svg?branch=master

@ -12,12 +12,11 @@
import functools
import inspect
import logging
import warnings
import pbr.version
__version__ = pbr.version.VersionInfo('python-keystoneclient').version_string()
_logger = logging.getLogger(__name__)
class positional(object):
@ -43,7 +42,7 @@ class positional(object):
:param enforcement: defines the way incorrect usage is reported. Currenlty
accepts :py:attr:`positional.EXCEPT` to raise a TypeError or
:py:attr:`positional.WARN` to print a warning. A warning can be useful
:py:attr:`positional.WARN` to show a warning. A warning can be useful
for applying to functions that are already public as a deprecation
notice. Defaults to :py:attr:`positional.EXCEPT`.
"""
@ -90,7 +89,7 @@ class positional(object):
if self._enforcement == self.EXCEPT:
raise TypeError(message)
elif self._enforcement == self.WARN:
_logger.warning(message)
warnings.warn(message, DeprecationWarning, stacklevel=2)
return func(*args, **kwargs)

@ -10,9 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import logging
import warnings
import six
import testtools
from positional import positional
@ -46,21 +45,15 @@ class TestPositional(testtools.TestCase):
self.assertRaises(TypeError, self.mixed_except, 1, 2, 3)
def test_mixed_warn(self):
logger_message = six.moves.cStringIO()
handler = logging.StreamHandler(logger_message)
handler.setLevel(logging.DEBUG)
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
logger = logging.getLogger(positional.__name__)
level = logger.getEffectiveLevel()
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
self.mixed_warn(1, 2, 3)
self.addCleanup(logger.removeHandler, handler)
self.addCleanup(logger.setLevel, level)
self.assertEqual(1, len(w))
self.mixed_warn(1, 2, 3)
self.assertIn('takes at most 3 positional', logger_message.getvalue())
self.assertTrue(issubclass(w[0].category, DeprecationWarning))
self.assertIn('takes at most 3 positional', str(w[0].message))
@positional(enforcement=positional.EXCEPT)
def inspect_func(self, arg, kwarg=None):

@ -2,5 +2,3 @@
# of appearance.
pbr>=1.6
six>=1.9.0