Skip to content

Additional AST-GREP rule for simplifying imports #323

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .ast-grep/rules/multicast-rule-simplify-imports.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# .ast-grep/multicast-rule-simplify-imports.yml
---
id: simplify-imports
rule:
any:
- kind: if_statement
pattern: |
if $CONDITION:
import $MODULE
else: $$$
inside:
kind: block
inside:
kind: try_statement
inside:
kind: module
all:
- has:
any:
- kind: comparison_operator
pattern: |
'$MODULE' not in sys.modules
- kind: comparison_operator
pattern: |
"$MODULE" not in sys.modules
- has:
kind: block
has:
kind: import_statement
message: "Consider simplifying import statement."
fix:
import $MODULE
description: Rule for sys.modules check pattern
language: python
examples:
- name: Complex import statement
code: |
try:
if 'os' not in sys.modules:
import os
else: # pragma: no branch
os = sys.modules["""os"""]
except ImportError as err: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] OS Failed to import.") from err
- name: Simplified import statement
code: |
try:
import os
except ImportError as err: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] OS Failed to import.") from err
67 changes: 9 additions & 58 deletions tests/MulticastUDPClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,68 +111,19 @@
raise ModuleNotFoundError(
"[CWE-440] OMG! sys.modules is not available or empty."
) from None
except ImportError as err:
raise ImportError("[CWE-440] Unable to import sys module.") from err
except ImportError as baton:
raise ImportError("[CWE-440] Unable to import sys module.") from baton

try:
if 'os' not in sys.modules:
import os
else: # pragma: no branch
os = sys.modules["""os"""]
except Exception as badErr: # pragma: no branch
baton = ModuleNotFoundError(badErr, str("[CWE-758] Test module failed completely."))
baton.module = __module__
baton.path = __file__
baton.__cause__ = badErr
raise baton from badErr
import socket
import socketserver
except ImportError as baton:
raise ImportError("[CWE-758] Test module failed completely.") from baton

try:
if 'functools' not in sys.modules:
import functools
else: # pragma: no branch
functools = sys.modules["""functools"""]
except Exception as badErr: # pragma: no branch
baton = ModuleNotFoundError(badErr, str("[CWE-758] Test module failed completely."))
baton.module = __module__
baton.path = __file__
baton.__cause__ = badErr
raise baton from badErr

try:
if 'socket' not in sys.modules:
import socket
else: # pragma: no branch
socket = sys.modules["""socket"""]
except Exception as badErr: # pragma: no branch
baton = ModuleNotFoundError(badErr, str("[CWE-758] Test module failed completely."))
baton.module = __module__
baton.path = __file__
baton.__cause__ = badErr
raise baton from badErr

try:
if 'socketserver' not in sys.modules:
import socketserver
else: # pragma: no branch
socketserver = sys.modules["""socketserver"""]
except Exception as badErr: # pragma: no branch
baton = ModuleNotFoundError(badErr, str("[CWE-758] Test module failed completely."))
baton.module = __module__
baton.path = __file__
baton.__cause__ = badErr
raise baton from badErr

try:
if 'random' not in sys.modules:
import random
else: # pragma: no branch
random = sys.modules["""random"""]
except Exception as badErr: # pragma: no branch
baton = ModuleNotFoundError(badErr, str("[CWE-758] Test module failed completely."))
baton.module = __module__
baton.path = __file__
baton.__cause__ = badErr
raise baton from badErr
import random
except ImportError as baton: # pragma: no branch
raise ModuleNotFoundError("[CWE-758] Test module failed to randomize.") from baton


class MCastClient(object): # skipcq: PYL-R0205
Expand Down
34 changes: 4 additions & 30 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,36 +55,10 @@

try:
import sys
if sys.__name__ is None: # pragma: no branch
raise ModuleNotFoundError(
"[CWE-440] OMG! we could not import sys. ABORT. ABORT."
) from None
except Exception as err: # pragma: no branch
raise ImportError(err) from err

try:
if 'os' not in sys.modules:
import os
else: # pragma: no branch
os = sys.modules["""os"""]
except Exception as err: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] OS Failed to import.") from err

try:
if 'unittest' not in sys.modules:
import unittest
else: # pragma: no branch
unittest = sys.modules["""unittest"""]
except Exception as err: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] unittest Failed to import.") from err

