We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
python 3.9 threading changes
Copied from https://bugzilla.redhat.com/show_bug.cgi?id=1808347

            Bug ID: 1808347
           Summary: fail2ban fails to build with Python 3.9: uses removed
                    threading.Thread.isAlive()
           Product: Fedora
           Version: rawhide
            Status: NEW
         Component: fail2ban
          Assignee: orion@nwra.com
          Reporter: mhroncok@redhat.com
        QA Contact: extras-qa@fedoraproject.org
                CC: anon.amish@gmail.com, axel.thimm@atrpms.net,
                    cstratak@redhat.com, mhroncok@redhat.com,
                    mplch@redhat.com, orion@nwra.com, vonsch@gmail.com
            Blocks: 1785415 (PYTHON39)
  Target Milestone: ---
    Classification: Fedora

fail2ban fails to build with Python 3.9.0a4.
```
ERROR: test_del_file
(fail2ban.tests.filtertestcase.MonitorFailures<FilterPoll>(/tmp/monitorfailures_FilterPoll__nshi9c2fail2ban))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./fail2ban/tests/filtertestcase.py", line 987, in setUp
    self._sleep_4_poll()
  File "./fail2ban/tests/filtertestcase.py", line 1008, in _sleep_4_poll
    Utils.wait_for(self.filter.isAlive, _maxWaitTime(5))
AttributeError: 'FilterPoll' object has no attribute 'isAlive'
```

And more. This looks like:

See https://docs.python.org/3.9/whatsnew/3.9.html#removed

"The isAlive() method of threading.Thread has been removed. It was deprecated
since Python 3.8. Use is_alive() instead."

For the build logs, see:
https://copr-be.cloud.fedoraproject.org/results/@python/python3.9/fedora-rawhide-x86_64/01255081-fail2ban/

For all our attempts to build fail2ban with Python 3.9, see:
https://copr.fedorainfracloud.org/coprs/g/python/python3.9/package/fail2ban/

Testing and mass rebuild of packages is happening in copr. You can follow these
instructions to test locally in mock if your package builds with Python 3.9:
https://copr.fedorainfracloud.org/coprs/g/python/python3.9/

Let us know here if you have any questions.

Python 3.9 will be included in Fedora 33. To make that update smoother, we're
building Fedora packages with early pre-releases of Python 3.9.
A build failure prevents us from testing all dependent packages (transitive
[Build]Requires), so if this package is required a lot, it's important for us
to get it fixed soon.
We'd appreciate help from the people who know this package best, but if you
don't want to work on this now, let us know so we can try to work around it on
our side.


Referenced Bugs:

