diff --git a/HACKING.rst b/HACKING.rst index a2f67d993b62..c5a1ba4ae39c 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -76,6 +76,7 @@ Nova Specific Commandments with eventlet patched code. Use nova.utils.ReaderWriterLock() instead. - [N370] Don't use or import six - [N371] You must explicitly import python's mock: ``from unittest import mock`` +- [N372] Don't use the setDaemon method. Use the daemon attribute instead. Creating Unit Tests ------------------- diff --git a/nova/hacking/checks.py b/nova/hacking/checks.py index cd393e7b33f7..704538250fe6 100644 --- a/nova/hacking/checks.py +++ b/nova/hacking/checks.py @@ -141,6 +141,8 @@ rwlock_re = re.compile( r"(?P(oslo_concurrency\.)?(lockutils|fasteners))" r"\.ReaderWriterLock\(.*\)") six_re = re.compile(r"^(import six(\..*)?|from six(\..*)? import .*)$") +# Regex for catching the setDaemon method +set_daemon_re = re.compile(r"\.setDaemon\(") class BaseASTChecker(ast.NodeVisitor): @@ -1078,3 +1080,22 @@ def import_stock_mock(logical_line): "N371: You must explicitly import python's mock: " "``from unittest import mock``" ) + + +@core.flake8ext +def check_set_daemon(logical_line): + """Check for use of the setDaemon method of the threading.Thread class + + The setDaemon method of the threading.Thread class has been deprecated + since Python 3.10. Use the daemon attribute instead. + + See + https://docs.python.org/3.10/library/threading.html#threading.Thread.setDaemon + for details. + + N372 + """ + res = set_daemon_re.search(logical_line) + if res: + yield (0, "N372: Don't use the setDaemon method. " + "Use the daemon attribute instead.") diff --git a/nova/tests/unit/test_hacking.py b/nova/tests/unit/test_hacking.py index 10b2a79db425..41cbada99faf 100644 --- a/nova/tests/unit/test_hacking.py +++ b/nova/tests/unit/test_hacking.py @@ -1043,3 +1043,24 @@ class HackingTestCase(test.NoDBTestCase): import unittest.mock """ self._assert_has_no_errors(code, checks.import_stock_mock) + + def test_check_set_daemon(self): + code = """ + self.setDaemon(True) + worker.setDaemon(True) + self._event_thread.setDaemon(True) + mythread.setDaemon(False) + self.thread.setDaemon(1) + """ + errors = [(x + 1, 0, 'N372') for x in range(5)] + self._assert_has_errors( + code, checks.check_set_daemon, expected_errors=errors) + + code = """ + self.setDaemon = True + worker.setDaemonFlag(True) + self._event_thread.resetDaemon(True) + self.set.Daemon(True) + self.thread.setdaemon(True) + """ + self._assert_has_no_errors(code, checks.check_set_daemon) diff --git a/tox.ini b/tox.ini index edb08599e7dc..082f3f4c7435 100644 --- a/tox.ini +++ b/tox.ini @@ -351,6 +351,7 @@ extension = N369 = checks:check_lockutils_rwlocks N370 = checks:check_six N371 = checks:import_stock_mock + N372 = checks:check_set_daemon paths = ./nova/hacking