Skip to content

Commit

Permalink
chore: Improve terraform type hint (#5471)
Browse files Browse the repository at this point in the history
* enable mypy for terraform/parser.py

* migrate bandit and pytest config to pyproject.toml

* updated pre-commit hooks and fixed new flake issue E721

* fix PR comments and new genrics to BaseRunner
  • Loading branch information
gruebel committed Aug 24, 2023
1 parent b42a3d3 commit 3cd73f9
Show file tree
Hide file tree
Showing 41 changed files with 216 additions and 150 deletions.
2 changes: 0 additions & 2 deletions .bandit

This file was deleted.

6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repos:
hooks:
- id: debug-statements
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
rev: 6.1.0
hooks:
- id: flake8
language_version: python3.9
Expand All @@ -18,7 +18,7 @@ repos:
- id: teyit
language_version: python3.9
- repo: https://github.com/rhysd/actionlint
rev: v1.6.24
rev: v1.6.25
hooks:
- id: actionlint-docker
# SC2129 - Consider using { cmd1; cmd2; } >> file instead of individual redirects.
Expand All @@ -33,7 +33,7 @@ repos:
additional_dependencies:
- vistir<0.7.0 # can be removed, when v4.0.0 of pipenv-setup comes out
- repo: https://github.com/seddonym/import-linter # checks the import dependencies between each other
rev: v1.10.0
rev: v1.11.1
hooks:
- id: import-linter
language_version: python3.9
Expand Down
10 changes: 8 additions & 2 deletions checkov/arm/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from collections.abc import Iterable
from typing import TYPE_CHECKING, Any, cast

from typing_extensions import TypeAlias # noqa[TC002]

from checkov.arm.graph_builder.local_graph import ArmLocalGraph
from checkov.arm.graph_manager import ArmGraphManager
from checkov.arm.registry import arm_resource_registry, arm_parameter_registry
Expand All @@ -28,8 +30,11 @@
from checkov.common.graph.checks_infra.registry import BaseRegistry
from checkov.common.typing import LibraryGraphConnector, _CheckResult

_ArmContext: TypeAlias = "dict[str, dict[str, Any]]"
_ArmDefinitions: TypeAlias = "dict[str, dict[str, Any]]"


class Runner(BaseRunner[ArmGraphManager]):
class Runner(BaseRunner[_ArmDefinitions, _ArmContext, ArmGraphManager]):
check_type = CheckType.ARM # noqa: CCE003 # a static attribute

def __init__(
Expand All @@ -51,8 +56,9 @@ def __init__(
self.graph_registry = get_graph_checks_registry(self.check_type)

# need to check, how to support subclass differences
self.definitions: "dict[str, dict[str, Any]]" = {} # type:ignore[assignment]
self.definitions: _ArmDefinitions = {}
self.definitions_raw: "dict[str, list[tuple[int, str]]]" = {}
self.context: _ArmContext | None = None
self.root_folder: "str | None" = None

def run(
Expand Down
11 changes: 8 additions & 3 deletions checkov/bicep/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from pathlib import Path
from typing import cast, Type, TYPE_CHECKING, Any

from typing_extensions import TypeAlias # noqa[TC002]

from checkov.bicep.graph_builder.context_definitions import build_definitions_context
from checkov.bicep.checks.param.registry import registry as param_registry
from checkov.bicep.checks.resource.registry import registry as resource_registry
Expand Down Expand Up @@ -40,8 +42,11 @@
from pycep.typing import BicepJson
from typing_extensions import Literal

_BicepContext: TypeAlias = "dict[str, dict[str, Any]]"
_BicepDefinitions: TypeAlias = "dict[Path, BicepJson]"


class Runner(ImageReferencerMixin[None], BaseRunner[BicepGraphManager]):
class Runner(ImageReferencerMixin[None], BaseRunner[_BicepDefinitions, _BicepContext, BicepGraphManager]):
check_type = CheckType.BICEP # noqa: CCE003 # a static attribute

block_type_registries: 'dict[Literal["parameters", "resources"], BaseCheckRegistry]' = { # noqa: CCE003 # a static attribute
Expand All @@ -66,8 +71,8 @@ def __init__(
)
self.graph_registry: Registry = get_graph_checks_registry(self.check_type)

self.context: dict[str, dict[str, Any]] = {}
self.definitions: dict[Path, BicepJson] = {} # type:ignore[assignment] # need to check, how to support subclass differences
self.context: _BicepContext = {}
self.definitions: _BicepDefinitions = {}
self.definitions_raw: dict[Path, list[tuple[int, str]]] = {} # type:ignore[assignment]
self.root_folder: str | Path | None = None

Expand Down
2 changes: 1 addition & 1 deletion checkov/circleci_pipelines/checks/SuspectCurlInScript.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def scan_conf(self, conf: dict[str, Any]) -> tuple[CheckResult, dict[str, Any]]:
if "run" not in conf:
return CheckResult.PASSED, conf
run = conf.get("run", "")
if type(run) == dict:
if isinstance(run, dict):
run = run.get("command", "")
if "curl" in run:
badstuff = ['curl', 'POST']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def scan_resource_conf(self, conf: dict[str, Any]) -> CheckResult:
# those, allowing inspected_keys in checks to use the same syntax.
# The last value shouldn't be changed, because it could be indeed a valid number
for i in range(0, len(match) - 1):
if type(match[i]) == int:
if type(match[i]) is int:
match[i] = f"[{match[i]}]"

if match[:-1] == path_elements:
Expand Down
11 changes: 8 additions & 3 deletions checkov/cloudformation/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import os
from typing import Type, Any, TYPE_CHECKING

from typing_extensions import TypeAlias # noqa[TC002]

from checkov.cloudformation import cfn_utils
from checkov.cloudformation.cfn_utils import create_definitions, build_definitions_context
from checkov.cloudformation.checks.resource.registry import cfn_registry
Expand Down Expand Up @@ -35,8 +37,11 @@
from checkov.common.checks_infra.registry import Registry
from checkov.common.images.image_referencer import Image

_CloudformationContext: TypeAlias = "dict[str, dict[str, Any]]"
_CloudformationDefinitions: TypeAlias = "dict[str, dict[str, Any]]"


class Runner(ImageReferencerMixin[None], BaseRunner[CloudformationGraphManager]):
class Runner(ImageReferencerMixin[None], BaseRunner[_CloudformationDefinitions, _CloudformationContext, CloudformationGraphManager]):
check_type = CheckType.CLOUDFORMATION # noqa: CCE003 # a static attribute

def __init__(
Expand All @@ -56,8 +61,8 @@ def __init__(
if graph_manager is not None
else CloudformationGraphManager(source=source, db_connector=db_connector)
)
self.context: "dict[str, dict[str, Any]]" = {}
self.definitions: "dict[str, dict[str, Any]]" = {} # type:ignore[assignment] # need to check, how to support subclass differences
self.context: _CloudformationContext = {}
self.definitions: _CloudformationDefinitions = {}
self.definitions_raw: "dict[str, list[tuple[int, str]]]" = {}
self.graph_registry: "Registry" = get_graph_checks_registry(self.check_type)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class EqualsAttributeSolver(BaseAttributeSolver):

def _get_operation(self, vertex: Dict[str, Any], attribute: Optional[str]) -> bool:
attr_val = vertex.get(attribute) # type:ignore[arg-type] # due to attribute can be None
if type(attr_val) == bool or type(self.value) == bool:
if isinstance(attr_val, bool) or isinstance(self.value, bool):
# handle cases like str(False) == "false"
# generally self.value will be a string, but could be a bool if the policy was created straight from json
return str(attr_val).lower() == str(self.value).lower()
Expand Down
2 changes: 1 addition & 1 deletion checkov/common/output/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def __init__(
file_abs_path: str,
entity_tags: Optional[Dict[str, str]] = None,
caller_file_path: Optional[str] = None,
caller_file_line_range: Optional[Tuple[int, int]] = None,
caller_file_line_range: tuple[int, int] | None = None,
bc_check_id: Optional[str] = None,
resource_address: Optional[str] = None,
severity: Optional[Severity] = None,
Expand Down
12 changes: 7 additions & 5 deletions checkov/common/runners/base_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from checkov.common.graph.checks_infra.registry import BaseRegistry
from checkov.common.typing import _CheckResult, LibraryGraphConnector

_Context = TypeVar("_Context", bound="dict[Any, Any]|None")
_Definitions = TypeVar("_Definitions", bound="dict[Any, Any]|None")
_GraphManager = TypeVar("_GraphManager", bound="GraphManager[Any, Any]|None")


Expand All @@ -50,11 +52,11 @@ def strtobool(val: str) -> int:
ignored_directories = IGNORED_DIRECTORIES_ENV.split(",")


class BaseRunner(ABC, Generic[_GraphManager]):
class BaseRunner(ABC, Generic[_Definitions, _Context, _GraphManager]):
check_type = ""
definitions: dict[str, dict[str, Any] | list[dict[str, Any]]] | None = None
definitions: _Definitions | None = None
raw_definitions: dict[str, list[tuple[int, str]]] | None = None
context: dict[str, dict[str, Any]] | None = None
context: _Context | None = None
breadcrumbs = None
external_registries: list[BaseRegistry] | None = None
graph_manager: _GraphManager | None = None
Expand Down Expand Up @@ -106,8 +108,8 @@ def included_paths(self) -> Iterable[str]:

def set_external_data(
self,
definitions: dict[str, dict[str, Any] | list[dict[str, Any]]] | None,
context: dict[str, dict[str, Any]] | None,
definitions: _Definitions | None,
context: _Context | None,
breadcrumbs: dict[str, dict[str, Any]] | None,
**kwargs: Any,
) -> None:
Expand Down
10 changes: 7 additions & 3 deletions checkov/common/runners/object_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from collections.abc import Iterable
from pathlib import Path
from typing import Any, TYPE_CHECKING, Callable
from typing_extensions import TypedDict
from typing_extensions import TypedDict, TypeAlias

from checkov.common.checks_infra.registry import get_graph_checks_registry
from checkov.common.models.enums import CheckResult
Expand All @@ -30,14 +30,17 @@
from checkov.common.graph.checks_infra.base_check import BaseGraphCheck
from checkov.common.runners.graph_builder.local_graph import ObjectLocalGraph

_ObjectContext: TypeAlias = "dict[str, dict[str, Any]]"
_ObjectDefinitions: TypeAlias = "dict[str, dict[str, Any] | list[dict[str, Any]]]"


class GhaMetadata(TypedDict):
triggers: set[str]
workflow_name: str
jobs: dict[int, str]


class Runner(BaseRunner[ObjectGraphManager]): # if a graph is added, Any needs to replaced
class Runner(BaseRunner[_ObjectDefinitions, _ObjectContext, ObjectGraphManager]):
def __init__(
self,
db_connector: LibraryGraphConnector | None = None,
Expand All @@ -46,8 +49,9 @@ def __init__(
graph_manager: ObjectGraphManager | None = None,
) -> None:
super().__init__()
self.definitions: dict[str, dict[str, Any] | list[dict[str, Any]]] = {}
self.definitions: _ObjectDefinitions = {}
self.definitions_raw: dict[str, list[tuple[int, str]]] = {}
self.context: _ObjectContext | None = None
self.map_file_path_to_gha_metadata_dict: dict[str, GhaMetadata] = {}
self.root_folder: str | None = None

Expand Down
2 changes: 1 addition & 1 deletion checkov/common/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from igraph import Graph
from checkov.terraform.modules.module_objects import TFDefinitionKey

_BaseRunner = TypeVar("_BaseRunner", bound="BaseRunner[Any]")
_BaseRunner = TypeVar("_BaseRunner", bound="BaseRunner[Any, Any, Any]")

_ScannerCallableAlias: TypeAlias = Callable[
[str, "BaseCheck", "list[_SkippedCheck]", "dict[str, Any]", str, str, "dict[str, Any]"], None
Expand Down
11 changes: 8 additions & 3 deletions checkov/dockerfile/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from collections.abc import Iterable
from typing import TYPE_CHECKING, Any

from typing_extensions import TypeAlias # noqa[TC002]

from checkov.common.checks_infra.registry import get_graph_checks_registry
from checkov.common.models.enums import CheckResult
from checkov.common.typing import LibraryGraphConnector
Expand Down Expand Up @@ -41,8 +43,11 @@
from checkov.common.graph.checks_infra.base_check import BaseGraphCheck
from checkov.common.images.image_referencer import Image

_DockerfileContext: TypeAlias = "dict[str, dict[str, Any]]"
_DockerfileDefinitions: TypeAlias = "dict[str, dict[str, list[_Instruction]]]"


class Runner(ImageReferencerMixin["dict[str, dict[str, list[_Instruction]]]"], BaseRunner[DockerfileGraphManager]):
class Runner(ImageReferencerMixin[_DockerfileDefinitions], BaseRunner[_DockerfileDefinitions, _DockerfileContext, DockerfileGraphManager]):
check_type = CheckType.DOCKERFILE # noqa: CCE003 # a static attribute

def __init__(
Expand All @@ -61,8 +66,8 @@ def __init__(
)
self.graph_registry = get_graph_checks_registry(self.check_type)

self.context: dict[str, dict[str, Any]] = {}
self.definitions: "dict[str, dict[str, list[_Instruction]]]" = {} # type:ignore[assignment] # need to check, how to support subclass differences
self.context: _DockerfileContext = {}
self.definitions: _DockerfileDefinitions = {}
self.definitions_raw: "dict[str, list[str]]" = {} # type:ignore[assignment]
self.root_folder: str | None = None

Expand Down
4 changes: 2 additions & 2 deletions checkov/helm/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from checkov.helm.image_referencer.manager import HelmImageReferencerManager
from checkov.helm.registry import registry
from checkov.kubernetes.graph_builder.local_graph import KubernetesLocalGraph
from checkov.kubernetes.runner import Runner as k8_runner, handle_timeout
from checkov.kubernetes.runner import Runner as k8_runner, handle_timeout, _KubernetesContext, _KubernetesDefinitions
from checkov.runner_filter import RunnerFilter
import signal

Expand Down Expand Up @@ -122,7 +122,7 @@ def extract_images(
return images


class Runner(BaseRunner["KubernetesGraphManager"]):
class Runner(BaseRunner[_KubernetesDefinitions, _KubernetesContext, "KubernetesGraphManager"]):
check_type: str = CheckType.HELM # noqa: CCE003 # a static attribute
helm_command = 'helm' # noqa: CCE003 # a static attribute
system_deps = True # noqa: CCE003 # a static attribute
Expand Down
10 changes: 8 additions & 2 deletions checkov/kubernetes/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import os
from typing import Type, Any, TYPE_CHECKING

from typing_extensions import TypeAlias # noqa[TC002]

from checkov.common.checks_infra.registry import get_graph_checks_registry
from checkov.common.graph.checks_infra.registry import BaseRegistry
from checkov.common.typing import LibraryGraphConnector
Expand Down Expand Up @@ -39,6 +41,9 @@
from checkov.common.images.image_referencer import Image
from checkov.common.typing import _CheckResult, _EntityContext

_KubernetesContext: TypeAlias = "dict[str, dict[str, Any]]"
_KubernetesDefinitions: TypeAlias = "dict[str, list[dict[str, Any]]]"


class TimeoutError(Exception):
pass
Expand All @@ -48,7 +53,7 @@ def handle_timeout(signum: int, frame: FrameType | None) -> Any:
raise TimeoutError('command got timeout')


class Runner(ImageReferencerMixin[None], BaseRunner[KubernetesGraphManager]):
class Runner(ImageReferencerMixin[None], BaseRunner[_KubernetesDefinitions, _KubernetesContext, KubernetesGraphManager]):
check_type = CheckType.KUBERNETES # noqa: CCE003 # a static attribute

def __init__(
Expand All @@ -69,8 +74,9 @@ def __init__(
graph_manager if graph_manager else KubernetesGraphManager(source=source, db_connector=db_connector)

self.graph_registry = get_graph_checks_registry(self.check_type)
self.definitions: "dict[str, list[dict[str, Any]]]" = {} # type:ignore[assignment]
self.definitions: _KubernetesDefinitions = {}
self.definitions_raw: "dict[str, list[tuple[int, str]]]" = {}
self.context: _KubernetesContext | None = None
self.report_mutator_data: "dict[str, dict[str, Any]]" = {}
self.report_type = report_type

Expand Down
7 changes: 3 additions & 4 deletions checkov/kustomize/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
from checkov.common.util.type_forcers import convert_str_to_bool
from checkov.kubernetes.kubernetes_utils import create_check_result, get_resource_id, calculate_code_lines, \
PARENT_RESOURCE_ID_KEY_NAME
from checkov.kubernetes.runner import Runner as K8sRunner
from checkov.kubernetes.runner import _get_entity_abs_path
from checkov.kubernetes.runner import Runner as K8sRunner, _get_entity_abs_path, _KubernetesContext, _KubernetesDefinitions
from checkov.kustomize.image_referencer.manager import KustomizeImageReferencerManager
from checkov.kustomize.utils import get_kustomize_version, get_kubectl_version
from checkov.runner_filter import RunnerFilter
Expand Down Expand Up @@ -65,7 +64,7 @@ def __init__(

def set_external_data(
self,
definitions: dict[str, dict[str, Any] | list[dict[str, Any]]] | None,
definitions: _KubernetesDefinitions | None,
context: dict[str, dict[str, Any]] | None,
breadcrumbs: dict[str, dict[str, Any]] | None,
report_mutator_data: dict[str, dict[str, Any]] | None = None,
Expand Down Expand Up @@ -354,7 +353,7 @@ def extract_images(
return images


class Runner(BaseRunner["KubernetesGraphManager"]):
class Runner(BaseRunner[_KubernetesDefinitions, _KubernetesContext, "KubernetesGraphManager"]):
kustomize_command = 'kustomize' # noqa: CCE003 # a static attribute
kubectl_command = 'kubectl' # noqa: CCE003 # a static attribute
check_type = CheckType.KUSTOMIZE # noqa: CCE003 # a static attribute
Expand Down
2 changes: 1 addition & 1 deletion checkov/sca_package/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from checkov.sca_package.scanner import Scanner


class Runner(BaseRunner[None]):
class Runner(BaseRunner[None, None, None]):
check_type = CheckType.SCA_PACKAGE # noqa: CCE003 # a static attribute

def __init__(self, report_type: str = check_type) -> None:
Expand Down
2 changes: 1 addition & 1 deletion checkov/sca_package_2/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from checkov.sca_package_2.scanner import Scanner


class Runner(BaseRunner[None]):
class Runner(BaseRunner[None, None, None]):
check_type = CheckType.SCA_PACKAGE # noqa: CCE003 # a static attribute

def __init__(self, report_type: str = check_type) -> None:
Expand Down
2 changes: 1 addition & 1 deletion checkov/secrets/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
MAX_FILE_SIZE = int(os.getenv('CHECKOV_MAX_FILE_SIZE', '5000000')) # 5 MB is default limit


class Runner(BaseRunner[None]):
class Runner(BaseRunner[None, None, None]):
check_type = CheckType.SECRETS # noqa: CCE003 # a static attribute

def __init__(self, file_extensions: Iterable[str] | None = None, file_names: Iterable[str] | None = None):
Expand Down
Loading

0 comments on commit 3cd73f9

Please sign in to comment.