https://bugzilla.redhat.com/show_bug.cgi?id=1785415
[Bug 1785415] Python 3.9

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `fail2ban/server/jailthread.py`
Content:
```
1 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
2 # vi: set ft=python sts=4 ts=4 sw=4 noet :
3 
4 # This file is part of Fail2Ban.
5 #
6 # Fail2Ban is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # Fail2Ban is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with Fail2Ban; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 
20 # Author: Cyril Jaquier
21 # 
22 
23 __author__ = "Cyril Jaquier"
24 __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
25 __license__ = "GPL"
26 
27 import sys
28 from threading import Thread
29 from abc import abstractmethod
30 
31 from .utils import Utils
32 from ..helpers import excepthook, prctl_set_th_name
33 
34 
35 class JailThread(Thread):
36 	"""Abstract class for threading elements in Fail2Ban.
37 
38 	Attributes
39 	----------
40 	daemon
41 	ident
42 	name
43 	status
44 	active : bool
45 		Control the state of the thread.
46 	idle : bool
47 		Control the idle state of the thread.
48 	sleeptime : int
49 		The time the thread sleeps for in the loop.
50 	"""
51 
52 	def __init__(self, name=None):
53 		super(JailThread, self).__init__(name=name)
54 		## Should going with main thread also:
55 		self.daemon = True
56 		## Control the state of the thread (None - was not started, True - active, False - stopped).
57 		self.active = None
58 		## Control the idle state of the thread.
59 		self.idle = False
60 		## The time the thread sleeps in the loop.
61 		self.sleeptime = Utils.DEFAULT_SLEEP_TIME
62 
63 		# excepthook workaround for threads, derived from:
64 		# http://bugs.python.org/issue1230540#msg91244
65 		run = self.run
66 
67 		def run_with_except_hook(*args, **kwargs):
68 			try:
69 				run(*args, **kwargs)
70 			except Exception as e:
71 				# avoid very sporadic error "'NoneType' object has no attribute 'exc_info'" (https://bugs.python.org/issue7336)
72 				# only extremely fast systems are affected ATM (2.7 / 3.x), if thread ends nothing is available here.
73 				if sys is not None:
74 					excepthook(*sys.exc_info())
75 				else:
76 					print(e)
77 		self.run = run_with_except_hook
78 
79 	if sys.version_info >= (3,): # pragma: 2.x no cover
80 		def _bootstrap(self):
81 			prctl_set_th_name(self.name)
82 			return super(JailThread, self)._bootstrap();
83 	else: # pragma: 3.x no cover
84 		def __bootstrap(self):
85 			prctl_set_th_name(self.name)
86 			return Thread._Thread__bootstrap(self)
87 
88 	@abstractmethod
89 	def status(self, flavor="basic"): # pragma: no cover - abstract
90 		"""Abstract - Should provide status information.
91 		"""
92 		pass
93 
94 	def start(self):
95 		"""Sets active flag and starts thread.
96 		"""
97 		self.active = True
98 		super(JailThread, self).start()
99 
100 	def stop(self):
101 		"""Sets `active` property to False, to flag run method to return.
102 		"""
103 		self.active = False
104 
105 	@abstractmethod
106 	def run(self): # pragma: no cover - absract
107 		"""Abstract - Called when thread starts, thread stops when returns.
108 		"""
109 		pass
110 
111 	def join(self):
112 		""" Safer join, that could be called also for not started (or ended) threads (used for cleanup).
113 		"""
114 		## if cleanup needed - create derivate and call it before join...
115 
116 		## if was really started - should call join:
117 		if self.active is not None:
118 			super(JailThread, self).join()
119 
120 ## python 2.x replace binding of private __bootstrap method:
121 if sys.version_info < (3,): # pragma: 3.x no cover
122 	JailThread._Thread__bootstrap = JailThread._JailThread__bootstrap
123
```
--- 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/fail2ban/server/jailthread.py b/fail2ban/server/jailthread.py
--- a/fail2ban/server/jailthread.py
+++ b/fail2ban/server/jailthread.py
@@ -120,3 +120,6 @@
 ## python 2.x replace binding of private __bootstrap method:
 if sys.version_info < (3,): # pragma: 3.x no cover
 	JailThread._Thread__bootstrap = JailThread._JailThread__bootstrap
+## python 3.9, restore isAlive method:
+elif not hasattr(JailThread, 'isAlive'): # pragma: 2.x no cover
+	 JailThread.isAlive = JailThread.is_alive

