We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Fix lint and mypy with Python < 3.8
In https://github.com/certbot/certbot/pull/8748, we made a change that causes our lint and mypy tests to need to be run on Python 3.8+ to pass. See https://github.com/certbot/certbot/pull/8748#issuecomment-808790093 for the discussion of the problem here.

I don't think we should do this. Certbot supports Python 3.6+ and I think it could cause a particularly bad experience for new devs that don't happen to know they need Python 3.8+. This change also broke our development Dockerfile as can be seen at https://dev.azure.com/certbot/certbot/_build/results?buildId=3742&view=logs&j=bea2d267-f41e-5b33-7b51-a88065a8cbb0&t=0dc90756-6888-5ee6-5a6a-5855e6b9ae76&l=1873. Instead, I think we should change our approach here so the tests work on all versions of Python we support. I'm open to other ideas, but the two ideas I had for this are:

1. Just declare a runtime dependency on `typing-extensions`.
2. Add `typing-extensions` as a dev/test dependency and try to import it, but use similar fallback code to what we current have if it's not available.

What do you think @adferrand? Are you interested in working on this?

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `certbot/setup.py`
Content:
```
1 import codecs
2 from distutils.version import LooseVersion
3 import os
4 import re
5 import sys
6 
7 from setuptools import __version__ as setuptools_version
8 from setuptools import find_packages
9 from setuptools import setup
10 
11 min_setuptools_version='39.0.1'
12 # This conditional isn't necessary, but it provides better error messages to
13 # people who try to install this package with older versions of setuptools.
14 if LooseVersion(setuptools_version) < LooseVersion(min_setuptools_version):
15     raise RuntimeError(f'setuptools {min_setuptools_version}+ is required')
16 
17 # Workaround for https://bugs.python.org/issue8876, see
18 # https://bugs.python.org/issue8876#msg208792
19 # This can be removed when using Python 2.7.9 or later:
20 # https://hg.python.org/cpython/raw-file/v2.7.9/Misc/NEWS
21 if os.path.abspath(__file__).split(os.path.sep)[1] == 'vagrant':
22     del os.link
23 
24 
25 def read_file(filename, encoding='utf8'):
26     """Read unicode from given file."""
27     with codecs.open(filename, encoding=encoding) as fd:
28         return fd.read()
29 
30 
31 here = os.path.abspath(os.path.dirname(__file__))
32 
33 # read version number (and other metadata) from package init
34 init_fn = os.path.join(here, 'certbot', '__init__.py')
35 meta = dict(re.findall(r"""__([a-z]+)__ = '([^']+)""", read_file(init_fn)))
36 
37 readme = read_file(os.path.join(here, 'README.rst'))
38 version = meta['version']
39 
40 # This package relies on PyOpenSSL and requests, however, it isn't specified
41 # here to avoid masking the more specific request requirements in acme. See
42 # https://github.com/pypa/pip/issues/988 for more info.
43 install_requires = [
44     'acme>=1.8.0',
45     # We technically need ConfigArgParse 0.10.0 for Python 2.6 support, but
46     # saying so here causes a runtime error against our temporary fork of 0.9.3
47     # in which we added 2.6 support (see #2243), so we relax the requirement.
48     'ConfigArgParse>=0.9.3',
49     'configobj>=5.0.6',
50     'cryptography>=2.1.4',
51     'distro>=1.0.1',
52     # 1.1.0+ is required to avoid the warnings described at
53     # https://github.com/certbot/josepy/issues/13.
54     'josepy>=1.1.0',
55     'parsedatetime>=2.4',
56     'pyrfc3339',
57     'pytz',
58     # This dependency needs to be added using environment markers to avoid its
59     # installation on Linux.
60     'pywin32>=300 ; sys_platform == "win32"',
61     f'setuptools>={min_setuptools_version}',
62     'zope.component',
63     'zope.interface',
64 ]
65 
66 dev_extras = [
67     'astroid',
68     'azure-devops',
69     'coverage',
70     'ipdb',
71     'mypy',
72     'PyGithub',
73     # 1.1.0+ is required for poetry to use the poetry-core library for the
74     # build system declared in tools/pinning/pyproject.toml.
75     'poetry>=1.1.0',
76     'pylint',
77     'pytest',
78     'pytest-cov',
79     'pytest-xdist',
80     'tox',
81     'twine',
82     'wheel',
83 ]
84 
85 docs_extras = [
86     # If you have Sphinx<1.5.1, you need docutils<0.13.1
87     # https://github.com/sphinx-doc/sphinx/issues/3212
88     'repoze.sphinx.autointerface',
89     'Sphinx>=1.2', # Annotation support
90     'sphinx_rtd_theme',
91 ]
92 
93 setup(
94     name='certbot',
95     version=version,
96     description="ACME client",
97     long_description=readme,
98     url='https://github.com/letsencrypt/letsencrypt',
99     author="Certbot Project",
100     author_email='client-dev@letsencrypt.org',
101     license='Apache License 2.0',
102     python_requires='>=3.6',
103     classifiers=[
104         'Development Status :: 5 - Production/Stable',
105         'Environment :: Console',
106         'Environment :: Console :: Curses',
107         'Intended Audience :: System Administrators',
108         'License :: OSI Approved :: Apache Software License',
109         'Operating System :: POSIX :: Linux',
110         'Programming Language :: Python',
111         'Programming Language :: Python :: 3',
112         'Programming Language :: Python :: 3.6',
113         'Programming Language :: Python :: 3.7',
114         'Programming Language :: Python :: 3.8',
115         'Programming Language :: Python :: 3.9',
116         'Topic :: Internet :: WWW/HTTP',
117         'Topic :: Security',
118         'Topic :: System :: Installation/Setup',
119         'Topic :: System :: Networking',
120         'Topic :: System :: Systems Administration',
121         'Topic :: Utilities',
122     ],
123 
124     packages=find_packages(exclude=['docs', 'examples', 'tests', 'venv']),
125     include_package_data=True,
126 
127     install_requires=install_requires,
128     extras_require={
129         'dev': dev_extras,
130         'docs': docs_extras,
131     },
132 
133     entry_points={
134         'console_scripts': [
135             'certbot = certbot.main:main',
136         ],
137         'certbot.plugins': [
138             'manual = certbot._internal.plugins.manual:Authenticator',
139             'null = certbot._internal.plugins.null:Installer',
140             'standalone = certbot._internal.plugins.standalone:Authenticator',
141             'webroot = certbot._internal.plugins.webroot:Authenticator',
142         ],
143     },
144 )
145
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/certbot/setup.py b/certbot/setup.py
--- a/certbot/setup.py
+++ b/certbot/setup.py
@@ -77,6 +77,9 @@
     'pytest',
     'pytest-cov',
     'pytest-xdist',
+    # typing-extensions is required to import typing.Protocol and make the mypy checks
+    # pass (along with pylint about non-existent objects) on Python 3.6 & 3.7
+    'typing-extensions',
     'tox',
     'twine',
     'wheel',

{"golden_diff": "diff --git a/certbot/setup.py b/certbot/setup.py\n--- a/certbot/setup.py\n+++ b/certbot/setup.py\n@@ -77,6 +77,9 @@\n     'pytest',\n     'pytest-cov',\n     'pytest-xdist',\n+    # typing-extensions is required to import typing.Protocol and make the mypy checks\n+    # pass (along with pylint about non-existent objects) on Python 3.6 & 3.7\n+    'typing-extensions',\n     'tox',\n     'twine',\n     'wheel',\n", "issue": "Fix lint and mypy with Python < 3.8\nIn https://github.com/certbot/certbot/pull/8748, we made a change that causes our lint and mypy tests to need to be run on Python 3.8+ to pass. See https://github.com/certbot/certbot/pull/8748#issuecomment-808790093 for the discussion of the problem here.\r\n\r\nI don't think we should do this. Certbot supports Python 3.6+ and I think it could cause a particularly bad experience for new devs that don't happen to know they need Python 3.8+. This change also broke our development Dockerfile as can be seen at https://dev.azure.com/certbot/certbot/_build/results?buildId=3742&view=logs&j=bea2d267-f41e-5b33-7b51-a88065a8cbb0&t=0dc90756-6888-5ee6-5a6a-5855e6b9ae76&l=1873. Instead, I think we should change our approach here so the tests work on all versions of Python we support. I'm open to other ideas, but the two ideas I had for this are:\r\n\r\n1. Just declare a runtime dependency on `typing-extensions`.\r\n2. Add `typing-extensions` as a dev/test dependency and try to import it, but use similar fallback code to what we current have if it's not available.\r\n\r\nWhat do you think @adferrand? Are you interested in working on this?\n", "before_files": [{"content": "import codecs\nfrom distutils.version import LooseVersion\nimport os\nimport re\nimport sys\n\nfrom setuptools import __version__ as setuptools_version\nfrom setuptools import find_packages\nfrom setuptools import setup\n\nmin_setuptools_version='39.0.1'\n# This conditional isn't necessary, but it provides better error messages to\n# people who try to install this package with older versions of setuptools.\nif LooseVersion(setuptools_version) < LooseVersion(min_setuptools_version):\n    raise RuntimeError(f'setuptools {min_setuptools_version}+ is required')\n\n# Workaround for https://bugs.python.org/issue8876, see\n# https://bugs.python.org/issue8876#msg208792\n# This can be removed when using Python 2.7.9 or later:\n# https://hg.python.org/cpython/raw-file/v2.7.9/Misc/NEWS\nif os.path.abspath(__file__).split(os.path.sep)[1] == 'vagrant':\n    del os.link\n\n\ndef read_file(filename, encoding='utf8'):\n    \"\"\"Read unicode from given file.\"\"\"\n    with codecs.open(filename, encoding=encoding) as fd:\n        return fd.read()\n\n\nhere = os.path.abspath(os.path.dirname(__file__))\n\n# read version number (and other metadata) from package init\ninit_fn = os.path.join(here, 'certbot', '__init__.py')\nmeta = dict(re.findall(r\"\"\"__([a-z]+)__ = '([^']+)\"\"\", read_file(init_fn)))\n\nreadme = read_file(os.path.join(here, 'README.rst'))\nversion = meta['version']\n\n# This package relies on PyOpenSSL and requests, however, it isn't specified\n# here to avoid masking the more specific request requirements in acme. See\n# https://github.com/pypa/pip/issues/988 for more info.\ninstall_requires = [\n    'acme>=1.8.0',\n    # We technically need ConfigArgParse 0.10.0 for Python 2.6 support, but\n    # saying so here causes a runtime error against our temporary fork of 0.9.3\n    # in which we added 2.6 support (see #2243), so we relax the requirement.\n    'ConfigArgParse>=0.9.3',\n    'configobj>=5.0.6',\n    'cryptography>=2.1.4',\n    'distro>=1.0.1',\n    # 1.1.0+ is required to avoid the warnings described at\n    # https://github.com/certbot/josepy/issues/13.\n    'josepy>=1.1.0',\n    'parsedatetime>=2.4',\n    'pyrfc3339',\n    'pytz',\n    # This dependency needs to be added using environment markers to avoid its\n    # installation on Linux.\n    'pywin32>=300 ; sys_platform == \"win32\"',\n    f'setuptools>={min_setuptools_version}',\n    'zope.component',\n    'zope.interface',\n]\n\ndev_extras = [\n    'astroid',\n    'azure-devops',\n    'coverage',\n    'ipdb',\n    'mypy',\n    'PyGithub',\n    # 1.1.0+ is required for poetry to use the poetry-core library for the\n    # build system declared in tools/pinning/pyproject.toml.\n    'poetry>=1.1.0',\n    'pylint',\n    'pytest',\n    'pytest-cov',\n    'pytest-xdist',\n    'tox',\n    'twine',\n    'wheel',\n]\n\ndocs_extras = [\n    # If you have Sphinx<1.5.1, you need docutils<0.13.1\n    # https://github.com/sphinx-doc/sphinx/issues/3212\n    'repoze.sphinx.autointerface',\n    'Sphinx>=1.2', # Annotation support\n    'sphinx_rtd_theme',\n]\n\nsetup(\n    name='certbot',\n    version=version,\n    description=\"ACME client\",\n    long_description=readme,\n    url='https://github.com/letsencrypt/letsencrypt',\n    author=\"Certbot Project\",\n    author_email='client-dev@letsencrypt.org',\n    license='Apache License 2.0',\n    python_requires='>=3.6',\n    classifiers=[\n        'Development Status :: 5 - Production/Stable',\n        'Environment :: Console',\n        'Environment :: Console :: Curses',\n        'Intended Audience :: System Administrators',\n        'License :: OSI Approved :: Apache Software License',\n        'Operating System :: POSIX :: Linux',\n        'Programming Language :: Python',\n        'Programming Language :: Python :: 3',\n        'Programming Language :: Python :: 3.6',\n        'Programming Language :: Python :: 3.7',\n        'Programming Language :: Python :: 3.8',\n        'Programming Language :: Python :: 3.9',\n        'Topic :: Internet :: WWW/HTTP',\n        'Topic :: Security',\n        'Topic :: System :: Installation/Setup',\n        'Topic :: System :: Networking',\n        'Topic :: System :: Systems Administration',\n        'Topic :: Utilities',\n    ],\n\n    packages=find_packages(exclude=['docs', 'examples', 'tests', 'venv']),\n    include_package_data=True,\n\n    install_requires=install_requires,\n    extras_require={\n        'dev': dev_extras,\n        'docs': docs_extras,\n    },\n\n    entry_points={\n        'console_scripts': [\n            'certbot = certbot.main:main',\n        ],\n        'certbot.plugins': [\n            'manual = certbot._internal.plugins.manual:Authenticator',\n            'null = certbot._internal.plugins.null:Installer',\n            'standalone = certbot._internal.plugins.standalone:Authenticator',\n            'webroot = certbot._internal.plugins.webroot:Authenticator',\n        ],\n    },\n)\n", "path": "certbot/setup.py"}], "after_files": [{"content": "import codecs\nfrom distutils.version import LooseVersion\nimport os\nimport re\nimport sys\n\nfrom setuptools import __version__ as setuptools_version\nfrom setuptools import find_packages\nfrom setuptools import setup\n\nmin_setuptools_version='39.0.1'\n# This conditional isn't necessary, but it provides better error messages to\n# people who try to install this package with older versions of setuptools.\nif LooseVersion(setuptools_version) < LooseVersion(min_setuptools_version):\n    raise RuntimeError(f'setuptools {min_setuptools_version}+ is required')\n\n# Workaround for https://bugs.python.org/issue8876, see\n# https://bugs.python.org/issue8876#msg208792\n# This can be removed when using Python 2.7.9 or later:\n# https://hg.python.org/cpython/raw-file/v2.7.9/Misc/NEWS\nif os.path.abspath(__file__).split(os.path.sep)[1] == 'vagrant':\n    del os.link\n\n\ndef read_file(filename, encoding='utf8'):\n    \"\"\"Read unicode from given file.\"\"\"\n    with codecs.open(filename, encoding=encoding) as fd:\n        return fd.read()\n\n\nhere = os.path.abspath(os.path.dirname(__file__))\n\n# read version number (and other metadata) from package init\ninit_fn = os.path.join(here, 'certbot', '__init__.py')\nmeta = dict(re.findall(r\"\"\"__([a-z]+)__ = '([^']+)\"\"\", read_file(init_fn)))\n\nreadme = read_file(os.path.join(here, 'README.rst'))\nversion = meta['version']\n\n# This package relies on PyOpenSSL and requests, however, it isn't specified\n# here to avoid masking the more specific request requirements in acme. See\n# https://github.com/pypa/pip/issues/988 for more info.\ninstall_requires = [\n    'acme>=1.8.0',\n    # We technically need ConfigArgParse 0.10.0 for Python 2.6 support, but\n    # saying so here causes a runtime error against our temporary fork of 0.9.3\n    # in which we added 2.6 support (see #2243), so we relax the requirement.\n    'ConfigArgParse>=0.9.3',\n    'configobj>=5.0.6',\n    'cryptography>=2.1.4',\n    'distro>=1.0.1',\n    # 1.1.0+ is required to avoid the warnings described at\n    # https://github.com/certbot/josepy/issues/13.\n    'josepy>=1.1.0',\n    'parsedatetime>=2.4',\n    'pyrfc3339',\n    'pytz',\n    # This dependency needs to be added using environment markers to avoid its\n    # installation on Linux.\n    'pywin32>=300 ; sys_platform == \"win32\"',\n    f'setuptools>={min_setuptools_version}',\n    'zope.component',\n    'zope.interface',\n]\n\ndev_extras = [\n    'astroid',\n    'azure-devops',\n    'coverage',\n    'ipdb',\n    'mypy',\n    'PyGithub',\n    # 1.1.0+ is required for poetry to use the poetry-core library for the\n    # build system declared in tools/pinning/pyproject.toml.\n    'poetry>=1.1.0',\n    'pylint',\n    'pytest',\n    'pytest-cov',\n    'pytest-xdist',\n    # typing-extensions is required to import typing.Protocol and make the mypy checks\n    # pass (along with pylint about non-existent objects) on Python 3.6 & 3.7\n    'typing-extensions',\n    'tox',\n    'twine',\n    'wheel',\n]\n\ndocs_extras = [\n    # If you have Sphinx<1.5.1, you need docutils<0.13.1\n    # https://github.com/sphinx-doc/sphinx/issues/3212\n    'repoze.sphinx.autointerface',\n    'Sphinx>=1.2', # Annotation support\n    'sphinx_rtd_theme',\n]\n\nsetup(\n    name='certbot',\n    version=version,\n    description=\"ACME client\",\n    long_description=readme,\n    url='https://github.com/letsencrypt/letsencrypt',\n    author=\"Certbot Project\",\n    author_email='client-dev@letsencrypt.org',\n    license='Apache License 2.0',\n    python_requires='>=3.6',\n    classifiers=[\n        'Development Status :: 5 - Production/Stable',\n        'Environment :: Console',\n        'Environment :: Console :: Curses',\n        'Intended Audience :: System Administrators',\n        'License :: OSI Approved :: Apache Software License',\n        'Operating System :: POSIX :: Linux',\n        'Programming Language :: Python',\n        'Programming Language :: Python :: 3',\n        'Programming Language :: Python :: 3.6',\n        'Programming Language :: Python :: 3.7',\n        'Programming Language :: Python :: 3.8',\n        'Programming Language :: Python :: 3.9',\n        'Topic :: Internet :: WWW/HTTP',\n        'Topic :: Security',\n        'Topic :: System :: Installation/Setup',\n        'Topic :: System :: Networking',\n        'Topic :: System :: Systems Administration',\n        'Topic :: Utilities',\n    ],\n\n    packages=find_packages(exclude=['docs', 'examples', 'tests', 'venv']),\n    include_package_data=True,\n\n    install_requires=install_requires,\n    extras_require={\n        'dev': dev_extras,\n        'docs': docs_extras,\n    },\n\n    entry_points={\n        'console_scripts': [\n            'certbot = certbot.main:main',\n        ],\n        'certbot.plugins': [\n            'manual = certbot._internal.plugins.manual:Authenticator',\n            'null = certbot._internal.plugins.null:Installer',\n            'standalone = certbot._internal.plugins.standalone:Authenticator',\n            'webroot = certbot._internal.plugins.webroot:Authenticator',\n        ],\n    },\n)\n", "path": "certbot/setup.py"}]}