try:
if 'functools' not in sys.modules:
import functools
else: # pragma: no branch
functools = sys.modules["""functools"""]
except Exception as err: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] functools Failed to import.") from err
import os
import unittest
except ImportError as baton: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] Module failed to import.") from baton

try:
if 'multicast' not in sys.modules:
Expand Down
53 changes: 11 additions & 42 deletions tests/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,44 +83,16 @@
raise ImportError("[CWE-440] Unable to import sys module.") from err

try:
if 'os' not in sys.modules:
import os
else: # pragma: no branch
os = sys.modules["""os"""]
except ImportError as err: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] OS Failed to import.") from err

try:
if 'secrets' not in sys.modules:
import secrets
else: # pragma: no branch
secrets = sys.modules["""secrets"""]
except ImportError as err: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] Secrets Failed to import.") from err

try:
if 'string' not in sys.modules:
import string
else: # pragma: no branch
string = sys.modules["""string"""]
import os
if not hasattr(os, 'sep') or not os.sep: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] OS support is not available.") from None
import string
if not hasattr(string, 'digits') or not string.digits: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] string support is not available.") from None
import secrets
import unittest
except ImportError as err: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] String Failed to import.") from err

try:
if 'unittest' not in sys.modules:
import unittest
else: # pragma: no branch
unittest = sys.modules["""unittest"""]
except ImportError as err: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] unittest Failed to import.") from err

try:
if 'contextlib' not in sys.modules:
import contextlib
else: # pragma: no branch
contextlib = sys.modules["""contextlib"""]
except ImportError as err: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] contextlib Failed to import.") from err
raise ModuleNotFoundError("[CWE-440] Module Failed to import.") from err

try:
from contextlib import contextmanager
Expand All @@ -136,10 +108,7 @@
raise ModuleNotFoundError("[CWE-440] Process Failed to import.") from err

try:
if 'subprocess' not in sys.modules:
import subprocess
else: # pragma: no branch
subprocess = sys.modules["""subprocess"""]
import subprocess
except ImportError as err: # pragma: no branch
raise ModuleNotFoundError("[CWE-440] subprocess Failed to import.") from err

Expand Down Expand Up @@ -1003,7 +972,7 @@ def _should_get_package_version_WHEN_valid(self):
def test_absolute_truth_and_meaning(self):
"""Test case 0: Insanitty Test."""
assert True
self.assertTrue(True, "Insanitty Test Failed")
self.assertTrue(True, "Insanitty Test Failed") # skipcq: PYL-W1503

def test_finds_python_WHEN_testing(self):
"""Test case 1: Class Test-Fixture Meta Test."""
Expand Down
10 changes: 2 additions & 8 deletions tests/test_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,12 @@
raise ImportError("[CWE-758] Failed to import test context") from _cause

try:
if 're' not in sys.modules:
import re
else: # pragma: no branch
re = sys.modules["""re"""]
import re
except Exception as _cause: # pragma: no branch
raise ImportError("[CWE-440] re Failed to import.") from _cause

try:
if 'venv' not in sys.modules:
import venv
else: # pragma: no branch
venv = sys.modules["""venv"""]
import venv
except Exception as _cause: # pragma: no branch
raise ImportError("[CWE-440] venv Failed to import.") from _cause

Expand Down
18 changes: 15 additions & 3 deletions tests/test_fuzz.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,25 @@
from hypothesis import settings
from hypothesis import strategies as st
_has_hypothesis = True
except ImportError as _: # pragma: no branch
del _ # skipcq - cleanup any error vars early
except ImportError: # pragma: no branch
_has_hypothesis = False


def onlyIfHasHypothesis(has_hypothesis):
"""Decorator to handle optional loading."""
"""
Conditionally enable a class based on the availability of the hypothesis library.

If the provided flag is False, returns a dummy class with a placeholder method that does nothing,
allowing tests dependent on hypothesis to be safely bypassed. If True, the original
class is returned unchanged.

Arguments:
has_hypothesis (bool): Flag indicating whether the hypothesis library is available.

Returns:
callable: A decorator function that returns either the original class or a dummy class
with a placeholder method, depending on the has_hypothesis flag.
"""
def decorator(cls):
if not has_hypothesis:
# Create an empty class with a method that returns None
Expand Down
Loading