{"golden_diff": "diff --git a/fail2ban/server/jailthread.py b/fail2ban/server/jailthread.py\n--- a/fail2ban/server/jailthread.py\n+++ b/fail2ban/server/jailthread.py\n@@ -120,3 +120,6 @@\n ## python 2.x replace binding of private __bootstrap method:\n if sys.version_info < (3,): # pragma: 3.x no cover\n \tJailThread._Thread__bootstrap = JailThread._JailThread__bootstrap\n+## python 3.9, restore isAlive method:\n+elif not hasattr(JailThread, 'isAlive'): # pragma: 2.x no cover\n+\t JailThread.isAlive = JailThread.is_alive\n", "issue": "python 3.9 threading changes\nCopied from https://bugzilla.redhat.com/show_bug.cgi?id=1808347\r\n\r\n            Bug ID: 1808347\r\n           Summary: fail2ban fails to build with Python 3.9: uses removed\r\n                    threading.Thread.isAlive()\r\n           Product: Fedora\r\n           Version: rawhide\r\n            Status: NEW\r\n         Component: fail2ban\r\n          Assignee: orion@nwra.com\r\n          Reporter: mhroncok@redhat.com\r\n        QA Contact: extras-qa@fedoraproject.org\r\n                CC: anon.amish@gmail.com, axel.thimm@atrpms.net,\r\n                    cstratak@redhat.com, mhroncok@redhat.com,\r\n                    mplch@redhat.com, orion@nwra.com, vonsch@gmail.com\r\n            Blocks: 1785415 (PYTHON39)\r\n  Target Milestone: ---\r\n    Classification: Fedora\r\n\r\nfail2ban fails to build with Python 3.9.0a4.\r\n```\r\nERROR: test_del_file\r\n(fail2ban.tests.filtertestcase.MonitorFailures<FilterPoll>(/tmp/monitorfailures_FilterPoll__nshi9c2fail2ban))\r\n----------------------------------------------------------------------\r\nTraceback (most recent call last):\r\n  File \"./fail2ban/tests/filtertestcase.py\", line 987, in setUp\r\n    self._sleep_4_poll()\r\n  File \"./fail2ban/tests/filtertestcase.py\", line 1008, in _sleep_4_poll\r\n    Utils.wait_for(self.filter.isAlive, _maxWaitTime(5))\r\nAttributeError: 'FilterPoll' object has no attribute 'isAlive'\r\n```\r\n\r\nAnd more. This looks like:\r\n\r\nSee https://docs.python.org/3.9/whatsnew/3.9.html#removed\r\n\r\n\"The isAlive() method of threading.Thread has been removed. It was deprecated\r\nsince Python 3.8. Use is_alive() instead.\"\r\n\r\nFor the build logs, see:\r\nhttps://copr-be.cloud.fedoraproject.org/results/@python/python3.9/fedora-rawhide-x86_64/01255081-fail2ban/\r\n\r\nFor all our attempts to build fail2ban with Python 3.9, see:\r\nhttps://copr.fedorainfracloud.org/coprs/g/python/python3.9/package/fail2ban/\r\n\r\nTesting and mass rebuild of packages is happening in copr. You can follow these\r\ninstructions to test locally in mock if your package builds with Python 3.9:\r\nhttps://copr.fedorainfracloud.org/coprs/g/python/python3.9/\r\n\r\nLet us know here if you have any questions.\r\n\r\nPython 3.9 will be included in Fedora 33. To make that update smoother, we're\r\nbuilding Fedora packages with early pre-releases of Python 3.9.\r\nA build failure prevents us from testing all dependent packages (transitive\r\n[Build]Requires), so if this package is required a lot, it's important for us\r\nto get it fixed soon.\r\nWe'd appreciate help from the people who know this package best, but if you\r\ndon't want to work on this now, let us know so we can try to work around it on\r\nour side.\r\n\r\n\r\nReferenced Bugs:\r\n\r\nhttps://bugzilla.redhat.com/show_bug.cgi?id=1785415\r\n[Bug 1785415] Python 3.9\n", "before_files": [{"content": "# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-\n# vi: set ft=python sts=4 ts=4 sw=4 noet :\n\n# This file is part of Fail2Ban.\n#\n# Fail2Ban is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# Fail2Ban is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with Fail2Ban; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n\n# Author: Cyril Jaquier\n# \n\n__author__ = \"Cyril Jaquier\"\n__copyright__ = \"Copyright (c) 2004 Cyril Jaquier\"\n__license__ = \"GPL\"\n\nimport sys\nfrom threading import Thread\nfrom abc import abstractmethod\n\nfrom .utils import Utils\nfrom ..helpers import excepthook, prctl_set_th_name\n\n\nclass JailThread(Thread):\n\t\"\"\"Abstract class for threading elements in Fail2Ban.\n\n\tAttributes\n\t----------\n\tdaemon\n\tident\n\tname\n\tstatus\n\tactive : bool\n\t\tControl the state of the thread.\n\tidle : bool\n\t\tControl the idle state of the thread.\n\tsleeptime : int\n\t\tThe time the thread sleeps for in the loop.\n\t\"\"\"\n\n\tdef __init__(self, name=None):\n\t\tsuper(JailThread, self).__init__(name=name)\n\t\t## Should going with main thread also:\n\t\tself.daemon = True\n\t\t## Control the state of the thread (None - was not started, True - active, False - stopped).\n\t\tself.active = None\n\t\t## Control the idle state of the thread.\n\t\tself.idle = False\n\t\t## The time the thread sleeps in the loop.\n\t\tself.sleeptime = Utils.DEFAULT_SLEEP_TIME\n\n\t\t# excepthook workaround for threads, derived from:\n\t\t# http://bugs.python.org/issue1230540#msg91244\n\t\trun = self.run\n\n\t\tdef run_with_except_hook(*args, **kwargs):\n\t\t\ttry:\n\t\t\t\trun(*args, **kwargs)\n\t\t\texcept Exception as e:\n\t\t\t\t# avoid very sporadic error \"'NoneType' object has no attribute 'exc_info'\" (https://bugs.python.org/issue7336)\n\t\t\t\t# only extremely fast systems are affected ATM (2.7 / 3.x), if thread ends nothing is available here.\n\t\t\t\tif sys is not None:\n\t\t\t\t\texcepthook(*sys.exc_info())\n\t\t\t\telse:\n\t\t\t\t\tprint(e)\n\t\tself.run = run_with_except_hook\n\n\tif sys.version_info >= (3,): # pragma: 2.x no cover\n\t\tdef _bootstrap(self):\n\t\t\tprctl_set_th_name(self.name)\n\t\t\treturn super(JailThread, self)._bootstrap();\n\telse: # pragma: 3.x no cover\n\t\tdef __bootstrap(self):\n\t\t\tprctl_set_th_name(self.name)\n\t\t\treturn Thread._Thread__bootstrap(self)\n\n\t@abstractmethod\n\tdef status(self, flavor=\"basic\"): # pragma: no cover - abstract\n\t\t\"\"\"Abstract - Should provide status information.\n\t\t\"\"\"\n\t\tpass\n\n\tdef start(self):\n\t\t\"\"\"Sets active flag and starts thread.\n\t\t\"\"\"\n\t\tself.active = True\n\t\tsuper(JailThread, self).start()\n\n\tdef stop(self):\n\t\t\"\"\"Sets `active` property to False, to flag run method to return.\n\t\t\"\"\"\n\t\tself.active = False\n\n\t@abstractmethod\n\tdef run(self): # pragma: no cover - absract\n\t\t\"\"\"Abstract - Called when thread starts, thread stops when returns.\n\t\t\"\"\"\n\t\tpass\n\n\tdef join(self):\n\t\t\"\"\" Safer join, that could be called also for not started (or ended) threads (used for cleanup).\n\t\t\"\"\"\n\t\t## if cleanup needed - create derivate and call it before join...\n\n\t\t## if was really started - should call join:\n\t\tif self.active is not None:\n\t\t\tsuper(JailThread, self).join()\n\n## python 2.x replace binding of private __bootstrap method:\nif sys.version_info < (3,): # pragma: 3.x no cover\n\tJailThread._Thread__bootstrap = JailThread._JailThread__bootstrap\n", "path": "fail2ban/server/jailthread.py"}], "after_files": [{"content": "# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-\n# vi: set ft=python sts=4 ts=4 sw=4 noet :\n\n# This file is part of Fail2Ban.\n#\n# Fail2Ban is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# Fail2Ban is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with Fail2Ban; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n\n# Author: Cyril Jaquier\n# \n\n__author__ = \"Cyril Jaquier\"\n__copyright__ = \"Copyright (c) 2004 Cyril Jaquier\"\n__license__ = \"GPL\"\n\nimport sys\nfrom threading import Thread\nfrom abc import abstractmethod\n\nfrom .utils import Utils\nfrom ..helpers import excepthook, prctl_set_th_name\n\n\nclass JailThread(Thread):\n\t\"\"\"Abstract class for threading elements in Fail2Ban.\n\n\tAttributes\n\t----------\n\tdaemon\n\tident\n\tname\n\tstatus\n\tactive : bool\n\t\tControl the state of the thread.\n\tidle : bool\n\t\tControl the idle state of the thread.\n\tsleeptime : int\n\t\tThe time the thread sleeps for in the loop.\n\t\"\"\"\n\n\tdef __init__(self, name=None):\n\t\tsuper(JailThread, self).__init__(name=name)\n\t\t## Should going with main thread also:\n\t\tself.daemon = True\n\t\t## Control the state of the thread (None - was not started, True - active, False - stopped).\n\t\tself.active = None\n\t\t## Control the idle state of the thread.\n\t\tself.idle = False\n\t\t## The time the thread sleeps in the loop.\n\t\tself.sleeptime = Utils.DEFAULT_SLEEP_TIME\n\n\t\t# excepthook workaround for threads, derived from:\n\t\t# http://bugs.python.org/issue1230540#msg91244\n\t\trun = self.run\n\n\t\tdef run_with_except_hook(*args, **kwargs):\n\t\t\ttry:\n\t\t\t\trun(*args, **kwargs)\n\t\t\texcept Exception as e:\n\t\t\t\t# avoid very sporadic error \"'NoneType' object has no attribute 'exc_info'\" (https://bugs.python.org/issue7336)\n\t\t\t\t# only extremely fast systems are affected ATM (2.7 / 3.x), if thread ends nothing is available here.\n\t\t\t\tif sys is not None:\n\t\t\t\t\texcepthook(*sys.exc_info())\n\t\t\t\telse:\n\t\t\t\t\tprint(e)\n\t\tself.run = run_with_except_hook\n\n\tif sys.version_info >= (3,): # pragma: 2.x no cover\n\t\tdef _bootstrap(self):\n\t\t\tprctl_set_th_name(self.name)\n\t\t\treturn super(JailThread, self)._bootstrap();\n\telse: # pragma: 3.x no cover\n\t\tdef __bootstrap(self):\n\t\t\tprctl_set_th_name(self.name)\n\t\t\treturn Thread._Thread__bootstrap(self)\n\n\t@abstractmethod\n\tdef status(self, flavor=\"basic\"): # pragma: no cover - abstract\n\t\t\"\"\"Abstract - Should provide status information.\n\t\t\"\"\"\n\t\tpass\n\n\tdef start(self):\n\t\t\"\"\"Sets active flag and starts thread.\n\t\t\"\"\"\n\t\tself.active = True\n\t\tsuper(JailThread, self).start()\n\n\tdef stop(self):\n\t\t\"\"\"Sets `active` property to False, to flag run method to return.\n\t\t\"\"\"\n\t\tself.active = False\n\n\t@abstractmethod\n\tdef run(self): # pragma: no cover - absract\n\t\t\"\"\"Abstract - Called when thread starts, thread stops when returns.\n\t\t\"\"\"\n\t\tpass\n\n\tdef join(self):\n\t\t\"\"\" Safer join, that could be called also for not started (or ended) threads (used for cleanup).\n\t\t\"\"\"\n\t\t## if cleanup needed - create derivate and call it before join...\n\n\t\t## if was really started - should call join:\n\t\tif self.active is not None:\n\t\t\tsuper(JailThread, self).join()\n\n## python 2.x replace binding of private __bootstrap method:\nif sys.version_info < (3,): # pragma: 3.x no cover\n\tJailThread._Thread__bootstrap = JailThread._JailThread__bootstrap\n## python 3.9, restore isAlive method:\nelif not hasattr(JailThread, 'isAlive'): # pragma: 2.x no cover\n\t JailThread.isAlive = JailThread.is_alive\n", "path": "fail2ban/server/jailthread.py"}]}