Make mypy pass on our tests
diff --git a/certbot-apache/certbot_apache/_internal/tests/apache-conf-files/apache-conf-test-pebble.py b/certbot-apache/certbot_apache/_internal/tests/apache-conf-files/apache-conf-test-pebble.py
index 68bd6287d75..383c652f8cf 100755
--- a/certbot-apache/certbot_apache/_internal/tests/apache-conf-files/apache-conf-test-pebble.py
+++ b/certbot-apache/certbot_apache/_internal/tests/apache-conf-files/apache-conf-test-pebble.py
@@ -12,9 +12,8 @@
 SCRIPT_DIRNAME = os.path.dirname(__file__)
 
 
-def main(args=None):
-    if not args:
-        args = sys.argv[1:]
+def main() -> int:
+    args = sys.argv[1:]
     with acme_server.ACMEServer('pebble', [], False) as acme_xdist:
         environ = os.environ.copy()
         environ['SERVER'] = acme_xdist['directory_url']
diff --git a/certbot-nginx/certbot_nginx/_internal/parser_obj.py b/certbot-nginx/certbot_nginx/_internal/parser_obj.py
index 0af38a9360a..7a094650015 100644
--- a/certbot-nginx/certbot_nginx/_internal/parser_obj.py
+++ b/certbot-nginx/certbot_nginx/_internal/parser_obj.py
@@ -1,5 +1,6 @@
 # type: ignore
-# This module is not used for now, so we just skip type check for the sake of simplicity.
+# This module is not used for now, so we just skip type checking for the sake
+# of simplicity.
 """ This file contains parsing routines and object classes to help derive meaning from
 raw lists of tokens from pyparsing. """
 
diff --git a/certbot-nginx/certbot_nginx/_internal/tests/http_01_test.py b/certbot-nginx/certbot_nginx/_internal/tests/http_01_test.py
index 6726b85ad2e..c81357607d0 100644
--- a/certbot-nginx/certbot_nginx/_internal/tests/http_01_test.py
+++ b/certbot-nginx/certbot_nginx/_internal/tests/http_01_test.py
@@ -7,6 +7,7 @@
 import pytest
 
 from acme import challenges
+from acme import messages
 from certbot import achallenges
 from certbot.tests import acme_util
 from certbot.tests import util as test_util
@@ -23,29 +24,29 @@ class HttpPerformTest(util.NginxTest):
     achalls = [
         achallenges.KeyAuthorizationAnnotatedChallenge(
             challb=acme_util.chall_to_challb(
-                challenges.HTTP01(token=b"kNdwjwOeX0I_A8DXt9Msmg"), "pending"),
+                challenges.HTTP01(token=b"kNdwjwOeX0I_A8DXt9Msmg"), messages.STATUS_PENDING),
             domain="www.example.com", account_key=account_key),
         achallenges.KeyAuthorizationAnnotatedChallenge(
             challb=acme_util.chall_to_challb(
                 challenges.HTTP01(
                     token=b"\xba\xa9\xda?<m\xaewmx\xea\xad\xadv\xf4\x02\xc9y"
                           b"\x80\xe2_X\t\xe7\xc7\xa4\t\xca\xf7&\x945"
-                ), "pending"),
+                ), messages.STATUS_PENDING),
             domain="ipv6.com", account_key=account_key),
         achallenges.KeyAuthorizationAnnotatedChallenge(
             challb=acme_util.chall_to_challb(
                 challenges.HTTP01(
                     token=b"\x8c\x8a\xbf_-f\\cw\xee\xd6\xf8/\xa5\xe3\xfd"
                           b"\xeb9\xf1\xf5\xb9\xefVM\xc9w\xa4u\x9c\xe1\x87\xb4"
-                ), "pending"),
+                ), messages.STATUS_PENDING),
             domain="www.example.org", account_key=account_key),
         achallenges.KeyAuthorizationAnnotatedChallenge(
             challb=acme_util.chall_to_challb(
-                challenges.HTTP01(token=b"kNdwjxOeX0I_A8DXt9Msmg"), "pending"),
+                challenges.HTTP01(token=b"kNdwjxOeX0I_A8DXt9Msmg"), messages.STATUS_PENDING),
             domain="migration.com", account_key=account_key),
         achallenges.KeyAuthorizationAnnotatedChallenge(
             challb=acme_util.chall_to_challb(
-                challenges.HTTP01(token=b"kNdwjxOeX0I_A8DXt9Msmg"), "pending"),
+                challenges.HTTP01(token=b"kNdwjxOeX0I_A8DXt9Msmg"), messages.STATUS_PENDING),
             domain="ipv6ssl.com", account_key=account_key),
     ]
 
