Spaces:
Runtime error
Runtime error
| """ | |
| 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 # NOTE: tests patch this name. | |
| 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], | |
| feature_flag: Optional[str] = None, | |
| issue: Optional[int] = None, | |
| ) -> None: | |
| """Helper to deprecate existing functionality. | |
| reason: | |
| Textual reason shown to the user about why this functionality has | |
| been deprecated. Should be a complete sentence. | |
| 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 an error if pip's current version is greater than or equal to | |
| this. | |
| feature_flag: | |
| Command-line flag of the form --use-feature={feature_flag} for testing | |
| upcoming functionality. | |
| issue: | |
| Issue number on the tracker that would serve as a useful place for | |
| users to find related discussion and provide feedback. | |
| """ | |
| # Determine whether or not the feature is already gone in this version. | |
| is_gone = gone_in is not None and parse(current_version) >= parse(gone_in) | |
| message_parts = [ | |
| (reason, f"{DEPRECATION_MSG_PREFIX}{{}}"), | |
| ( | |
| gone_in, | |
| "pip {} will enforce this behaviour change." | |
| if not is_gone | |
| else "Since pip {}, this is no longer supported.", | |
| ), | |
| ( | |
| replacement, | |
| "A possible replacement is {}.", | |
| ), | |
| ( | |
| feature_flag, | |
| "You can use the flag --use-feature={} to test the upcoming behaviour." | |
| if not is_gone | |
| else None, | |
| ), | |
| ( | |
| issue, | |
| "Discussion can be found at https://github.com/pypa/pip/issues/{}", | |
| ), | |
| ] | |
| message = " ".join( | |
| format_str.format(value) | |
| for value, format_str in message_parts | |
| if format_str is not None and value is not None | |
| ) | |
| # Raise as an error if this behaviour is deprecated. | |
| if is_gone: | |
| raise PipDeprecationWarning(message) | |
| warnings.warn(message, category=PipDeprecationWarning, stacklevel=2) | |