Skip to content

Commit c4d2a50

Browse files
Modify pre-commit script
1 parent 6656904 commit c4d2a50

File tree

1 file changed

+33
-24
lines changed

1 file changed

+33
-24
lines changed

ci/pre-commit/check_optional_imports.py

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python3
22
"""
3-
Pre-commit hook to ensure optional imports are wrapped in try...except blocks.
3+
Pre-commit hook to ensure optional dependencies are always imported from .options module.
44
This ensures that the connector can operate in environments where these optional libraries are not available.
55
"""
66
import argparse
@@ -27,17 +27,12 @@ def __str__(self):
2727

2828

2929
class ImportChecker(ast.NodeVisitor):
30-
"""Checks for unwrapped optional imports."""
30+
"""Checks that optional imports are only imported from .options module."""
3131

3232
def __init__(self, filename: str):
3333
self.filename = filename
3434
self.violations: List[ImportViolation] = []
3535

36-
def visit_Try(self, node: ast.Try):
37-
"""Track entry/exit of try blocks."""
38-
# do not visit blocks inside try..except blocks
39-
pass
40-
4136
def visit_Import(self, node: ast.Import):
4237
"""Check import statements."""
4338
for alias in node.names:
@@ -47,27 +42,41 @@ def visit_Import(self, node: ast.Import):
4742
def visit_ImportFrom(self, node: ast.ImportFrom):
4843
"""Check from...import statements."""
4944
if node.module:
50-
self._check_import(node.module, node.lineno, node.col_offset)
45+
# Check if importing from a checked module directly
46+
for module in CHECKED_MODULES:
47+
if node.module.startswith(module):
48+
self.violations.append(
49+
ImportViolation(
50+
self.filename,
51+
node.lineno,
52+
node.col_offset,
53+
f"Import from '{node.module}' is not allowed. Use 'from .options import {module}' instead",
54+
)
55+
)
56+
57+
# Check if importing checked modules from .options (this is allowed)
58+
if node.module == ".options":
59+
# This is the correct way to import these modules
60+
pass
5161
self.generic_visit(node)
5262

5363
def _check_import(self, module_name: str, line: int, col: int):
54-
"""Check if a module import is boto-related and unwrapped."""
55-
64+
"""Check if a module import is for checked modules and not from .options."""
5665
for module in CHECKED_MODULES:
5766
if module_name.startswith(module):
5867
self.violations.append(
5968
ImportViolation(
6069
self.filename,
6170
line,
6271
col,
63-
f"Import of '{module_name}' must be wrapped in try...except block to handle cases where {module} is not available",
72+
f"Direct import of '{module_name}' is not allowed. Use 'from .options import {module}' instead",
6473
)
6574
)
6675
break
6776

6877

6978
def check_file(filename: str) -> List[ImportViolation]:
70-
"""Check a file for boto import violations."""
79+
"""Check a file for optional import violations."""
7180
try:
7281
tree = ast.parse(Path(filename).read_text())
7382
except SyntaxError:
@@ -80,9 +89,8 @@ def check_file(filename: str) -> List[ImportViolation]:
8089

8190
def main():
8291
"""Main function for pre-commit hook."""
83-
return 0 # temporarily skip the check
8492
parser = argparse.ArgumentParser(
85-
description="Check for unwrapped boto3/botocore imports"
93+
description="Check that optional imports are only imported from .options module"
8694
)
8795
parser.add_argument("filenames", nargs="*", help="Filenames to check")
8896
parser.add_argument(
@@ -98,7 +106,7 @@ def main():
98106

99107
# Show violations
100108
if all_violations:
101-
print("Unwrapped boto3/botocore import violations found:")
109+
print("Optional import violations found:")
102110
print()
103111

104112
for violation in all_violations:
@@ -107,18 +115,19 @@ def main():
107115
if args.show_fixes:
108116
print()
109117
print("How to fix:")
110-
print(" - Wrap boto3/botocore imports in try...except blocks")
118+
print(" - Import optional modules only from .options module")
111119
print(" - Example:")
112-
print(" try:")
113-
print(" import boto3")
114-
print(" from botocore.config import Config")
115-
print(" except ImportError:")
116-
print(" # Handle the case where boto3/botocore is not available")
117-
print(" boto3 = None")
118-
print(" Config = None")
120+
print(" # CORRECT:")
121+
print(" from .options import boto3, botocore, installed_boto")
122+
print(" if installed_boto:")
123+
print(" SigV4Auth = botocore.auth.SigV4Auth")
124+
print()
125+
print(" # INCORRECT:")
126+
print(" import boto3")
127+
print(" from botocore.auth import SigV4Auth")
119128
print()
120129
print(
121-
" - This ensures the connector works in environments where AWS libraries are not installed"
130+
" - This ensures the connector works in environments where optional libraries are not installed"
122131
)
123132

124133
print()

0 commit comments

Comments
 (0)