From a18596089762eb2e8df0fe17f9e5b5772ac1f1fb Mon Sep 17 00:00:00 2001 From: Pierre-Yves David Date: Tue, 4 Apr 2017 11:03:29 +0200 Subject: [PATCH] util: add a way to issue deprecation warning without a UI object Our current deprecation warning mechanism relies on ui object. They are case where we cannot have access to the UI object. On a general basis we avoid using the python mechanism for deprecation warning because up to Python 2.6 it is exposing warning to unsuspecting user who cannot do anything to deal with them. So we build a "safe" strategy to hide this warnings behind a flag in an environment variable. The test runner set this flag so that tests show these warning. This will help us marker API as deprecated for extensions to update their code. --- mercurial/util.py | 26 ++++++++++++++++++++++++++ tests/run-tests.py | 1 + tests/test-devel-warnings.t | 16 +++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/mercurial/util.py b/mercurial/util.py index 1c4dd5d3cc..453d583978 100644 --- a/mercurial/util.py +++ b/mercurial/util.py @@ -38,6 +38,7 @@ import tempfile import textwrap import time import traceback +import warnings import zlib from . import ( @@ -156,6 +157,31 @@ def bitsfrom(container): bits |= bit return bits +# python 2.6 still have deprecation warning enabled by default. We do not want +# to display anything to standard user so detect if we are running test and +# only use python deprecation warning in this case. +_dowarn = bool(encoding.environ.get('HGEMITWARNINGS')) +if _dowarn: + # explicitly unfilter our warning for python 2.7 + # + # The option of setting PYTHONWARNINGS in the test runner was investigated. + # However, module name set through PYTHONWARNINGS was exactly matched, so + # we cannot set 'mercurial' and have it match eg: 'mercurial.scmutil'. This + # makes the whole PYTHONWARNINGS thing useless for our usecase. + warnings.filterwarnings('default', '', DeprecationWarning, 'mercurial') + warnings.filterwarnings('default', '', DeprecationWarning, 'hgext') + warnings.filterwarnings('default', '', DeprecationWarning, 'hgext3rd') + +def nouideprecwarn(msg, version, stacklevel=1): + """Issue an python native deprecation warning + + This is a noop outside of tests, use 'ui.deprecwarn' when possible. + """ + if _dowarn: + msg += ("\n(compatibility will be dropped after Mercurial-%s," + " update your code.)") % version + warnings.warn(msg, DeprecationWarning, stacklevel + 1) + DIGESTS = { 'md5': hashlib.md5, 'sha1': hashlib.sha1, diff --git a/tests/run-tests.py b/tests/run-tests.py index 59c8799d78..6ef6a3b666 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -884,6 +884,7 @@ class Test(unittest.TestCase): env = os.environ.copy() if sysconfig is not None: env['PYTHONUSERBASE'] = sysconfig.get_config_var('userbase') + env['HGEMITWARNINGS'] = '1' env['TESTTMP'] = self._testtmp env['HOME'] = self._testtmp # This number should match portneeded in _getport diff --git a/tests/test-devel-warnings.t b/tests/test-devel-warnings.t index 54aca6ff38..70792ee67b 100644 --- a/tests/test-devel-warnings.t +++ b/tests/test-devel-warnings.t @@ -3,7 +3,7 @@ > """A small extension that tests our developer warnings > """ > - > from mercurial import cmdutil, repair + > from mercurial import cmdutil, repair, util > > cmdtable = {} > command = cmdutil.command(cmdtable) @@ -58,6 +58,9 @@ > def foobar(ui): > ui.deprecwarn('foorbar is deprecated, go shopping', '42.1337') > foobar(ui) + > @command('nouiwarning', [], '') + > def nouiwarning(ui, repo): + > util.nouideprecwarn('this is a test', '13.37') > EOF $ cat << EOF >> $HGRCPATH @@ -163,4 +166,15 @@ Test programming error failure: Traceback (most recent call last): mercurial.error.ProgrammingError: transaction requires locking +Old style deprecation warning + + $ hg nouiwarning + $TESTTMP/buggylocking.py:61: DeprecationWarning: this is a test + (compatibility will be dropped after Mercurial-13.37, update your code.) + util.nouideprecwarn('this is a test', '13.37') + +(disabled outside of test run) + + $ HGEMITWARNINGS= hg nouiwarning + $ cd ..