diff --git a/src/codemodder/codemods/base_codemod.py b/src/codemodder/codemods/base_codemod.py index a8f3d572..c5348c5a 100644 --- a/src/codemodder/codemods/base_codemod.py +++ b/src/codemodder/codemods/base_codemod.py @@ -1,4 +1,4 @@ -from dataclasses import dataclass, asdict +from dataclasses import dataclass from enum import Enum import itertools from typing import List, ClassVar @@ -30,25 +30,6 @@ class BaseCodemod: execution_context: CodemodExecutionContext file_context: FileContext - def __init_subclass__(cls, **kwargs): - super().__init_subclass__(**kwargs) - - if "codemodder.codemods.base_codemod.SemgrepCodemod" in str(cls): - # hack: SemgrepCodemod won't NotImplementedError but all other child - # classes will. - return - - for attr in ["SUMMARY", "METADATA"]: - if getattr(cls, attr) is NotImplemented: - raise NotImplementedError( - f"You forgot to define {attr} for {cls.__name__}" - ) - for k, v in asdict(cls.METADATA).items(): - if v is NotImplemented: - raise NotImplementedError(f"You forgot to define METADATA.{k}") - if not v: - raise NotImplementedError(f"METADATA.{k} should not be None or empty") - def __init__(self, execution_context: CodemodExecutionContext, file_context): self.execution_context = execution_context self.file_context = file_context @@ -88,18 +69,9 @@ class SemgrepCodemod(BaseCodemod): YAML_FILES: ClassVar[List[str]] = NotImplemented is_semgrep = True - def __init_subclass__(cls, **kwargs): - super().__init_subclass__(**kwargs) - - if cls.YAML_FILES is NotImplemented: - raise NotImplementedError( - "You forgot to define class attribute: YAML_FILES" - ) - - cls.RULE_IDS = rule_ids_from_yaml_files(cls.YAML_FILES) - def __init__(self, *args): super().__init__(*args) + self.RULE_IDS = rule_ids_from_yaml_files(self.YAML_FILES) self._results = list( itertools.chain.from_iterable( map(lambda rId: self.file_context.results_by_id[rId], self.RULE_IDS) diff --git a/tests/codemods/test_base_codemod.py b/tests/codemods/test_base_codemod.py index 571019e9..e277d90e 100644 --- a/tests/codemods/test_base_codemod.py +++ b/tests/codemods/test_base_codemod.py @@ -2,7 +2,6 @@ from typing import DefaultDict import libcst as cst from libcst.codemod import Codemod, CodemodContext -import pytest import mock from codemodder.codemods.base_codemod import ( SemgrepCodemod, @@ -43,35 +42,3 @@ def run_and_assert(self, input_code, expexted_output): def test_empty_results(self): input_code = """print('Hello World')""" self.run_and_assert(input_code, input_code) - - -class TestSemgrepCodemod: - # pylint: disable=unused-variable - def test_missing_class_attrs(self): - with pytest.raises(NotImplementedError): - - class MissingInfoCodemod(SemgrepCodemod): - ... - - with pytest.raises(NotImplementedError): - - class MissingNameCodemod(SemgrepCodemod): - METADATA = CodemodMetadata( - "Description", None, ReviewGuidance.MERGE_WITHOUT_REVIEW - ) - - with pytest.raises(NotImplementedError): - - class MissingDescriptionCodemod(SemgrepCodemod): - METADATA = CodemodMetadata( - "", "Name", ReviewGuidance.MERGE_WITHOUT_REVIEW - ) - - with pytest.raises(NotImplementedError): - - class MissingAuthorCodemod(SemgrepCodemod): - METADATA = CodemodMetadata( - NotImplemented, - "Name", - ReviewGuidance.MERGE_WITHOUT_REVIEW, - ) diff --git a/tests/codemods/test_django_debug_flag_on.py b/tests/codemods/test_django_debug_flag_on.py index 20426530..4db6ab22 100644 --- a/tests/codemods/test_django_debug_flag_on.py +++ b/tests/codemods/test_django_debug_flag_on.py @@ -5,8 +5,12 @@ class TestDjangoDebugFlagOn(BaseDjangoCodemodTest): codemod = DjangoDebugFlagOn - def test_rule_ids(self): - assert self.codemod.RULE_IDS == ["django-debug-flag-on"] + def test_rule_ids(self, mocker): + assert self.codemod( + mocker.MagicMock(), + mocker.MagicMock(), + mocker.MagicMock(), + ).RULE_IDS == ["django-debug-flag-on"] def test_settings_dot_py(self, tmpdir): django_root, settings_folder = self.create_dir_structure(tmpdir) diff --git a/tests/codemods/test_django_session_cookie_secure_off.py b/tests/codemods/test_django_session_cookie_secure_off.py index 327f4457..8e4afac1 100644 --- a/tests/codemods/test_django_session_cookie_secure_off.py +++ b/tests/codemods/test_django_session_cookie_secure_off.py @@ -8,8 +8,12 @@ class TestDjangoSessionSecureCookieOff(BaseDjangoCodemodTest): codemod = DjangoSessionCookieSecureOff - def test_rule_ids(self): - assert self.codemod.RULE_IDS == ["found-settings-file"] + def test_rule_ids(self, mocker): + assert self.codemod( + mocker.MagicMock(), + mocker.MagicMock(), + mocker.MagicMock(), + ).RULE_IDS == ["found-settings-file"] def test_not_settings_dot_py(self, tmpdir): django_root, settings_folder = self.create_dir_structure(tmpdir) diff --git a/tests/codemods/test_url_sandbox.py b/tests/codemods/test_url_sandbox.py index eafb0fab..379effc9 100644 --- a/tests/codemods/test_url_sandbox.py +++ b/tests/codemods/test_url_sandbox.py @@ -6,8 +6,12 @@ class TestUrlSandbox(BaseSemgrepCodemodTest): codemod = UrlSandbox - def test_rule_ids(self): - assert self.codemod.RULE_IDS == ["sandbox-url-creation"] + def test_rule_ids(self, mocker): + assert self.codemod( + mocker.MagicMock(), + mocker.MagicMock(), + mocker.MagicMock(), + ).RULE_IDS == ["sandbox-url-creation"] def test_import_requests(self, tmpdir): input_code = """import requests