You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
3.1 KiB
104 lines
3.1 KiB
""" |
|
A module that implements tooling to enable easy warnings about deprecations. |
|
""" |
|
|
|
import logging |
|
import warnings |
|
from typing import Any, Optional, TextIO, Type, Union |
|
|
|
from pip._vendor.packaging.version import parse |
|
|
|
from pip import __version__ as current_version |
|
|
|
DEPRECATION_MSG_PREFIX = "DEPRECATION: " |
|
|
|
|
|
class PipDeprecationWarning(Warning): |
|
pass |
|
|
|
|
|
_original_showwarning: Any = None |
|
|
|
|
|
# Warnings <-> Logging Integration |
|
def _showwarning( |
|
message: Union[Warning, str], |
|
category: Type[Warning], |
|
filename: str, |
|
lineno: int, |
|
file: Optional[TextIO] = None, |
|
line: Optional[str] = None, |
|
) -> None: |
|
if file is not None: |
|
if _original_showwarning is not None: |
|
_original_showwarning(message, category, filename, lineno, file, line) |
|
elif issubclass(category, PipDeprecationWarning): |
|
# We use a specially named logger which will handle all of the |
|
# deprecation messages for pip. |
|
logger = logging.getLogger("pip._internal.deprecations") |
|
logger.warning(message) |
|
else: |
|
_original_showwarning(message, category, filename, lineno, file, line) |
|
|
|
|
|
def install_warning_logger() -> None: |
|
# Enable our Deprecation Warnings |
|
warnings.simplefilter("default", PipDeprecationWarning, append=True) |
|
|
|
global _original_showwarning |
|
|
|
if _original_showwarning is None: |
|
_original_showwarning = warnings.showwarning |
|
warnings.showwarning = _showwarning |
|
|
|
|
|
def deprecated( |
|
reason: str, |
|
replacement: Optional[str], |
|
gone_in: Optional[str], |
|
issue: Optional[int] = None, |
|
) -> None: |
|
"""Helper to deprecate existing functionality. |
|
|
|
reason: |
|
Textual reason shown to the user about why this functionality has |
|
been deprecated. |
|
replacement: |
|
Textual suggestion shown to the user about what alternative |
|
functionality they can use. |
|
gone_in: |
|
The version of pip does this functionality should get removed in. |
|
Raises errors if pip's current version is greater than or equal to |
|
this. |
|
issue: |
|
Issue number on the tracker that would serve as a useful place for |
|
users to find related discussion and provide feedback. |
|
|
|
Always pass replacement, gone_in and issue as keyword arguments for clarity |
|
at the call site. |
|
""" |
|
|
|
# Construct a nice message. |
|
# This is eagerly formatted as we want it to get logged as if someone |
|
# typed this entire message out. |
|
sentences = [ |
|
(reason, DEPRECATION_MSG_PREFIX + "{}"), |
|
(gone_in, "pip {} will remove support for this functionality."), |
|
(replacement, "A possible replacement is {}."), |
|
( |
|
issue, |
|
( |
|
"You can find discussion regarding this at " |
|
"https://github.com/pypa/pip/issues/{}." |
|
), |
|
), |
|
] |
|
message = " ".join( |
|
template.format(val) for val, template in sentences if val is not None |
|
) |
|
|
|
# Raise as an error if it has to be removed. |
|
if gone_in is not None and parse(current_version) >= parse(gone_in): |
|
raise PipDeprecationWarning(message) |
|
|
|
warnings.warn(message, category=PipDeprecationWarning, stacklevel=2)
|
|
|