[PATCH 1 of 2 V3] util: add a way to issue deprecation warning without a UI object
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Thu Apr 13 14:53:31 UTC 2017
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
# Date 1491296609 -7200
# Tue Apr 04 11:03:29 2017 +0200
# Node ID a86a1d8576c062dc6a95a7d02c886f9cf798d65e
# Parent 2bf73e351eb1bb086e30c9f58543817fb05e558c
# EXP-Topic vfs.cleanup
# Available At https://www.mercurial-scm.org/repo/users/marmoute/mercurial/
# hg pull https://www.mercurial-scm.org/repo/users/marmoute/mercurial/ -r a86a1d8576c0
util: add a way to issue deprecation warning without a UI object
Our current deprecation warning mechanism rely 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.
diff --git a/mercurial/util.py b/mercurial/util.py
--- 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 (
@@ -155,6 +156,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
--- 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
--- 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 ..
More information about the Mercurial-devel
mailing list