Skip to content

Commit 3c91e44

Browse files
committed
Add H905 hacking check to ban eventlet usage
OpenStack projects are migrating away from eventlet. Currently, each migrated project needs to implement their own eventlet detection rules, leading to code duplication and inconsistent enforcement. This change provides a standardized H905 hacking check that detects eventlet imports across all OpenStack projects. The check is disabled by default to avoid breaking unmigrated projects, but migrated projects can simply enable it with "enable-extensions = H905" in their tox.ini instead of maintaining custom eventlet detection code. This eliminates the need to recreate this rule in each deliverable and provides consistent eventlet removal enforcement across the ecosystem. Assisted-By: Claude Code Change-Id: I5b99df46098f022de5b316ca561c29cbfcdcb2a3 Signed-off-by: Hervé Beraud <[email protected]>
1 parent abff65f commit 3c91e44

File tree

5 files changed

+81
-1
lines changed

5 files changed

+81
-1
lines changed

HACKING.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ General
3333
- [H105] Don't use author tags. We use version control instead.
3434
- [H106] Don't put vim configuration in source files (off by default).
3535
- [H904] Delay string interpolations at logging calls (off by default).
36+
- [H905] Do not import eventlet (off by default). Eventlet usage is being
37+
removed from OpenStack projects as part of the async migration effort.
38+
Use threading or asyncio instead.
3639
- Do not shadow a built-in or reserved word. Shadowing built -in or reserved
3740
words makes the code harder to understand. Example::
3841

@@ -86,14 +89,15 @@ Real-world Import Order Examples
8689
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8790
Example::
8891

92+
import asyncio
8993
import httplib
9094
import logging
9195
import random
9296
import StringIO
97+
import threading
9398
import time
9499
import unittest
95100

96-
import eventlet
97101
import webob.exc
98102

99103
import nova.api.ec2

hacking/checks/imports.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
from hacking import core
1616

1717
RE_RELATIVE_IMPORT = re.compile(r'^from\s*[.]')
18+
RE_EVENTLET_IMPORT = re.compile(
19+
r'^\s*(?:import\s+eventlet(?:\s|$|\.)|from\s+eventlet(?:\s|$|\.))')
1820

1921

2022
@core.flake8ext
@@ -102,3 +104,25 @@ def hacking_import_alphabetical(logical_line, blank_before, previous_logical,
102104
if split_line[1] < split_previous[1]:
103105
yield (0, "H306: imports not in alphabetical order (%s, %s)"
104106
% (split_previous[1], split_line[1]))
107+
108+
109+
@core.flake8ext
110+
@core.off_by_default
111+
def hacking_no_eventlet(logical_line, noqa):
112+
r"""Check that eventlet is not imported.
113+
114+
Eventlet is being removed from OpenStack projects as part of the
115+
async migration effort. New code should use threading or asyncio instead.
116+
117+
Examples:
118+
H905: import eventlet
119+
H905: from eventlet import something
120+
Okay: import asyncio
121+
Okay: import threading
122+
"""
123+
if noqa:
124+
return
125+
126+
if RE_EVENTLET_IMPORT.match(logical_line):
127+
yield (0, "H905: eventlet import detected. "
128+
"Eventlet is banned, use threading or asyncio instead.")
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
10+
# implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
14+
import ddt
15+
16+
from hacking.checks import imports
17+
from hacking import tests
18+
19+
20+
@ddt.ddt
21+
class ImportsTestCase(tests.TestCase):
22+
"""This tests hacking checks from the 'imports' group."""
23+
24+
@ddt.unpack
25+
@ddt.data(
26+
(True, 'import eventlet', None),
27+
(True, 'from eventlet import monkey_patch', None),
28+
(True, 'from eventlet.green import socket', None),
29+
(True, ' import eventlet # with indentation', None),
30+
(True, ' from eventlet import something', None),
31+
(False, 'import eventlet # noqa', '# noqa'),
32+
(False, 'import asyncio', None),
33+
(False, 'import threading', None),
34+
(False, 'from threading import Thread', None),
35+
(False, 'import concurrent.futures', None),
36+
(False, 'import some_other_module', None),
37+
(False, 'import not_eventlet', None),
38+
(False, 'from not_eventlet import something', None),
39+
)
40+
def test_H905_hacking_no_eventlet(self, should_fail, line, noqa):
41+
if should_fail:
42+
self.assertCheckFails(imports.hacking_no_eventlet, line, noqa)
43+
else:
44+
self.assertCheckPasses(imports.hacking_no_eventlet, line, noqa)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
features:
3+
- |
4+
Added new hacking check ``H905`` to detect and ban ``eventlet`` usage in
5+
OpenStack projects. This check supports the ongoing ``eventlet`` removal
6+
effort across OpenStack as part of the async migration to ``threading``
7+
and ``asyncio``.

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ flake8.extension =
6262
H700 = hacking.checks.localization:hacking_localization_strings
6363
H903 = hacking.checks.other:hacking_no_cr
6464
H904 = hacking.checks.other:hacking_delayed_string_interpolation
65+
H905 = hacking.checks.imports:hacking_no_eventlet
6566

6667
[extras]
6768
pep257 =

0 commit comments

Comments
 (0)