@@ -137,7 +138,7 @@ def test_mod_config_deduplicate(self, mock_add_server_directives):
         """A vhost that appears in both HTTP and HTTPS vhosts only gets modded once"""
         achall = achallenges.KeyAuthorizationAnnotatedChallenge(
             challb=acme_util.chall_to_challb(
-                challenges.HTTP01(token=b"kNdwjxOeX0I_A8DXt9Msmg"), "pending"),
+                challenges.HTTP01(token=b"kNdwjxOeX0I_A8DXt9Msmg"), messages.STATUS_PENDING),
             domain="ssl.both.com", account_key=AUTH_KEY)
         self.http01.add_chall(achall)
         self.http01._mod_config() # pylint: disable=protected-access
diff --git a/certbot-nginx/certbot_nginx/_internal/tests/parser_obj_test.py b/certbot-nginx/certbot_nginx/_internal/tests/parser_obj_test.py
index 7503897cc67..710b63fc4be 100644
--- a/certbot-nginx/certbot_nginx/_internal/tests/parser_obj_test.py
+++ b/certbot-nginx/certbot_nginx/_internal/tests/parser_obj_test.py
@@ -1,3 +1,6 @@
+# type: ignore
+# As done in parser_obj.py, this module is not used for now, so we just skip
+# type checking for the sake of simplicity.
 """ Tests for functions and classes in parser_obj.py """
 
 import sys
diff --git a/certbot/certbot/_internal/tests/plugins/common_test.py b/certbot/certbot/_internal/tests/plugins/common_test.py
index 4a0af7c5e29..8c5b260319b 100644
--- a/certbot/certbot/_internal/tests/plugins/common_test.py
+++ b/certbot/certbot/_internal/tests/plugins/common_test.py
@@ -9,6 +9,7 @@
 import pytest
 
 from acme import challenges
+from acme import messages
 from certbot import achallenges
 from certbot import crypto_util
 from certbot import errors
@@ -20,7 +21,7 @@
 AUTH_KEY = jose.JWKRSA.load(test_util.load_vector("rsa512_key.pem"))
 ACHALL = achallenges.KeyAuthorizationAnnotatedChallenge(
             challb=acme_util.chall_to_challb(challenges.HTTP01(token=b'token1'),
-                                             "pending"),
+                                             messages.STATUS_PENDING),
             domain="encryption-example.demo", account_key=AUTH_KEY)
 
 
@@ -51,7 +52,7 @@ def prepare(self) -> None:
                 pass
 
             def more_info(self) -> str:
-                pass
+                return "info"
 
             @classmethod
             def add_parser_arguments(cls, add):
diff --git a/certbot/certbot/_internal/tests/util_test.py b/certbot/certbot/_internal/tests/util_test.py
index ac3b5ab888f..b4256176e14 100644
--- a/certbot/certbot/_internal/tests/util_test.py
+++ b/certbot/certbot/_internal/tests/util_test.py
@@ -247,13 +247,6 @@ def test_default_exists(self):
         fd3.close()
 
 
-try:
-    file_type = file
-except NameError:
-    import io
-    file_type = io.TextIOWrapper  # type: ignore
-
-
 class UniqueLineageNameTest(test_util.TempDirTestCase):
     """Tests for certbot.util.unique_lineage_name."""
 
@@ -263,7 +256,7 @@ def _call(self, filename, mode=0o777):
 
     def test_basic(self):
         f, path = self._call("wow")
-        assert isinstance(f, file_type)
+        assert isinstance(f, io.TextIOWrapper)
         assert os.path.join(self.tempdir, "wow.conf") == path
         f.close()
 
@@ -272,7 +265,7 @@ def test_multiple(self):
         for _ in range(10):
             items.append(self._call("wow"))
         f, name = items[-1]
-        assert isinstance(f, file_type)
+        assert isinstance(f, io.TextIOWrapper)
         assert isinstance(name, str)
         assert "wow-0009.conf" in name
         for f, _ in items:
diff --git a/mypy.ini b/mypy.ini
index 6c01929d4ec..2c9ba518764 100644
--- a/mypy.ini
+++ b/mypy.ini
@@ -1,8 +1,14 @@
 [mypy]
-# Removing this exclude setting is being tracked by
-# https://github.com/certbot/certbot/issues/7909.
-exclude = .*/_internal/tests/
 ignore_missing_imports = True
 warn_unused_ignores = True
 show_error_codes = True
 disallow_untyped_defs = True
+
+# Using stricter settings here is being tracked by
+# https://github.com/certbot/certbot/issues/9647.
+[mypy-*._internal.tests.*]
+# By default, mypy prints notes without erroring about any type annotations it
+# finds in untyped function bodies when check_untyped_defs is false. Disabling
+# this "error" code removes this visual noise.
+disable_error_code = annotation-unchecked
+disallow_untyped_defs = False

Fixes https://github.com/certbot/certbot/issues/7909 after opening https://github.com/certbot/certbot/issues/9647.

This approach to getting a very small subset of mypy's tests passing on existing code is suggested in the mypy docs at https://mypy.readthedocs.io/en/stable/existing_code.html#start-small.