summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2023-01-02 12:27:36 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2023-01-02 15:00:41 -0500
commit4f7b6a095590e1216c44935e7a7ba725733ca8d5 (patch)
tree088e1be289f2e132c7b92bf4df0dc373f7cc86c2
parent532373b18f2e77910bb642a27a2cca3179499389 (diff)
downloadsqlalchemy-4f7b6a095590e1216c44935e7a7ba725733ca8d5.tar.gz
add uber warning for 1.4
As we don't have any automatic deprecation warning for 2.0 unless SQLALCHEMY_WARN_20 is set, applications that are not being monitored for deprecations have no way to guard against 2.0 being released on pypi unless they add a requirements rule. make sure we are putting out a major warning for people who may have not noticed that SQLAlchemy 2.0 will break compatibility with legacy use patterns. Fixes: #8983 Change-Id: I7d50db52c9a0fe3165b0131aab2fce9af80d51dd
-rw-r--r--lib/sqlalchemy/testing/profiling.py2
-rw-r--r--lib/sqlalchemy/util/deprecations.py66
2 files changed, 68 insertions, 0 deletions
diff --git a/lib/sqlalchemy/testing/profiling.py b/lib/sqlalchemy/testing/profiling.py
index 41326303a..8c4d9a484 100644
--- a/lib/sqlalchemy/testing/profiling.py
+++ b/lib/sqlalchemy/testing/profiling.py
@@ -252,6 +252,8 @@ def function_call_count(variance=0.05, times=1, warmup=0):
with mock.patch.object(
deprecations, "SQLALCHEMY_WARN_20", False
), mock.patch.object(
+ deprecations, "SILENCE_UBER_WARNING", True
+ ), mock.patch.object(
row.LegacyRow, "_default_key_style", row.KEY_OBJECTS_NO_WARN
):
for warm in range(warmup):
diff --git a/lib/sqlalchemy/util/deprecations.py b/lib/sqlalchemy/util/deprecations.py
index b61516d85..ca346ee0e 100644
--- a/lib/sqlalchemy/util/deprecations.py
+++ b/lib/sqlalchemy/util/deprecations.py
@@ -10,6 +10,7 @@ functionality."""
import os
import re
+import sys
from . import compat
from .langhelpers import _hash_limit_string
@@ -22,15 +23,29 @@ from .. import exc
SQLALCHEMY_WARN_20 = False
+SILENCE_UBER_WARNING = False
+
if os.getenv("SQLALCHEMY_WARN_20", "false").lower() in ("true", "yes", "1"):
SQLALCHEMY_WARN_20 = True
+if compat.py2k:
+ SILENCE_UBER_WARNING = True
+elif os.getenv("SQLALCHEMY_SILENCE_UBER_WARNING", "false").lower() in (
+ "true",
+ "yes",
+ "1",
+):
+ SILENCE_UBER_WARNING = True
+
def _warn_with_version(msg, version, type_, stacklevel, code=None):
if (
issubclass(type_, exc.Base20DeprecationWarning)
and not SQLALCHEMY_WARN_20
):
+ if not SILENCE_UBER_WARNING:
+ _emit_uber_warning(type_, stacklevel)
+
return
warn = type_(msg, code=code)
@@ -39,6 +54,57 @@ def _warn_with_version(msg, version, type_, stacklevel, code=None):
_warnings_warn(warn, stacklevel=stacklevel + 1)
+def _emit_uber_warning(type_, stacklevel):
+ global SILENCE_UBER_WARNING
+
+ if SILENCE_UBER_WARNING:
+ return
+
+ SILENCE_UBER_WARNING = True
+
+ file_ = sys.stderr
+
+ # source: https://github.com/pytest-dev/pytest/blob/326ae0cd88f5e954c8effc2b0c986832e9caff11/src/_pytest/_io/terminalwriter.py#L35-L37 # noqa: E501
+ use_color = (
+ hasattr(file_, "isatty")
+ and file_.isatty()
+ and os.environ.get("TERM") != "dumb"
+ )
+
+ msg = (
+ "%(red)sDeprecated API features detected! "
+ "These feature(s) are not compatible with SQLAlchemy 2.0. "
+ "%(green)sTo prevent incompatible upgrades prior to updating "
+ "applications, ensure requirements files are "
+ 'pinned to "sqlalchemy<2.0". '
+ "%(cyan)sSet environment variable SQLALCHEMY_WARN_20=1 to show all "
+ "deprecation warnings. Set environment variable "
+ "SQLALCHEMY_SILENCE_UBER_WARNING=1 to silence this message.%(nocolor)s"
+ )
+
+ if use_color:
+ msg = msg % {
+ "red": "\x1b[31m",
+ "cyan": "\x1b[36m",
+ "green": "\x1b[32m",
+ "magenta": "\x1b[35m",
+ "nocolor": "\x1b[0m",
+ }
+ else:
+ msg = msg % {
+ "red": "",
+ "cyan": "",
+ "green": "",
+ "magenta": "",
+ "nocolor": "",
+ }
+
+ # note this is a exc.Base20DeprecationWarning subclass, which
+ # will implicitly add the link to the SQLAlchemy 2.0 page in the message
+ warn = type_(msg)
+ _warnings_warn(warn, stacklevel=stacklevel + 1)
+
+
def warn_deprecated(msg, version, stacklevel=3, code=None):
_warn_with_version(
msg, version, exc.SADeprecationWarning, stacklevel, code=code