Patchwork [2,of,3] util: add a way to issue deprecation warning without a UI object

login
register
mail settings
Submitter Pierre-Yves David
Date April 3, 2017, 1:03 p.m.
Message ID <1f0d735dff0613a2dadc.1491224638@nodosa.octopoid.net>
Download mbox | patch
Permalink /patch/19930/
State Changes Requested
Headers show

Comments

Pierre-Yves David - April 3, 2017, 1:03 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@ens-lyon.org>
# Date 1491222955 -7200
#      Mon Apr 03 14:35:55 2017 +0200
# Node ID 1f0d735dff0613a2dadce85fbc396ef9306c0578
# Parent  e219af4bf3d4f6b7b3b634db1f7af8eaa524c4c1
# 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 1f0d735dff06
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 enable these warnings only during test run.
This will help us marker API as deprecated for extensions to update their code.

Patch

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('HGTESTRUNNING'))
+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/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, revset
+  > from mercurial import cmdutil, repair, revset, util
   > 
   > cmdtable = {}
   > command = cmdutil.command(cmdtable)
@@ -63,6 +63,10 @@ 
   >     return list(subset)
   > 
   > revset.symbols['oldstyle'] = oldstylerevset
+  > 
+  > @command('nouiwarning', [], '')
+  > def nouiwarning(ui, repo):
+  >     util.nouideprecwarn('this is a test', '13.37')
   > EOF
 
   $ cat << EOF >> $HGRCPATH
@@ -176,4 +180,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:67: 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)
+
+  $ HGTESTRUNNING= hg nouiwarning
+
   $ cd ..