[PATCH 1 of 2 V2] util: add a way to issue deprecation warning without a UI object

Yuya Nishihara yuya at tcha.org
Thu Apr 6 09:58:24 EDT 2017


On Tue, 04 Apr 2017 11:58:49 +0200, Pierre-Yves David wrote:
> # 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 3992b843a7832bf23f2430dc2308907d1f5ba7f9
> # Parent  2632df096fc0ac7582382b1f94ea4b9ad0bce8f2
> # 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 3992b843a783
> 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)

Sorry for late reply, but can this DeprecationWarning really reach extension
authors who need the warning?

If dirty hack allowed, I would do something like the following:

  # util.py
  def _deprecwarn(msg, version):
      pass

  # somewhere ui is available, maybe in dispatch.py
  util._deprecwarn = ui.deprecwarn


More information about the Mercurial-devel mailing list