summaryrefslogtreecommitdiffstats
path: root/third_party/python/setuptools/setuptools/warnings.py
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/python/setuptools/setuptools/warnings.py')
-rw-r--r--third_party/python/setuptools/setuptools/warnings.py104
1 files changed, 104 insertions, 0 deletions
diff --git a/third_party/python/setuptools/setuptools/warnings.py b/third_party/python/setuptools/setuptools/warnings.py
new file mode 100644
index 0000000000..4ea782e509
--- /dev/null
+++ b/third_party/python/setuptools/setuptools/warnings.py
@@ -0,0 +1,104 @@
+"""Provide basic warnings used by setuptools modules.
+
+Using custom classes (other than ``UserWarning``) allow users to set
+``PYTHONWARNINGS`` filters to run tests and prepare for upcoming changes in
+setuptools.
+"""
+
+import os
+import warnings
+from datetime import date
+from inspect import cleandoc
+from textwrap import indent
+from typing import Optional, Tuple
+
+_DueDate = Tuple[int, int, int] # time tuple
+_INDENT = 8 * " "
+_TEMPLATE = f"""{80 * '*'}\n{{details}}\n{80 * '*'}"""
+
+
+class SetuptoolsWarning(UserWarning):
+ """Base class in ``setuptools`` warning hierarchy."""
+
+ @classmethod
+ def emit(
+ cls,
+ summary: Optional[str] = None,
+ details: Optional[str] = None,
+ due_date: Optional[_DueDate] = None,
+ see_docs: Optional[str] = None,
+ see_url: Optional[str] = None,
+ stacklevel: int = 2,
+ **kwargs
+ ):
+ """Private: reserved for ``setuptools`` internal use only"""
+ # Default values:
+ summary_ = summary or getattr(cls, "_SUMMARY", None) or ""
+ details_ = details or getattr(cls, "_DETAILS", None) or ""
+ due_date = due_date or getattr(cls, "_DUE_DATE", None)
+ docs_ref = see_docs or getattr(cls, "_SEE_DOCS", None)
+ docs_url = docs_ref and f"https://setuptools.pypa.io/en/latest/{docs_ref}"
+ see_url = see_url or getattr(cls, "_SEE_URL", None)
+ due = date(*due_date) if due_date else None
+
+ text = cls._format(summary_, details_, due, see_url or docs_url, kwargs)
+ if due and due < date.today() and _should_enforce():
+ raise cls(text)
+ warnings.warn(text, cls, stacklevel=stacklevel + 1)
+
+ @classmethod
+ def _format(
+ cls,
+ summary: str,
+ details: str,
+ due_date: Optional[date] = None,
+ see_url: Optional[str] = None,
+ format_args: Optional[dict] = None,
+ ):
+ """Private: reserved for ``setuptools`` internal use only"""
+ today = date.today()
+ summary = cleandoc(summary).format_map(format_args or {})
+ possible_parts = [
+ cleandoc(details).format_map(format_args or {}),
+ (
+ f"\nBy {due_date:%Y-%b-%d}, you need to update your project and remove "
+ "deprecated calls\nor your builds will no longer be supported."
+ if due_date and due_date > today else None
+ ),
+ (
+ "\nThis deprecation is overdue, please update your project and remove "
+ "deprecated\ncalls to avoid build errors in the future."
+ if due_date and due_date < today else None
+ ),
+ (f"\nSee {see_url} for details." if see_url else None)
+
+ ]
+ parts = [x for x in possible_parts if x]
+ if parts:
+ body = indent(_TEMPLATE.format(details="\n".join(parts)), _INDENT)
+ return "\n".join([summary, "!!\n", body, "\n!!"])
+ return summary
+
+
+class InformationOnly(SetuptoolsWarning):
+ """Currently there is no clear way of displaying messages to the users
+ that use the setuptools backend directly via ``pip``.
+ The only thing that might work is a warning, although it is not the
+ most appropriate tool for the job...
+
+ See pypa/packaging-problems#558.
+ """
+
+
+class SetuptoolsDeprecationWarning(SetuptoolsWarning):
+ """
+ Base class for warning deprecations in ``setuptools``
+
+ This class is not derived from ``DeprecationWarning``, and as such is
+ visible by default.
+ """
+
+
+def _should_enforce():
+ enforce = os.getenv("SETUPTOOLS_ENFORCE_DEPRECATION", "false").lower()
+ return enforce in ("true", "on", "ok", "1")