Deprecate Python 3.7 support
diff --git a/acme/acme/__init__.py b/acme/acme/__init__.py
index 1e21b589668..cd250b3caf0 100644
--- a/acme/acme/__init__.py
+++ b/acme/acme/__init__.py
@@ -6,6 +6,7 @@
 
 """
 import sys
+import warnings
 
 # This code exists to keep backwards compatibility with people using acme.jose
 # before it became the standalone josepy package.
@@ -19,3 +20,10 @@
     # preserved (acme.jose.* is josepy.*)
     if mod == 'josepy' or mod.startswith('josepy.'):
         sys.modules['acme.' + mod.replace('josepy', 'jose', 1)] = sys.modules[mod]
+
+if sys.version_info[:2] == (3, 7):
+    warnings.warn(
+            "Python 3.7 support will be dropped in the next planned release of "
+            "acme. Please upgrade your Python version.",
+            PendingDeprecationWarning,
+    )  # pragma: no cover
diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md
index 37fdef694af..20cc0fb251d 100644
--- a/certbot/CHANGELOG.md
+++ b/certbot/CHANGELOG.md
@@ -12,6 +12,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
 
 * `NamespaceConfig` now tracks how its arguments were set via a dictionary, allowing us to remove a bunch
   of global state previously needed to inspect whether a user set an argument or not.
+* Support for Python 3.7 was deprecated and will be removed in our next planned release.
 * Added `RENEWED_DOMAINS` and `FAILED_DOMAINS` environment variables for consumption by post renewal hooks.
 
 ### Fixed
diff --git a/certbot/certbot/__init__.py b/certbot/certbot/__init__.py
index 82ddadb759e..ff21c83e488 100644
--- a/certbot/certbot/__init__.py
+++ b/certbot/certbot/__init__.py
@@ -1,3 +1,13 @@
 """Certbot client."""
+import sys
+import warnings
+
 # version number like 1.2.3a0, must have at least 2 parts, like 1.2
 __version__ = '2.7.0.dev0'
+
+if sys.version_info[:2] == (3, 7):
+    warnings.warn(
+            "Python 3.7 support will be dropped in the next planned release of "
+            "certbot. Please upgrade your Python version.",
+            PendingDeprecationWarning,
+    )  # pragma: no cover
diff --git a/certbot/certbot/_internal/main.py b/certbot/certbot/_internal/main.py
index 70332e32c49..ef36261618f 100644
--- a/certbot/certbot/_internal/main.py
+++ b/certbot/certbot/_internal/main.py
@@ -1863,6 +1863,10 @@ def main(cli_args: Optional[List[str]] = None) -> Optional[Union[str, int]]:
         if config.func != plugins_cmd:  # pylint: disable=comparison-with-callable
             raise
 
+    if sys.version_info[:2] == (3, 7):
+        logger.warning("Python 3.7 support will be dropped in the next planned release "
+                       "of Certbot - please upgrade your Python version.")
+
     with make_displayer(config) as displayer:
         display_obj.set_display(displayer)
 
diff --git a/pytest.ini b/pytest.ini
index 047cf4a54d7..672e2c0542d 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -26,6 +26,7 @@
 #    It is also is used in sphinxcontrib-devhelp 1.0.2 which as of writing this
 #    is the latest version of that library. See
 #    https://github.com/sphinx-doc/sphinxcontrib-devhelp/blob/1.0.2/setup.py#L69.
+# 7) Ignore our own PendingDeprecationWarning about Python 3.7 soon to be dropped.
 filterwarnings =
     error
     ignore:decodestring\(\) is a deprecated alias:DeprecationWarning:dns
@@ -33,3 +34,4 @@ filterwarnings =
     ignore:'urllib3.contrib.pyopenssl:DeprecationWarning:requests_toolbelt
     ignore:update_symlinks is deprecated:PendingDeprecationWarning
     ignore:.*declare_namespace\(':DeprecationWarning
+    ignore:Python 3.7 support will be dropped:PendingDeprecationWarning

[Python 3.7 has reached its end of life](https://devguide.python.org/versions/).

This PR was based on #9160.