From 32a70e25cfed1eceb7fc04c94cf8387b980d2219 Mon Sep 17 00:00:00 2001 From: andrecs <12188364+andrecsilva@users.noreply.github.com> Date: Mon, 22 Jan 2024 10:34:03 -0300 Subject: [PATCH 1/7] Sonar results processing and first codemod --- integration_tests/test_numpy_nan_equality.py | 7 +- pyproject.toml | 1 + src/codemodder/codemodder.py | 12 +++ src/codemodder/codemods/base_codemod.py | 81 ++++++++++++------- src/codemodder/codemods/base_visitor.py | 1 + src/codemodder/codemods/sonar.py | 34 ++++++++ src/codemodder/context.py | 6 ++ src/codemodder/file_context.py | 13 ++- src/codemodder/result.py | 3 + src/codemodder/scripts/generate_docs.py | 6 +- src/codemodder/sonar_results.py | 38 +++++++++ src/core_codemods/__init__.py | 11 +++ src/core_codemods/api/core_codemod.py | 29 +++++++ .../sonar_python_numpy-nan-equality-S6725.md | 0 src/core_codemods/numpy_nan_equality.py | 34 +++++--- src/core_codemods/sonar_numpy_nan_equality.py | 34 ++++++++ 16 files changed, 258 insertions(+), 52 deletions(-) create mode 100644 src/codemodder/codemods/sonar.py create mode 100644 src/codemodder/sonar_results.py create mode 100644 src/core_codemods/docs/sonar_python_numpy-nan-equality-S6725.md create mode 100644 src/core_codemods/sonar_numpy_nan_equality.py diff --git a/integration_tests/test_numpy_nan_equality.py b/integration_tests/test_numpy_nan_equality.py index 85ebd36a..9007a9b6 100644 --- a/integration_tests/test_numpy_nan_equality.py +++ b/integration_tests/test_numpy_nan_equality.py @@ -1,4 +1,7 @@ -from core_codemods.numpy_nan_equality import NumpyNanEquality +from core_codemods.numpy_nan_equality import ( + NumpyNanEquality, + NumpyNanEqualityTransformer, +) from integration_tests.base_test import ( BaseIntegrationTest, original_and_expected_from_code_path, @@ -30,5 +33,5 @@ class TestNumpyNanEquality(BaseIntegrationTest): # fmt: on expected_line_change = "4" - change_description = NumpyNanEquality.change_description + change_description = NumpyNanEqualityTransformer.change_description num_changed_files = 1 diff --git a/pyproject.toml b/pyproject.toml index 3034d790..c3e32780 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,6 +74,7 @@ all = [ [project.entry-points.codemods] core = "core_codemods:registry" +sonar = "core_codemods:sonar_registry" [tool.setuptools] diff --git a/src/codemodder/codemodder.py b/src/codemodder/codemodder.py index da471919..448907d9 100644 --- a/src/codemodder/codemodder.py +++ b/src/codemodder/codemodder.py @@ -20,6 +20,7 @@ from codemodder.report.codetf_reporter import report_default from codemodder.result import ResultSet from codemodder.semgrep import run as run_semgrep +from codemodder.sonar_results import SonarResultSet def update_code(file_path, new_code): @@ -136,6 +137,13 @@ def record_dependency_update(dependency_results: dict[Dependency, PackageStore | logger.debug("The following dependencies could not be added: %s", str_list) +def process_sonar_findings(sonar_json_files: list[str]) -> SonarResultSet: + combined_result_set = SonarResultSet() + for file in sonar_json_files or []: + combined_result_set |= SonarResultSet.from_json(file) + return combined_result_set + + def run(original_args) -> int: start = datetime.datetime.now() @@ -156,6 +164,9 @@ def run(original_args) -> int: logger.info("codemodder: python/%s", __version__) logger.info("command: %s %s", Path(sys.argv[0]).name, " ".join(original_args)) + tool_result_files_map = {"sonar": argv.sonar_issues_json} + # TODO find the tool name in the --sarif files here and populate the dict + repo_manager = PythonRepoManager(Path(argv.directory)) context = CodemodExecutionContext( Path(argv.directory), @@ -165,6 +176,7 @@ def run(original_args) -> int: repo_manager, argv.path_include, argv.path_exclude, + tool_result_files_map, argv.max_workers, ) diff --git a/src/codemodder/codemods/base_codemod.py b/src/codemodder/codemods/base_codemod.py index 2a0e5e0c..60ee6f6d 100644 --- a/src/codemodder/codemods/base_codemod.py +++ b/src/codemodder/codemods/base_codemod.py @@ -3,6 +3,7 @@ from dataclasses import dataclass, field from enum import Enum from functools import cached_property +import functools import importlib.resources from importlib.abc import Traversable from pathlib import Path @@ -129,6 +130,30 @@ def describe(self): "references": [ref.to_json() for ref in self.references], } + def _apply( + self, + context: CodemodExecutionContext, + files_to_analyze: list[Path], + rules: list[str], + ) -> None: + results = ( + # It seems like semgrep doesn't like our fully-specified id format + self.detector.apply(self.name, context, files_to_analyze) + if self.detector + else ResultSet() + ) + + process_file = functools.partial( + self._process_file, context=context, results=results, rules=rules + ) + + with ThreadPoolExecutor() as executor: + logger.debug("using executor with %s workers", context.max_workers) + contexts = executor.map(process_file, files_to_analyze) + executor.shutdown(wait=True) + + context.process_results(self.id, contexts) + def apply( self, context: CodemodExecutionContext, @@ -150,36 +175,32 @@ def apply( :param context: The codemod execution context :param files_to_analyze: The list of files to analyze """ - results = ( - # It seems like semgrep doesn't like our fully-specified id format - self.detector.apply(self.name, context, files_to_analyze) - if self.detector - else ResultSet() - ) - - def process_file(filename: Path): - line_exclude = file_line_patterns(filename, context.path_exclude) - line_include = file_line_patterns(filename, context.path_include) - findings_for_rule = results.results_for_rule_and_file(self.name, filename) - - file_context = FileContext( - context.directory, - filename, - line_exclude, - line_include, - findings_for_rule, - ) - - if change_set := self.transformer.apply( - context, file_context, findings_for_rule - ): - file_context.add_result(change_set) + self._apply(context, files_to_analyze, [self.name]) - return file_context + def _process_file( + self, + filename: Path, + context: CodemodExecutionContext, + results: ResultSet, + rules: list[str], + ): + line_exclude = file_line_patterns(filename, context.path_exclude) + line_include = file_line_patterns(filename, context.path_include) + findings_for_rule = [] + for rule in rules: + findings_for_rule.extend(results.results_for_rule_and_file(rule, filename)) + + file_context = FileContext( + context.directory, + filename, + line_exclude, + line_include, + findings_for_rule, + ) - with ThreadPoolExecutor() as executor: - logger.debug("using executor with %s workers", context.max_workers) - contexts = executor.map(process_file, files_to_analyze) - executor.shutdown(wait=True) + if change_set := self.transformer.apply( + context, file_context, findings_for_rule + ): + file_context.add_result(change_set) - context.process_results(self.id, contexts) + return file_context diff --git a/src/codemodder/codemods/base_visitor.py b/src/codemodder/codemods/base_visitor.py index e50c9178..a8477634 100644 --- a/src/codemodder/codemods/base_visitor.py +++ b/src/codemodder/codemods/base_visitor.py @@ -35,6 +35,7 @@ def node_is_selected(self, node) -> bool: return False pos_to_match = self.node_position(node) + print(pos_to_match) return self.filter_by_result( pos_to_match ) and self.filter_by_path_includes_or_excludes(pos_to_match) diff --git a/src/codemodder/codemods/sonar.py b/src/codemodder/codemods/sonar.py new file mode 100644 index 00000000..482cfd4a --- /dev/null +++ b/src/codemodder/codemods/sonar.py @@ -0,0 +1,34 @@ +from pathlib import Path +from codemodder.codemods.base_detector import BaseDetector +from codemodder.context import CodemodExecutionContext +from codemodder.result import ResultSet +from codemodder.sonar_results import SonarResultSet +from core_codemods.api.core_codemod import SASTCodemod + + +class SonarCodemod(SASTCodemod): + @property + def origin(self): + return "sonar" + + +class SonarDetector(BaseDetector): + _lazy_cache = None + + def _process_sonar_findings(self, sonar_json_files: list[str]) -> SonarResultSet: + combined_result_set = SonarResultSet() + for file in sonar_json_files or []: + combined_result_set |= SonarResultSet.from_json(file) + return combined_result_set + + def apply( + self, + codemod_id: str, + context: CodemodExecutionContext, + files_to_analyze: list[Path], + ) -> ResultSet: + if not self._lazy_cache: + self._lazy_cache = self._process_sonar_findings( + context.tool_result_files_map.get("sonar", []) + ) + return self._lazy_cache diff --git a/src/codemodder/context.py b/src/codemodder/context.py index 84811959..a61e80e5 100644 --- a/src/codemodder/context.py +++ b/src/codemodder/context.py @@ -37,6 +37,7 @@ class CodemodExecutionContext: # pylint: disable=too-many-instance-attributes path_include: list[str] path_exclude: list[str] max_workers: int = 1 + tool_result_files_map: dict[str, list[str]] def __init__( self, @@ -47,6 +48,7 @@ def __init__( repo_manager: PythonRepoManager, path_include: list[str], path_exclude: list[str], + tool_result_files_map: dict[str, list[str]] | None = None, max_workers: int = 1, ): # pylint: disable=too-many-arguments self.directory = directory @@ -61,6 +63,10 @@ def __init__( self.path_include = path_include self.path_exclude = path_exclude self.max_workers = max_workers + if tool_result_files_map: + self.tool_result_files_map = tool_result_files_map + else: + self.tool_result_files_map = {} def add_results(self, codemod_name: str, change_sets: List[ChangeSet]): self._results_by_codemod.setdefault(codemod_name, []).extend(change_sets) diff --git a/src/codemodder/file_context.py b/src/codemodder/file_context.py index 9cd5e403..17fc9ff7 100644 --- a/src/codemodder/file_context.py +++ b/src/codemodder/file_context.py @@ -1,6 +1,5 @@ from dataclasses import dataclass, field from pathlib import Path -from typing import List from codemodder.change import Change, ChangeSet from codemodder.dependency import Dependency @@ -16,13 +15,13 @@ class FileContext: # pylint: disable=too-many-instance-attributes base_directory: Path file_path: Path - line_exclude: List[int] = field(default_factory=list) - line_include: List[int] = field(default_factory=list) - findings: List[Result] = field(default_factory=list) + line_exclude: list[int] = field(default_factory=list) + line_include: list[int] = field(default_factory=list) + findings: list[Result] = field(default_factory=list) dependencies: set[Dependency] = field(default_factory=set) - codemod_changes: List[Change] = field(default_factory=list) - results: List[ChangeSet] = field(default_factory=list) - failures: List[Path] = field(default_factory=list) + codemod_changes: list[Change] = field(default_factory=list) + results: list[ChangeSet] = field(default_factory=list) + failures: list[Path] = field(default_factory=list) timer: Timer = field(default_factory=Timer) def add_dependency(self, dependency: Dependency): diff --git a/src/codemodder/result.py b/src/codemodder/result.py index 2409a7b6..b268c7d2 100644 --- a/src/codemodder/result.py +++ b/src/codemodder/result.py @@ -47,3 +47,6 @@ def files_for_rule(self, rule_id: str) -> list[Path]: def all_rule_ids(self) -> list[str]: return list(self.keys()) + + def __or__(self, other): + return ResultSet(super().__or__(other)) diff --git a/src/codemodder/scripts/generate_docs.py b/src/codemodder/scripts/generate_docs.py index 6c43b586..29419f9f 100644 --- a/src/codemodder/scripts/generate_docs.py +++ b/src/codemodder/scripts/generate_docs.py @@ -14,7 +14,7 @@ class DocMetadata: # codemod-specific metadata that's used only for docs, not for codemod API -METADATA = { +CORE_METADATA = { "add-requests-timeouts": DocMetadata( importance="Medium", guidance_explained="This change makes your code safer but in some cases it may be necessary to adjust the timeout value for your particular application.", @@ -224,6 +224,10 @@ class DocMetadata: ), } +METADATA = CORE_METADATA | { + "numpy-nan-equality-S6725": CORE_METADATA["numpy-nan-equality"] +} + def generate_docs(codemod): try: diff --git a/src/codemodder/sonar_results.py b/src/codemodder/sonar_results.py new file mode 100644 index 00000000..31bd6fc0 --- /dev/null +++ b/src/codemodder/sonar_results.py @@ -0,0 +1,38 @@ +import json +from pathlib import Path +from typing_extensions import Self +from codemodder.result import LineInfo, Location, Result, ResultSet + + +class SonarLocation(Location): + @classmethod + def from_issue(cls, issue) -> Self: + location = issue.get("textRange") + start = LineInfo(location.get("startLine"), location.get("startOffset"), "") + end = LineInfo(location.get("endLine"), location.get("endOffset"), "") + file = Path(issue.get("component").split(":")[-1]) + return cls(file=file, start=start, end=end) + + +class SonarResult(Result): + @classmethod + def from_issue(cls, issue) -> Self: + rule_id = issue.get("rule") + if not rule_id: + raise ValueError("Could not extract rule id from sarif result.") + + locations: list[Location] = [SonarLocation.from_issue(issue)] + return cls(rule_id=rule_id, locations=locations) + + +class SonarResultSet(ResultSet): + @classmethod + def from_json(cls, json_file: str | Path) -> Self: + with open(json_file, "r", encoding="utf-8") as file: + data = json.load(file) + + result_set = cls() + for issue in data.get("issues"): + result_set.add_result(SonarResult.from_issue(issue)) + + return result_set diff --git a/src/core_codemods/__init__.py b/src/core_codemods/__init__.py index bf304289..174c3767 100644 --- a/src/core_codemods/__init__.py +++ b/src/core_codemods/__init__.py @@ -50,6 +50,8 @@ from .remove_assertion_in_pytest_raises import RemoveAssertionInPytestRaises from .fix_assert_tuple import FixAssertTuple +from .sonar_numpy_nan_equality import SonarNumpyNanEquality + registry = CodemodCollection( origin="pixee", docs_module="core_codemods.docs", @@ -106,3 +108,12 @@ FixAssertTuple, ], ) + +sonar_registry = CodemodCollection( + origin="sonar", + docs_module="core_codemods.docs", + semgrep_config_module="core_codemods.semgrep", + codemods=[ + SonarNumpyNanEquality, + ], +) diff --git a/src/core_codemods/api/core_codemod.py b/src/core_codemods/api/core_codemod.py index deefb4e4..334bdb3c 100644 --- a/src/core_codemods/api/core_codemod.py +++ b/src/core_codemods/api/core_codemod.py @@ -1,4 +1,9 @@ +from pathlib import Path from codemodder.codemods.api import BaseCodemod, SimpleCodemod as _SimpleCodemod +from codemodder.codemods.base_codemod import Metadata +from codemodder.codemods.base_detector import BaseDetector +from codemodder.codemods.base_transformer import BaseTransformerPipeline +from codemodder.context import CodemodExecutionContext class CoreCodemod(BaseCodemod): @@ -15,6 +20,30 @@ def docs_module_path(self): return "core_codemods.docs" +class SASTCodemod(CoreCodemod): + requested_rules: list[str] + + def __init__( + self, + *, + metadata: Metadata, + detector: BaseDetector | None = None, + transformer: BaseTransformerPipeline, + requested_rules: list[str] | None = None, + ): + super().__init__(metadata=metadata, detector=detector, transformer=transformer) + self.requested_rules = [self.name] + if requested_rules: + self.requested_rules.extend(requested_rules) + + def apply( + self, + context: CodemodExecutionContext, + files_to_analyze: list[Path], + ) -> None: + self._apply(context, files_to_analyze, self.requested_rules) + + class SimpleCodemod(_SimpleCodemod): """ Base class for all core codemods with a single detector and transformer. diff --git a/src/core_codemods/docs/sonar_python_numpy-nan-equality-S6725.md b/src/core_codemods/docs/sonar_python_numpy-nan-equality-S6725.md new file mode 100644 index 00000000..e69de29b diff --git a/src/core_codemods/numpy_nan_equality.py b/src/core_codemods/numpy_nan_equality.py index e63016c6..4d6e988d 100644 --- a/src/core_codemods/numpy_nan_equality.py +++ b/src/core_codemods/numpy_nan_equality.py @@ -1,26 +1,20 @@ import libcst as cst from libcst import UnaryOperation +from codemodder.codemods.libcst_transformer import ( + LibcstResultTransformer, + LibcstTransformerPipeline, +) from codemodder.codemods.utils_mixin import NameResolutionMixin from core_codemods.api import ( Metadata, Reference, ReviewGuidance, - SimpleCodemod, ) +from core_codemods.api.core_codemod import CoreCodemod -class NumpyNanEquality(SimpleCodemod, NameResolutionMixin): - metadata = Metadata( - name="numpy-nan-equality", - summary="Replace == comparison with numpy.isnan()", - review_guidance=ReviewGuidance.MERGE_WITHOUT_REVIEW, - references=[ - Reference( - url="https://numpy.org/doc/stable/reference/constants.html#numpy.nan" - ), - ], - ) +class NumpyNanEqualityTransformer(LibcstResultTransformer, NameResolutionMixin): change_description = "Replaces == check with numpy.isnan()." np_nan = "numpy.nan" @@ -71,3 +65,19 @@ def leave_Comparison( rpar=original_node.rpar, ) return updated_node + + +NumpyNanEquality = CoreCodemod( + metadata=Metadata( + name="numpy-nan-equality", + summary="Replace == comparison with numpy.isnan()", + review_guidance=ReviewGuidance.MERGE_WITHOUT_REVIEW, + references=[ + Reference( + url="https://numpy.org/doc/stable/reference/constants.html#numpy.nan" + ), + ], + ), + transformer=LibcstTransformerPipeline(NumpyNanEqualityTransformer), + detector=None, +) diff --git a/src/core_codemods/sonar_numpy_nan_equality.py b/src/core_codemods/sonar_numpy_nan_equality.py new file mode 100644 index 00000000..7fbc7170 --- /dev/null +++ b/src/core_codemods/sonar_numpy_nan_equality.py @@ -0,0 +1,34 @@ +import libcst as cst +from codemodder.codemods.libcst_transformer import ( + LibcstTransformerPipeline, +) +from codemodder.codemods.sonar import SonarDetector +from codemodder.codemods.sonar import SonarCodemod + +from core_codemods.api import Metadata +from core_codemods.numpy_nan_equality import ( + NumpyNanEquality, + NumpyNanEqualityTransformer, +) + + +class SonarNumpyNanEqualityTransformer(NumpyNanEqualityTransformer): + def leave_Comparison( + self, original_node: cst.Comparison, updated_node: cst.Comparison + ) -> cst.BaseExpression: + if self.filter_by_result(self.node_position(original_node)): + return super().leave_Comparison(original_node, updated_node) + return updated_node + + +SonarNumpyNanEquality = SonarCodemod( + metadata=Metadata( + name="numpy-nan-equality-S6725", + summary=NumpyNanEquality.summary, + review_guidance=NumpyNanEquality._metadata.review_guidance, # pylint: disable=protected-access + references=NumpyNanEquality.references, + ), + transformer=LibcstTransformerPipeline(SonarNumpyNanEqualityTransformer), + detector=SonarDetector(), + requested_rules=["python:S6725"], +) From 11008f1e9d768642b553e74d8c749db82c6cbbc7 Mon Sep 17 00:00:00 2001 From: andrecs <12188364+andrecsilva@users.noreply.github.com> Date: Tue, 23 Jan 2024 09:30:39 -0300 Subject: [PATCH 2/7] Adjusted docs generation and tests --- src/codemodder/codemods/base_codemod.py | 11 +++++------ src/codemodder/scripts/generate_docs.py | 6 +++++- .../docs/sonar_python_numpy-nan-equality-S6725.md | 0 src/core_codemods/order_imports.py | 2 +- src/core_codemods/refactor/refactor_new_api.py | 2 +- src/core_codemods/sonar_numpy_nan_equality.py | 14 +++++++++++--- tests/test_codemod_docs.py | 5 +++-- 7 files changed, 26 insertions(+), 14 deletions(-) delete mode 100644 src/core_codemods/docs/sonar_python_numpy-nan-equality-S6725.md diff --git a/src/codemodder/codemods/base_codemod.py b/src/codemodder/codemods/base_codemod.py index 60ee6f6d..f2c5b2d2 100644 --- a/src/codemodder/codemods/base_codemod.py +++ b/src/codemodder/codemods/base_codemod.py @@ -41,7 +41,7 @@ class Metadata: summary: str review_guidance: ReviewGuidance references: list[Reference] = field(default_factory=list) - has_description: bool = True + description: str | None = None class BaseCodemod(metaclass=ABCMeta): @@ -108,11 +108,10 @@ def docs_module(self) -> Traversable: @cached_property def description(self) -> str: - if not self._metadata.has_description: - return "" - - doc_path = self.docs_module / f"{self.origin}_python_{self.name}.md" - return doc_path.read_text() + if not self._metadata.description: + doc_path = self.docs_module / f"{self.origin}_python_{self.name}.md" + return doc_path.read_text() + return self._metadata.description @property def review_guidance(self): diff --git a/src/codemodder/scripts/generate_docs.py b/src/codemodder/scripts/generate_docs.py index 29419f9f..602b1704 100644 --- a/src/codemodder/scripts/generate_docs.py +++ b/src/codemodder/scripts/generate_docs.py @@ -225,7 +225,11 @@ class DocMetadata: } METADATA = CORE_METADATA | { - "numpy-nan-equality-S6725": CORE_METADATA["numpy-nan-equality"] + "numpy-nan-equality-S6725": DocMetadata( + importance=CORE_METADATA["numpy-nan-equality"].importance, + guidance_explained=CORE_METADATA["numpy-nan-equality"].guidance_explained, + need_sarif="Yes (Sonar)", + ), } diff --git a/src/core_codemods/docs/sonar_python_numpy-nan-equality-S6725.md b/src/core_codemods/docs/sonar_python_numpy-nan-equality-S6725.md deleted file mode 100644 index e69de29b..00000000 diff --git a/src/core_codemods/order_imports.py b/src/core_codemods/order_imports.py index f6c49718..2117ac59 100644 --- a/src/core_codemods/order_imports.py +++ b/src/core_codemods/order_imports.py @@ -14,7 +14,7 @@ class OrderImports(SimpleCodemod): name="order-imports", summary="Order Imports", review_guidance=ReviewGuidance.MERGE_WITHOUT_REVIEW, - has_description=False, + description="", ) change_description = "Ordered and formatted import block below this line" diff --git a/src/core_codemods/refactor/refactor_new_api.py b/src/core_codemods/refactor/refactor_new_api.py index 02453bbf..372d5305 100644 --- a/src/core_codemods/refactor/refactor_new_api.py +++ b/src/core_codemods/refactor/refactor_new_api.py @@ -9,7 +9,7 @@ class RefactorNewApi(SimpleCodemod, NameResolutionMixin): name="refactor-new-api", summary="Refactor to use thew new simplified API", review_guidance=ReviewGuidance.MERGE_AFTER_REVIEW, - has_description=False, + description="", ) new_api_module = "codemodder.codemods.new_api" diff --git a/src/core_codemods/sonar_numpy_nan_equality.py b/src/core_codemods/sonar_numpy_nan_equality.py index 7fbc7170..a8b6f716 100644 --- a/src/core_codemods/sonar_numpy_nan_equality.py +++ b/src/core_codemods/sonar_numpy_nan_equality.py @@ -1,4 +1,5 @@ import libcst as cst +from codemodder.codemods.base_codemod import Reference from codemodder.codemods.libcst_transformer import ( LibcstTransformerPipeline, ) @@ -21,14 +22,21 @@ def leave_Comparison( return updated_node +rules = ["python:S6725"] + SonarNumpyNanEquality = SonarCodemod( metadata=Metadata( name="numpy-nan-equality-S6725", - summary=NumpyNanEquality.summary, + summary="Sonar: " + NumpyNanEquality.summary, review_guidance=NumpyNanEquality._metadata.review_guidance, # pylint: disable=protected-access - references=NumpyNanEquality.references, + references=NumpyNanEquality.references + + [ + Reference(url="https://rules.sonarsource.com/python/type/Bug/RSPEC-6725/"), + ], + description=f"This codemod acts upon the following Sonar rules: {str(rules)[1:-1]}.\n\n" + + NumpyNanEquality.description, ), transformer=LibcstTransformerPipeline(SonarNumpyNanEqualityTransformer), detector=SonarDetector(), - requested_rules=["python:S6725"], + requested_rules=rules, ) diff --git a/tests/test_codemod_docs.py b/tests/test_codemod_docs.py index a8cbdae7..a2fa46f2 100644 --- a/tests/test_codemod_docs.py +++ b/tests/test_codemod_docs.py @@ -12,10 +12,11 @@ def pytest_generate_tests(metafunc): def test_load_codemod_docs_info(codemod: BaseCodemod): - if codemod.name in ["order-imports", "refactor-new-api"]: + print(codemod.name) + if codemod.name in ["order-imports"]: pytest.xfail(reason=f"{codemod.name} has no description") - assert codemod.description is not None # pylint: disable=protected-access + assert codemod.description assert codemod.review_guidance in ( "Merge After Review", "Merge After Cursory Review", From 5d52426ea27ede70f6843e1c9e92df449e0dae0c Mon Sep 17 00:00:00 2001 From: andrecs <12188364+andrecsilva@users.noreply.github.com> Date: Fri, 26 Jan 2024 14:02:42 -0300 Subject: [PATCH 3/7] Tests for sast codemods --- integration_tests/base_test.py | 18 ++++-- .../test_sonar_numpy_nan_equality.py | 38 +++++++++++++ src/codemodder/sonar_results.py | 23 +++++--- tests/codemods/base_codemod_test.py | 57 +++++++++++++++++++ .../codemods/test_sonar_numpy_nan_equality.py | 41 +++++++++++++ tests/samples/sonar_issues.json | 1 + 6 files changed, 165 insertions(+), 13 deletions(-) create mode 100644 integration_tests/test_sonar_numpy_nan_equality.py create mode 100644 tests/codemods/test_sonar_numpy_nan_equality.py create mode 100644 tests/samples/sonar_issues.json diff --git a/integration_tests/base_test.py b/integration_tests/base_test.py index e463c135..afca6189 100644 --- a/integration_tests/base_test.py +++ b/integration_tests/base_test.py @@ -55,6 +55,7 @@ class BaseIntegrationTest(DependencyTestMixin, CleanRepoMixin): _lines = [] num_changed_files = 1 allowed_exceptions = () + sonar_issues_json: str | None = None @classmethod def setup_class(cls): @@ -82,10 +83,16 @@ def _assert_run_fields(self, run, output_path): assert run["tool"] == "codemodder-python" assert run["version"] == __version__ assert run["elapsed"] != "" - assert ( - run["commandLine"] - == f'codemodder {SAMPLES_DIR} --output {output_path} --codemod-include={self.codemod_instance.name} --path-include={code_path} --path-exclude=""' - ) + if self.sonar_issues_json: + assert ( + run["commandLine"] + == f"codemodder {SAMPLES_DIR} --output {output_path} --codemod-include={self.codemod_instance.name} --path-include={code_path} --sonar-issues-json={self.sonar_issues_json}" + ) + else: + assert ( + run["commandLine"] + == f"codemodder {SAMPLES_DIR} --output {output_path} --codemod-include={self.codemod_instance.name} --path-include={code_path}" + ) assert run["directory"] == os.path.abspath(SAMPLES_DIR) assert run["sarifs"] == [] @@ -161,6 +168,9 @@ def test_file_rewritten(self): '--path-exclude=""', ] + if self.sonar_issues_json: + command.append(f"--sonar-issues-json={self.sonar_issues_json}") + self.check_code_before() self.check_dependencies_before() diff --git a/integration_tests/test_sonar_numpy_nan_equality.py b/integration_tests/test_sonar_numpy_nan_equality.py new file mode 100644 index 00000000..c3365ddc --- /dev/null +++ b/integration_tests/test_sonar_numpy_nan_equality.py @@ -0,0 +1,38 @@ +from core_codemods.sonar_numpy_nan_equality import ( + SonarNumpyNanEquality, + SonarNumpyNanEqualityTransformer, +) +from integration_tests.base_test import ( + BaseIntegrationTest, + original_and_expected_from_code_path, +) + + +class TestNumpyNanEquality(BaseIntegrationTest): + codemod = SonarNumpyNanEquality + code_path = "tests/samples/numpy_nan_equality.py" + original_code, expected_new_code = original_and_expected_from_code_path( + code_path, + [ + (3, """if np.isnan(a):\n"""), + ], + ) + sonar_issues_json = "tests/samples/sonar_issues.json" + + # fmt: off + expected_diff =( + """--- \n""" + """+++ \n""" + """@@ -1,5 +1,5 @@\n""" + """ import numpy as np\n""" + """ \n""" + """ a = np.nan\n""" + """-if a == np.nan:\n""" + """+if np.isnan(a):\n""" + """ pass\n""" + ) + # fmt: on + + expected_line_change = "4" + change_description = SonarNumpyNanEqualityTransformer.change_description + num_changed_files = 1 diff --git a/src/codemodder/sonar_results.py b/src/codemodder/sonar_results.py index 31bd6fc0..975607ca 100644 --- a/src/codemodder/sonar_results.py +++ b/src/codemodder/sonar_results.py @@ -2,6 +2,7 @@ from pathlib import Path from typing_extensions import Self from codemodder.result import LineInfo, Location, Result, ResultSet +from codemodder.logging import logger class SonarLocation(Location): @@ -17,7 +18,7 @@ def from_issue(cls, issue) -> Self: class SonarResult(Result): @classmethod def from_issue(cls, issue) -> Self: - rule_id = issue.get("rule") + rule_id = issue.get("rule", None) if not rule_id: raise ValueError("Could not extract rule id from sarif result.") @@ -28,11 +29,15 @@ def from_issue(cls, issue) -> Self: class SonarResultSet(ResultSet): @classmethod def from_json(cls, json_file: str | Path) -> Self: - with open(json_file, "r", encoding="utf-8") as file: - data = json.load(file) - - result_set = cls() - for issue in data.get("issues"): - result_set.add_result(SonarResult.from_issue(issue)) - - return result_set + try: + with open(json_file, "r", encoding="utf-8") as file: + data = json.load(file) + + result_set = cls() + for issue in data.get("issues"): + result_set.add_result(SonarResult.from_issue(issue)) + + return result_set + except Exception: + logger.debug("Could not parse sonar json %s", json_file) + return cls() diff --git a/tests/codemods/base_codemod_test.py b/tests/codemods/base_codemod_test.py index c5ed3112..9de8f263 100644 --- a/tests/codemods/base_codemod_test.py +++ b/tests/codemods/base_codemod_test.py @@ -128,3 +128,60 @@ def create_dir_structure(self, tmpdir): settings_folder = django_root / "mysite" os.makedirs(settings_folder) return (django_root, settings_folder) + + +class BaseSASTCodemodTest(BaseCodemodTest): + tool: ClassVar = NotImplemented + + def run_and_assert( # pylint: disable=too-many-arguments + self, + tmpdir, + input_code, + expected, + num_changes: int = 1, + root: Path | None = None, + files: list[Path] | None = None, + lines_to_exclude: list[int] | None = None, + results: str = "", + ): + root = root or tmpdir + tmp_file_path = files[0] if files else Path(tmpdir) / "code.py" + tmp_file_path.write_text(dedent(input_code)) + + tmp_results_file_path = Path(tmpdir) / "sast_results" + + with open(tmp_results_file_path, "w", encoding="utf-8") as results_file: + results_file.write(results) + + files_to_check = files or [tmp_file_path] + + path_exclude = [f"{tmp_file_path}:{line}" for line in lines_to_exclude or []] + + self.execution_context = CodemodExecutionContext( + directory=root, + dry_run=False, + verbose=False, + tool_result_files_map={self.tool: [str(tmp_results_file_path)]}, + registry=mock.MagicMock(), + repo_manager=mock.MagicMock(), + path_include=[f.name for f in files_to_check], + path_exclude=path_exclude, + ) + + self.codemod.apply(self.execution_context, files_to_check) + changes = self.execution_context.get_results(self.codemod.id) + + if input_code == expected: + assert not changes + return + + assert len(changes) == 1 + assert len(changes[0].changes) == num_changes + + self.assert_changes( + tmpdir, + tmp_file_path, + input_code, + expected, + changes[0], + ) diff --git a/tests/codemods/test_sonar_numpy_nan_equality.py b/tests/codemods/test_sonar_numpy_nan_equality.py new file mode 100644 index 00000000..52d25bf3 --- /dev/null +++ b/tests/codemods/test_sonar_numpy_nan_equality.py @@ -0,0 +1,41 @@ +import json +from core_codemods.sonar_numpy_nan_equality import SonarNumpyNanEquality +from tests.codemods.base_codemod_test import BaseSASTCodemodTest +from textwrap import dedent + + +class TestSonarNumpyNanEquality(BaseSASTCodemodTest): + codemod = SonarNumpyNanEquality + tool = "sonar" + + def test_name(self): + assert self.codemod.name == "numpy-nan-equality-S6725" + + def test_simple(self, tmpdir): + input_code = """\ + import numpy + if a == numpy.nan: + pass + """ + expected = """\ + import numpy + if numpy.isnan(a): + pass + """ + issues = { + "issues": [ + { + "rule": "python:S6725", + "component": f"{tmpdir / 'code.py'}", + "textRange": { + "startLine": 2, + "endLine": 2, + "startOffset": 3, + "endOffset": 17, + }, + } + ] + } + self.run_and_assert( + tmpdir, dedent(input_code), dedent(expected), results=json.dumps(issues) + ) diff --git a/tests/samples/sonar_issues.json b/tests/samples/sonar_issues.json new file mode 100644 index 00000000..5fd08ebf --- /dev/null +++ b/tests/samples/sonar_issues.json @@ -0,0 +1 @@ +{"total":135,"p":1,"ps":500,"paging":{"pageIndex":1,"pageSize":500,"total":135},"effortTotal":729,"issues":[{"key":"AYzPBcZfI9DtgZJSDWTQ","rule":"python:S125","severity":"MAJOR","component":"test:libcstbug.py","project":"test","hash":"1e8c7d758157748821d5638a8c3bd0a6","textRange":{"startLine":13,"endLine":13,"startOffset":8,"endOffset":69},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this commented out code.","effort":"5min","debt":"5min","author":"","tags":["unused"],"creationDate":"2024-01-03T08:11:31-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcZfI9DtgZJSDWTR","rule":"python:S1135","severity":"INFO","component":"test:libcstbug.py","project":"test","hash":"c2dd8aaf32d843f95ee813f9f395fb3a","textRange":{"startLine":56,"endLine":56,"startOffset":0,"endOffset":39},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"","tags":["cwe"],"creationDate":"2024-01-03T08:11:31-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcZ6I9DtgZJSDWTX","rule":"python:S125","severity":"MAJOR","component":"test:test.py","project":"test","hash":"6a9fb82373f1d169019a31cbc5ac664e","textRange":{"startLine":12,"endLine":12,"startOffset":0,"endOffset":19},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this commented out code.","effort":"5min","debt":"5min","author":"","tags":["unused"],"creationDate":"2024-01-03T08:11:31-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcZ6I9DtgZJSDWTY","rule":"python:S5796","severity":"MAJOR","component":"test:test.py","project":"test","hash":"5d07b1ff1be4d3b6d2b036fb06f3f944","textRange":{"startLine":29,"endLine":29,"startOffset":8,"endOffset":10},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Replace this \"is\" operator with \"\u003d\u003d\".","effort":"5min","debt":"5min","author":"","tags":[],"creationDate":"2024-01-03T08:11:31-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"BUG","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"RELIABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcZ6I9DtgZJSDWTZ","rule":"python:S108","severity":"MAJOR","component":"test:test.py","project":"test","hash":"1a1dc91c907325c69271ddf0c944bc72","textRange":{"startLine":30,"endLine":30,"startOffset":4,"endOffset":8},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Either remove or fill this block of code.","effort":"5min","debt":"5min","author":"","tags":["suspicious"],"creationDate":"2024-01-03T08:11:31-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcZ6I9DtgZJSDWTa","rule":"python:S125","severity":"MAJOR","component":"test:test.py","project":"test","hash":"5c22dd3edbfa364683d5156fc07bc417","textRange":{"startLine":37,"endLine":37,"startOffset":0,"endOffset":41},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this commented out code.","effort":"5min","debt":"5min","author":"","tags":["unused"],"creationDate":"2024-01-03T08:11:31-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcZsI9DtgZJSDWTS","rule":"python:S1135","severity":"INFO","component":"test:test2.py","project":"test","hash":"aa08d1463198bfc89ef63e694a9000fb","textRange":{"startLine":22,"endLine":22,"startOffset":8,"endOffset":71},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"","tags":["cwe"],"creationDate":"2024-01-03T08:11:31-0300","updateDate":"2024-01-03T08:20:03-0300","closeDate":"2024-01-03T08:20:03-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcZsI9DtgZJSDWTT","rule":"python:S125","severity":"MAJOR","component":"test:test2.py","project":"test","hash":"814d57ce43e514ceb0657f26b9c53a68","textRange":{"startLine":24,"endLine":24,"startOffset":8,"endOffset":93},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this commented out code.","effort":"5min","debt":"5min","author":"","tags":["unused"],"creationDate":"2024-01-03T08:11:31-0300","updateDate":"2024-01-03T08:20:03-0300","closeDate":"2024-01-03T08:20:03-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcZsI9DtgZJSDWTU","rule":"python:S125","severity":"MAJOR","component":"test:test2.py","project":"test","hash":"6a9fb82373f1d169019a31cbc5ac664e","textRange":{"startLine":27,"endLine":27,"startOffset":0,"endOffset":19},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this commented out code.","effort":"5min","debt":"5min","author":"","tags":["unused"],"creationDate":"2024-01-03T08:11:31-0300","updateDate":"2024-01-03T08:20:03-0300","closeDate":"2024-01-03T08:20:03-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcZsI9DtgZJSDWTV","rule":"python:S125","severity":"MAJOR","component":"test:test2.py","project":"test","hash":"5c22dd3edbfa364683d5156fc07bc417","textRange":{"startLine":48,"endLine":48,"startOffset":0,"endOffset":41},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this commented out code.","effort":"5min","debt":"5min","author":"","tags":["unused"],"creationDate":"2024-01-03T08:11:31-0300","updateDate":"2024-01-03T08:20:03-0300","closeDate":"2024-01-03T08:20:03-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcIxI9DtgZJSDWRX","rule":"python:S5796","severity":"MAJOR","component":"test:tests/samples/literal_or_new_object_identity.py","project":"test","hash":"5f91740da6697d58cdb69e089d79d894","textRange":{"startLine":2,"endLine":2,"startOffset":13,"endOffset":15},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Replace this \"is\" operator with \"\u003d\u003d\".","effort":"5min","debt":"5min","author":"12188364+andrecsilva@users.noreply.github.com","tags":[],"creationDate":"2023-12-21T14:02:41-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"BUG","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"RELIABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcIJI9DtgZJSDWRU","rule":"python:S2208","severity":"CRITICAL","component":"test:tests/samples/future_imports.py","project":"test","hash":"a56a786938a93ed7d67121ef75d2f5a1","textRange":{"startLine":2,"endLine":2,"startOffset":0,"endOffset":24},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Import only needed names or import the module and then use its members.","effort":"5min","debt":"5min","author":"dan.davella@pixee.ai","tags":["pitfall"],"creationDate":"2023-12-20T14:06:01-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcKAI9DtgZJSDWRg","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/samples/requests_timeout.py","project":"test","hash":"2fd7c126440d981f3ce18829c9c03933","textRange":{"startLine":3,"endLine":3,"startOffset":13,"endOffset":34},"flows":[{"locations":[{"component":"test:tests/samples/requests_timeout.py","textRange":{"startLine":4,"endLine":4,"startOffset":13,"endOffset":34},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/samples/requests_timeout.py","textRange":{"startLine":5,"endLine":5,"startOffset":13,"endOffset":34},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/samples/requests_timeout.py","textRange":{"startLine":6,"endLine":6,"startOffset":14,"endOffset":35},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"https://example.com\" 4 times.","effort":"8min","debt":"8min","author":"dan.davella@pixee.ai","tags":["design"],"creationDate":"2023-12-19T15:03:18-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcKAI9DtgZJSDWRh","rule":"python:S4830","severity":"CRITICAL","component":"test:tests/samples/requests_timeout.py","project":"test","hash":"02caea87886dd9bc3563d522a2bbd30b","textRange":{"startLine":5,"endLine":5,"startOffset":60,"endOffset":65},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Enable server certificate validation on this SSL/TLS connection.","effort":"5min","debt":"5min","author":"dan.davella@pixee.ai","tags":["cwe","privacy","ssl"],"creationDate":"2023-12-19T15:03:18-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"VULNERABILITY","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"TRUSTWORTHY","cleanCodeAttributeCategory":"RESPONSIBLE","impacts":[{"softwareQuality":"SECURITY","severity":"HIGH"}]},{"key":"AYzPBcKAI9DtgZJSDWRi","rule":"python:S4830","severity":"CRITICAL","component":"test:tests/samples/requests_timeout.py","project":"test","hash":"78f1767a2f00e6bfe8fca45347545b27","textRange":{"startLine":6,"endLine":6,"startOffset":44,"endOffset":49},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Enable server certificate validation on this SSL/TLS connection.","effort":"5min","debt":"5min","author":"dan.davella@pixee.ai","tags":["cwe","privacy","ssl"],"creationDate":"2023-12-19T15:03:18-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"VULNERABILITY","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"TRUSTWORTHY","cleanCodeAttributeCategory":"RESPONSIBLE","impacts":[{"softwareQuality":"SECURITY","severity":"HIGH"}]},{"key":"AYzPBcZKI9DtgZJSDWTP","rule":"python:S1192","severity":"CRITICAL","component":"test:integration_tests/test_dependency_manager.py","project":"test","hash":"1232977452dce7fd37ead45976af47c4","textRange":{"startLine":60,"endLine":60,"startOffset":12,"endOffset":43},"flows":[{"locations":[{"component":"test:integration_tests/test_dependency_manager.py","textRange":{"startLine":83,"endLine":83,"startOffset":12,"endOffset":43},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:integration_tests/test_dependency_manager.py","textRange":{"startLine":108,"endLine":108,"startOffset":12,"endOffset":43},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:integration_tests/test_dependency_manager.py","textRange":{"startLine":133,"endLine":133,"startOffset":12,"endOffset":43},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"--codemod-include\u003durl-sandbox\" 4 times.","effort":"8min","debt":"8min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["design"],"creationDate":"2023-12-19T08:06:16-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcXjI9DtgZJSDWTL","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/codemodder.py","project":"test","hash":"f96c05d17f52455d64038b35d159eda2","textRange":{"startLine":234,"endLine":234,"startOffset":4,"endOffset":47},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-12-19T08:06:16-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcJsI9DtgZJSDWRe","rule":"python:S5754","severity":"CRITICAL","component":"test:tests/samples/exception_without_raise.py","project":"test","hash":"3e264f5fbab10735799511f21ca70842","textRange":{"startLine":3,"endLine":3,"startOffset":0,"endOffset":6},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Specify an exception class to catch or reraise the exception","effort":"5min","debt":"5min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["bad-practice","error-handling","suspicious"],"creationDate":"2023-12-15T13:52:35-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcJsI9DtgZJSDWRf","rule":"python:S3984","severity":"MAJOR","component":"test:tests/samples/exception_without_raise.py","project":"test","hash":"5a2cfd89b7b171fd7b4794b08023d04f","textRange":{"startLine":2,"endLine":2,"startOffset":4,"endOffset":14},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Raise this exception or remove this useless statement.","effort":"2min","debt":"2min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["error-handling"],"creationDate":"2023-12-15T13:52:35-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"BUG","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"RELIABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcQ8I9DtgZJSDWSN","rule":"python:S3776","severity":"CRITICAL","component":"test:src/core_codemods/flask_json_response_type.py","project":"test","hash":"3571a4d0451af638b1cf47f461516d50","textRange":{"startLine":48,"endLine":48,"startOffset":8,"endOffset":20},"flows":[{"locations":[{"component":"test:src/core_codemods/flask_json_response_type.py","textRange":{"startLine":49,"endLine":49,"startOffset":8,"endOffset":10},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/flask_json_response_type.py","textRange":{"startLine":54,"endLine":54,"startOffset":16,"endOffset":18},"msg":"+2 (incl 1 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/flask_json_response_type.py","textRange":{"startLine":57,"endLine":57,"startOffset":12,"endOffset":14},"msg":"+2 (incl 1 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/flask_json_response_type.py","textRange":{"startLine":59,"endLine":59,"startOffset":16,"endOffset":18},"msg":"+3 (incl 2 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/flask_json_response_type.py","textRange":{"startLine":65,"endLine":65,"startOffset":16,"endOffset":20},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/flask_json_response_type.py","textRange":{"startLine":68,"endLine":68,"startOffset":20,"endOffset":22},"msg":"+4 (incl 3 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/flask_json_response_type.py","textRange":{"startLine":71,"endLine":71,"startOffset":24,"endOffset":26},"msg":"+5 (incl 4 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/flask_json_response_type.py","textRange":{"startLine":76,"endLine":76,"startOffset":20,"endOffset":24},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/flask_json_response_type.py","textRange":{"startLine":91,"endLine":91,"startOffset":16,"endOffset":20},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/flask_json_response_type.py","textRange":{"startLine":94,"endLine":94,"startOffset":20,"endOffset":22},"msg":"+4 (incl 3 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/flask_json_response_type.py","textRange":{"startLine":95,"endLine":95,"startOffset":24,"endOffset":26},"msg":"+5 (incl 4 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/flask_json_response_type.py","textRange":{"startLine":100,"endLine":100,"startOffset":20,"endOffset":24},"msg":"+1","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Refactor this function to reduce its Cognitive Complexity from 30 to the 15 allowed.","effort":"20min","debt":"20min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["brain-overload"],"creationDate":"2023-12-13T12:52:51-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"FOCUSED","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcQ8I9DtgZJSDWSO","rule":"python:S125","severity":"MAJOR","component":"test:src/core_codemods/flask_json_response_type.py","project":"test","hash":"3d0a35112c60b772371f9fe4bfb3b5f3","textRange":{"startLine":90,"endLine":90,"startOffset":16,"endOffset":34},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this commented out code.","effort":"5min","debt":"5min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["unused"],"creationDate":"2023-12-13T12:52:51-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcMeI9DtgZJSDWRs","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/codemods/test_fix_deprecated_abstractproperty.py","project":"test","hash":"0e5bc1bca31277a1bbd488405c796afb","textRange":{"startLine":17,"endLine":25,"startOffset":19,"endOffset":11},"flows":[{"locations":[{"component":"test:tests/codemods/test_fix_deprecated_abstractproperty.py","textRange":{"startLine":37,"endLine":45,"startOffset":19,"endOffset":11},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/codemods/test_fix_deprecated_abstractproperty.py","textRange":{"startLine":57,"endLine":65,"startOffset":19,"endOffset":11},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"\"\"\n import abc\n\n class A:\n @property\n @abc.abstractmethod\n def foo(self):\n pass\n \"\"\" 3 times.","effort":"6min","debt":"6min","author":"dan.davella@pixee.ai","tags":["design"],"creationDate":"2023-12-08T11:49:12-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcG2I9DtgZJSDWRO","rule":"python:S1186","severity":"CRITICAL","component":"test:tests/samples/deprecated_abstractproperty.py","project":"test","hash":"bb3f753715558573f191a0cdb10ec88b","textRange":{"startLine":6,"endLine":6,"startOffset":8,"endOffset":11},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Add a nested comment explaining why this method is empty, or complete the implementation.","effort":"5min","debt":"5min","author":"dan.davella@pixee.ai","tags":["suspicious"],"creationDate":"2023-12-08T11:49:12-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcQoI9DtgZJSDWSJ","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_codemodder.py","project":"test","hash":"1232977452dce7fd37ead45976af47c4","textRange":{"startLine":28,"endLine":28,"startOffset":12,"endOffset":43},"flows":[{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":80,"endLine":80,"startOffset":12,"endOffset":43},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":160,"endLine":160,"startOffset":12,"endOffset":43},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":175,"endLine":175,"startOffset":12,"endOffset":43},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"--codemod-include\u003durl-sandbox\" 4 times.","effort":"8min","debt":"8min","author":"dan.davella@pixee.ai","tags":["design"],"creationDate":"2023-12-07T11:07:59-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcWSI9DtgZJSDWTA","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/project_analysis/file_parsers/setup_py_file_parser.py","project":"test","hash":"c36ba8a0e2d9a33a4451a2a6d3c43df5","textRange":{"startLine":41,"endLine":41,"startOffset":8,"endOffset":61},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-12-05T11:56:23-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcWSI9DtgZJSDWTB","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/project_analysis/file_parsers/setup_py_file_parser.py","project":"test","hash":"4be59fe2fa90221a2f08ae907ff51421","textRange":{"startLine":44,"endLine":44,"startOffset":8,"endOffset":74},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-12-05T11:56:23-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcWSI9DtgZJSDWTC","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/project_analysis/file_parsers/setup_py_file_parser.py","project":"test","hash":"287278dfe304dfa50677cd8dabfc7225","textRange":{"startLine":64,"endLine":64,"startOffset":16,"endOffset":100},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-12-05T11:56:23-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcV3I9DtgZJSDWS-","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/cli.py","project":"test","hash":"98dfc90178ac70701a45dcf9c1fd60a1","textRange":{"startLine":47,"endLine":47,"startOffset":12,"endOffset":73},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-12-01T14:18:50-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcGRI9DtgZJSDWRL","rule":"python:S6725","severity":"BLOCKER","component":"test:tests/samples/numpy_nan_equality.py","project":"test","hash":"75f47436b9576613efd85cdfeaf157ce","textRange":{"startLine":4,"endLine":4,"startOffset":3,"endOffset":14},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Don\u0027t perform an equality/inequality check against \"numpy.nan\".","effort":"2min","debt":"2min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["numpy","python3"],"creationDate":"2023-12-01T14:12:37-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"BUG","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcGRI9DtgZJSDWRM","rule":"python:S108","severity":"MAJOR","component":"test:tests/samples/numpy_nan_equality.py","project":"test","hash":"1a1dc91c907325c69271ddf0c944bc72","textRange":{"startLine":5,"endLine":5,"startOffset":4,"endOffset":8},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Either remove or fill this block of code.","effort":"5min","debt":"5min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["suspicious"],"creationDate":"2023-12-01T14:12:37-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcT3I9DtgZJSDWSp","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/dependency_management/setup_py_writer.py","project":"test","hash":"6d85d784d7d943a1e53c54debb2f2a37","textRange":{"startLine":117,"endLine":117,"startOffset":8,"endOffset":75},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"danalitovsky+git@gmail.com","tags":["cwe"],"creationDate":"2023-12-01T13:41:35-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcPYI9DtgZJSDWR8","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/dependency_management/test_setup_py_writer.py","project":"test","hash":"48df41bfba0d31c40c6528e9b71d345c","textRange":{"startLine":36,"endLine":36,"startOffset":34,"endOffset":44},"flows":[{"locations":[{"component":"test:tests/dependency_management/test_setup_py_writer.py","textRange":{"startLine":120,"endLine":120,"startOffset":34,"endOffset":44},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_setup_py_writer.py","textRange":{"startLine":189,"endLine":189,"startOffset":34,"endOffset":44},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_setup_py_writer.py","textRange":{"startLine":221,"endLine":221,"startOffset":34,"endOffset":44},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_setup_py_writer.py","textRange":{"startLine":253,"endLine":253,"startOffset":34,"endOffset":44},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_setup_py_writer.py","textRange":{"startLine":293,"endLine":293,"startOffset":34,"endOffset":44},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"setup.py\" 6 times.","effort":"12min","debt":"12min","author":"danalitovsky+git@gmail.com","tags":["design"],"creationDate":"2023-12-01T13:41:35-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcPYI9DtgZJSDWR9","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/dependency_management/test_setup_py_writer.py","project":"test","hash":"662c89092c909263426589e6de3c89d6","textRange":{"startLine":43,"endLine":43,"startOffset":21,"endOffset":28},"flows":[{"locations":[{"component":"test:tests/dependency_management/test_setup_py_writer.py","textRange":{"startLine":127,"endLine":127,"startOffset":21,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_setup_py_writer.py","textRange":{"startLine":165,"endLine":165,"startOffset":21,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_setup_py_writer.py","textRange":{"startLine":196,"endLine":196,"startOffset":21,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_setup_py_writer.py","textRange":{"startLine":228,"endLine":228,"startOffset":21,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_setup_py_writer.py","textRange":{"startLine":260,"endLine":260,"startOffset":21,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_setup_py_writer.py","textRange":{"startLine":300,"endLine":300,"startOffset":21,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"\u003e\u003d3.6\" 7 times.","effort":"14min","debt":"14min","author":"danalitovsky+git@gmail.com","tags":["design"],"creationDate":"2023-12-01T13:41:35-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcOeI9DtgZJSDWR3","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/project_analysis/file_parsers/test_pyproject_toml_file_parser.py","project":"test","hash":"6f78e107382b24c52416f7ffdc9b048f","textRange":{"startLine":9,"endLine":9,"startOffset":27,"endOffset":43},"flows":[{"locations":[{"component":"test:tests/project_analysis/file_parsers/test_pyproject_toml_file_parser.py","textRange":{"startLine":37,"endLine":37,"startOffset":27,"endOffset":43},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/project_analysis/file_parsers/test_pyproject_toml_file_parser.py","textRange":{"startLine":58,"endLine":58,"startOffset":35,"endOffset":51},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/project_analysis/file_parsers/test_pyproject_toml_file_parser.py","textRange":{"startLine":68,"endLine":68,"startOffset":35,"endOffset":51},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"pyproject.toml\" 4 times.","effort":"8min","debt":"8min","author":"danalitovsky+git@gmail.com","tags":["design"],"creationDate":"2023-12-01T13:41:35-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcJCI9DtgZJSDWRY","rule":"python:S1186","severity":"CRITICAL","component":"test:tests/samples/django_receiver_on_top.py","project":"test","hash":"255d126a347bf5b478ac390dd2032abc","textRange":{"startLine":7,"endLine":7,"startOffset":4,"endOffset":7},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Add a nested comment explaining why this function is empty, or complete the implementation.","effort":"5min","debt":"5min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["suspicious"],"creationDate":"2023-11-30T15:59:21-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcJDI9DtgZJSDWRZ","rule":"python:S6552","severity":"MAJOR","component":"test:tests/samples/django_receiver_on_top.py","project":"test","hash":"91d1a8baa6977afdf844ab3f2870df56","textRange":{"startLine":6,"endLine":6,"startOffset":0,"endOffset":27},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Move this \u0027@receiver\u0027 decorator to the top of the other decorators.","effort":"5min","debt":"5min","author":"12188364+andrecsilva@users.noreply.github.com","tags":[],"creationDate":"2023-11-30T15:59:21-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"BUG","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"RELIABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcQEI9DtgZJSDWSE","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/conftest.py","project":"test","hash":"18d25a4250def9047fad8eb54bb92a9b","textRange":{"startLine":59,"endLine":59,"startOffset":26,"endOffset":44},"flows":[{"locations":[{"component":"test:tests/conftest.py","textRange":{"startLine":68,"endLine":68,"startOffset":26,"endOffset":44},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/conftest.py","textRange":{"startLine":77,"endLine":77,"startOffset":26,"endOffset":44},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"requirements.txt\" 3 times.","effort":"6min","debt":"6min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["design"],"creationDate":"2023-11-30T14:06:46-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcPOI9DtgZJSDWR6","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/dependency_management/test_pyproject_writer.py","project":"test","hash":"aae0c4f1870a7f2a101b9f6014d168b6","textRange":{"startLine":40,"endLine":40,"startOffset":21,"endOffset":31},"flows":[{"locations":[{"component":"test:tests/dependency_management/test_pyproject_writer.py","textRange":{"startLine":129,"endLine":129,"startOffset":21,"endOffset":31},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_pyproject_writer.py","textRange":{"startLine":182,"endLine":182,"startOffset":21,"endOffset":31},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_pyproject_writer.py","textRange":{"startLine":208,"endLine":208,"startOffset":21,"endOffset":31},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"\u003e\u003d3.10.0\" 4 times.","effort":"8min","debt":"8min","author":"danalitovsky+git@gmail.com","tags":["design"],"creationDate":"2023-11-28T11:02:07-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcPOI9DtgZJSDWR7","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/dependency_management/test_pyproject_writer.py","project":"test","hash":"479fa65038891a22cf227d1806695867","textRange":{"startLine":33,"endLine":33,"startOffset":33,"endOffset":49},"flows":[{"locations":[{"component":"test:tests/dependency_management/test_pyproject_writer.py","textRange":{"startLine":122,"endLine":122,"startOffset":33,"endOffset":49},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_pyproject_writer.py","textRange":{"startLine":175,"endLine":175,"startOffset":33,"endOffset":49},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_pyproject_writer.py","textRange":{"startLine":201,"endLine":201,"startOffset":33,"endOffset":49},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"pyproject.toml\" 4 times.","effort":"8min","debt":"8min","author":"danalitovsky+git@gmail.com","tags":["design"],"creationDate":"2023-11-28T11:02:07-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcVUI9DtgZJSDWS1","rule":"python:S1854","severity":"MAJOR","component":"test:src/codemodder/codemods/utils_mixin.py","project":"test","hash":"d8b1e30e271a4266aa9a4498834e175e","textRange":{"startLine":261,"endLine":261,"startOffset":17,"endOffset":36},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this assignment to local variable \u0027node\u0027; the value is never used.","effort":"1min","debt":"1min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe","unused"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcVUI9DtgZJSDWS2","rule":"python:S1854","severity":"MAJOR","component":"test:src/codemodder/codemods/utils_mixin.py","project":"test","hash":"46974426ff2660b5daaffcc73990b813","textRange":{"startLine":271,"endLine":271,"startOffset":17,"endOffset":38},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this assignment to local variable \u0027node\u0027; the value is never used.","effort":"1min","debt":"1min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe","unused"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcVUI9DtgZJSDWS3","rule":"python:S1854","severity":"MAJOR","component":"test:src/codemodder/codemods/utils_mixin.py","project":"test","hash":"3a5f2ce3a16bc34e54c3525758ce8c15","textRange":{"startLine":281,"endLine":281,"startOffset":17,"endOffset":39},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this assignment to local variable \u0027node\u0027; the value is never used.","effort":"1min","debt":"1min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe","unused"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcVUI9DtgZJSDWS4","rule":"python:S1854","severity":"MAJOR","component":"test:src/codemodder/codemods/utils_mixin.py","project":"test","hash":"a62cfcbefe6dc7818622c29ee5f0e670","textRange":{"startLine":291,"endLine":291,"startOffset":17,"endOffset":40},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this assignment to local variable \u0027node\u0027; the value is never used.","effort":"1min","debt":"1min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe","unused"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcVUI9DtgZJSDWS5","rule":"python:S1854","severity":"MAJOR","component":"test:src/codemodder/codemods/utils_mixin.py","project":"test","hash":"5e29520faa9c51fdd70bf6f7d2016add","textRange":{"startLine":301,"endLine":301,"startOffset":17,"endOffset":36},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this assignment to local variable \u0027node\u0027; the value is never used.","effort":"1min","debt":"1min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe","unused"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcVUI9DtgZJSDWS6","rule":"python:S1854","severity":"MAJOR","component":"test:src/codemodder/codemods/utils_mixin.py","project":"test","hash":"7bea7c267ec7513487ee1dad5990d1b1","textRange":{"startLine":311,"endLine":311,"startOffset":17,"endOffset":42},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this assignment to local variable \u0027node\u0027; the value is never used.","effort":"1min","debt":"1min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe","unused"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcTaI9DtgZJSDWSj","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/file_resource_leak.py","project":"test","hash":"47689e4f4fa83717b662246a02277e86","textRange":{"startLine":176,"endLine":176,"startOffset":8,"endOffset":92},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcTaI9DtgZJSDWSk","rule":"python:S1515","severity":"MAJOR","component":"test:src/core_codemods/file_resource_leak.py","project":"test","hash":"fac86662062d7a7dccca3159c3e4f980","textRange":{"startLine":197,"endLine":197,"startOffset":57,"endOffset":77},"flows":[{"locations":[{"component":"test:src/core_codemods/file_resource_leak.py","textRange":{"startLine":197,"endLine":197,"startOffset":16,"endOffset":22},"msg":"Lambda capturing the variable","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/file_resource_leak.py","textRange":{"startLine":191,"endLine":191,"startOffset":12,"endOffset":32},"msg":"Assignment in the loop","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Add a parameter to the parent lambda function and use variable \"name_escapes_partial\" as its default value; The value of \"name_escapes_partial\" might change at the next loop iteration.","effort":"30min","debt":"30min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["suspicious"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcTaI9DtgZJSDWSl","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/file_resource_leak.py","project":"test","hash":"e1cbddbbd48474fddcb9d041e1bc7143","textRange":{"startLine":270,"endLine":270,"startOffset":12,"endOffset":66},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcTaI9DtgZJSDWSm","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/file_resource_leak.py","project":"test","hash":"646f6a928a5638d0abb6f004e8878756","textRange":{"startLine":361,"endLine":361,"startOffset":12,"endOffset":71},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcTaI9DtgZJSDWSn","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/file_resource_leak.py","project":"test","hash":"5831cc586cde9708ab78700ff5c28371","textRange":{"startLine":366,"endLine":366,"startOffset":12,"endOffset":67},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcTaI9DtgZJSDWSo","rule":"python:S1854","severity":"MAJOR","component":"test:src/core_codemods/file_resource_leak.py","project":"test","hash":"ee21923e539e34c7ef65750720c9f9ba","textRange":{"startLine":398,"endLine":398,"startOffset":17,"endOffset":36},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this assignment to local variable \u0027node\u0027; the value is never used.","effort":"1min","debt":"1min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe","unused"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcHOI9DtgZJSDWRP","rule":"python:S2772","severity":"MINOR","component":"test:tests/samples/file_resource_leak.py","project":"test","hash":"1a1dc91c907325c69271ddf0c944bc72","textRange":{"startLine":4,"endLine":4,"startOffset":0,"endOffset":4},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this unneeded \"pass\".","effort":"2min","debt":"2min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["unused"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcOuI9DtgZJSDWR4","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_ancestorpatterns_mixin.py","project":"test","hash":"8913bec05d784d316371b8684d8d5ce2","textRange":{"startLine":18,"endLine":20,"startOffset":12,"endOffset":11},"flows":[{"locations":[{"component":"test:tests/test_ancestorpatterns_mixin.py","textRange":{"startLine":33,"endLine":35,"startOffset":12,"endOffset":11},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_ancestorpatterns_mixin.py","textRange":{"startLine":51,"endLine":53,"startOffset":12,"endOffset":11},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_ancestorpatterns_mixin.py","textRange":{"startLine":69,"endLine":71,"startOffset":12,"endOffset":11},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_ancestorpatterns_mixin.py","textRange":{"startLine":86,"endLine":88,"startOffset":12,"endOffset":11},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"\"\"\\\n a \u003d 1\n \"\"\" 5 times.","effort":"10min","debt":"10min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["design"],"creationDate":"2023-11-27T13:22:20-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcPEI9DtgZJSDWR5","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/dependency_management/test_requirements_txt_writer.py","project":"test","hash":"74c6d8844e0c487dc8373ff39b6ba818","textRange":{"startLine":17,"endLine":17,"startOffset":41,"endOffset":59},"flows":[{"locations":[{"component":"test:tests/dependency_management/test_requirements_txt_writer.py","textRange":{"startLine":64,"endLine":64,"startOffset":41,"endOffset":59},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_requirements_txt_writer.py","textRange":{"startLine":83,"endLine":83,"startOffset":41,"endOffset":59},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/dependency_management/test_requirements_txt_writer.py","textRange":{"startLine":101,"endLine":101,"startOffset":41,"endOffset":59},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"requirements.txt\" 4 times.","effort":"8min","debt":"8min","author":"danalitovsky+git@gmail.com","tags":["design"],"creationDate":"2023-11-27T11:01:28-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcR8I9DtgZJSDWSe","rule":"python:S125","severity":"MAJOR","component":"test:src/core_codemods/secure_flask_session_config.py","project":"test","hash":"957c69225ed1c33f6df72ecadf1eb76a","textRange":{"startLine":49,"endLine":49,"startOffset":4,"endOffset":32},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this commented out code.","effort":"5min","debt":"5min","author":"danalitovsky+git@gmail.com","tags":["unused"],"creationDate":"2023-11-21T14:05:17-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcR8I9DtgZJSDWSf","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/secure_flask_session_config.py","project":"test","hash":"7bea1c8dec766204e4c1b8852b2ee40e","textRange":{"startLine":107,"endLine":107,"startOffset":16,"endOffset":89},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"danalitovsky+git@gmail.com","tags":["cwe"],"creationDate":"2023-11-21T14:05:17-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcM6I9DtgZJSDWRt","rule":"python:S1135","severity":"INFO","component":"test:tests/codemods/test_secure_flask_session_config.py","project":"test","hash":"ac39714751dd31034f9cd60bb61a3028","textRange":{"startLine":25,"endLine":25,"startOffset":8,"endOffset":70},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"danalitovsky+git@gmail.com","tags":["cwe"],"creationDate":"2023-11-21T14:05:17-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcM6I9DtgZJSDWRu","rule":"python:S1607","severity":"MAJOR","component":"test:tests/codemods/test_secure_flask_session_config.py","project":"test","hash":"49f2f52b4a80eed6228b51a5829b3193","textRange":{"startLine":227,"endLine":227,"startOffset":4,"endOffset":23},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Provide a reason for skipping this test.","effort":"2min","debt":"2min","author":"danalitovsky+git@gmail.com","tags":["bad-practice","confusing","tests"],"creationDate":"2023-11-21T14:05:17-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"TESTED","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcLiI9DtgZJSDWRp","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/codemods/test_enable_jinja2_autoescape.py","project":"test","hash":"303ecda2174e3d482d669af7ac2f5ee4","textRange":{"startLine":17,"endLine":21,"startOffset":26,"endOffset":11},"flows":[{"locations":[{"component":"test:tests/codemods/test_enable_jinja2_autoescape.py","textRange":{"startLine":31,"endLine":35,"startOffset":26,"endOffset":11},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/codemods/test_enable_jinja2_autoescape.py","textRange":{"startLine":94,"endLine":98,"startOffset":21,"endOffset":11},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"\"\"\n import jinja2\n env \u003d jinja2.Environment(autoescape\u003dTrue)\n var \u003d \"hello\"\n \"\"\" 3 times.","effort":"6min","debt":"6min","author":"dan.davella@pixee.ai","tags":["design"],"creationDate":"2023-11-21T12:43:00-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcVhI9DtgZJSDWS7","rule":"python:S1542","severity":"MAJOR","component":"test:src/codemodder/codemods/utils.py","project":"test","hash":"a618840a35db154d8cc2e742c730ba09","textRange":{"startLine":175,"endLine":175,"startOffset":4,"endOffset":23},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Rename function \"is_assigned_to_True\" to match the regular expression ^[a-z_][a-z0-9_]*$.","effort":"10min","debt":"10min","author":"danalitovsky+git@gmail.com","tags":["convention"],"creationDate":"2023-11-20T08:54:00-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"IDENTIFIABLE","cleanCodeAttributeCategory":"CONSISTENT","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcXjI9DtgZJSDWTK","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/codemodder.py","project":"test","hash":"cf0f95fe2e5adc2e0bfd6d5b826251d9","textRange":{"startLine":211,"endLine":211,"startOffset":8,"endOffset":77},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-11-15T13:56:18-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcQoI9DtgZJSDWSK","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_codemodder.py","project":"test","hash":"2aac7ca2e34ecdbb2a47672144b2471e","textRange":{"startLine":21,"endLine":21,"startOffset":26,"endOffset":41},"flows":[{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":73,"endLine":73,"startOffset":26,"endOffset":41},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":116,"endLine":116,"startOffset":26,"endOffset":41},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"result.codetf\" 3 times.","effort":"6min","debt":"6min","author":"dan.davella@pixee.ai","tags":["design"],"creationDate":"2023-11-15T13:56:18-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcRiI9DtgZJSDWSR","rule":"python:S3776","severity":"CRITICAL","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"0567469bfb0aeb9a733014704be8d11c","textRange":{"startLine":91,"endLine":91,"startOffset":8,"endOffset":28},"flows":[{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":93,"endLine":93,"startOffset":23,"endOffset":25},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":93,"endLine":93,"startOffset":64,"endOffset":66},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":98,"endLine":98,"startOffset":8,"endOffset":10},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":101,"endLine":101,"startOffset":8,"endOffset":11},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":103,"endLine":103,"startOffset":12,"endOffset":14},"msg":"+2 (incl 1 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":105,"endLine":105,"startOffset":16,"endOffset":18},"msg":"+3 (incl 2 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":107,"endLine":107,"startOffset":20,"endOffset":22},"msg":"+4 (incl 3 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":107,"endLine":107,"startOffset":63,"endOffset":66},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":110,"endLine":110,"startOffset":12,"endOffset":14},"msg":"+2 (incl 1 for nesting)","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Refactor this function to reduce its Cognitive Complexity from 16 to the 15 allowed.","effort":"6min","debt":"6min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["brain-overload"],"creationDate":"2023-11-15T08:32:24-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"FOCUSED","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcRiI9DtgZJSDWSS","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"2b08d5082998f60dfdd7f4345283450e","textRange":{"startLine":99,"endLine":99,"startOffset":12,"endOffset":48},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-11-15T08:32:24-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcRiI9DtgZJSDWST","rule":"python:S1940","severity":"MINOR","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"5699bad408862ad0644afee69c4249e6","textRange":{"startLine":107,"endLine":107,"startOffset":23,"endOffset":40},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Use the opposite operator (\"not in\") instead.","effort":"2min","debt":"2min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["pitfall"],"creationDate":"2023-11-15T08:32:24-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CONVENTIONAL","cleanCodeAttributeCategory":"CONSISTENT","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcRiI9DtgZJSDWSU","rule":"python:S1940","severity":"MINOR","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"5699bad408862ad0644afee69c4249e6","textRange":{"startLine":107,"endLine":107,"startOffset":45,"endOffset":62},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Use the opposite operator (\"not in\") instead.","effort":"2min","debt":"2min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["pitfall"],"creationDate":"2023-11-15T08:32:24-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CONVENTIONAL","cleanCodeAttributeCategory":"CONSISTENT","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcRiI9DtgZJSDWSV","rule":"python:S1940","severity":"MINOR","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"5699bad408862ad0644afee69c4249e6","textRange":{"startLine":107,"endLine":107,"startOffset":67,"endOffset":84},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Use the opposite operator (\"not in\") instead.","effort":"2min","debt":"2min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["pitfall"],"creationDate":"2023-11-15T08:32:24-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CONVENTIONAL","cleanCodeAttributeCategory":"CONSISTENT","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcRiI9DtgZJSDWSY","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"ad4605ab639f4ab90936235f60c1c9d1","textRange":{"startLine":174,"endLine":174,"startOffset":16,"endOffset":92},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-11-15T08:32:24-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcRiI9DtgZJSDWSc","rule":"python:S5727","severity":"CRITICAL","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"205a2d2939d3a6e2e54c3cec47d225e3","textRange":{"startLine":436,"endLine":436,"startOffset":16,"endOffset":31},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this !\u003d comparison; it will always be True.","effort":"10min","debt":"10min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["suspicious"],"creationDate":"2023-11-15T08:32:24-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcXjI9DtgZJSDWTJ","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/codemodder.py","project":"test","hash":"8a6e51cebb305d6b2c218c4c0d4de44a","textRange":{"startLine":104,"endLine":104,"startOffset":23,"endOffset":48},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-11-06T12:43:33-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcOII9DtgZJSDWR2","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/codemods/test_tempfile_mktemp.py","project":"test","hash":"3d3a0e0f17aca0f930a130198d59b118","textRange":{"startLine":17,"endLine":21,"startOffset":26,"endOffset":3},"flows":[{"locations":[{"component":"test:tests/codemods/test_tempfile_mktemp.py","textRange":{"startLine":45,"endLine":49,"startOffset":26,"endOffset":3},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/codemods/test_tempfile_mktemp.py","textRange":{"startLine":71,"endLine":75,"startOffset":26,"endOffset":3},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"\"\"import tempfile\n\ntempfile.mkstemp()\nvar \u003d \"hello\"\n\"\"\" 3 times.","effort":"6min","debt":"6min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["design"],"creationDate":"2023-10-30T08:44:21-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcQxI9DtgZJSDWSM","rule":"python:S3776","severity":"CRITICAL","component":"test:src/core_codemods/remove_unused_imports.py","project":"test","hash":"0ac87518a3304e5b0727e9b51521e715","textRange":{"startLine":76,"endLine":76,"startOffset":8,"endOffset":30},"flows":[{"locations":[{"component":"test:src/core_codemods/remove_unused_imports.py","textRange":{"startLine":81,"endLine":81,"startOffset":8,"endOffset":10},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/remove_unused_imports.py","textRange":{"startLine":81,"endLine":81,"startOffset":18,"endOffset":21},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/remove_unused_imports.py","textRange":{"startLine":88,"endLine":88,"startOffset":12,"endOffset":14},"msg":"+2 (incl 1 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/remove_unused_imports.py","textRange":{"startLine":91,"endLine":91,"startOffset":12,"endOffset":15},"msg":"+2 (incl 1 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/remove_unused_imports.py","textRange":{"startLine":93,"endLine":93,"startOffset":16,"endOffset":18},"msg":"+3 (incl 2 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/remove_unused_imports.py","textRange":{"startLine":93,"endLine":93,"startOffset":43,"endOffset":46},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/remove_unused_imports.py","textRange":{"startLine":97,"endLine":97,"startOffset":16,"endOffset":18},"msg":"+3 (incl 2 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/remove_unused_imports.py","textRange":{"startLine":97,"endLine":97,"startOffset":43,"endOffset":46},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/remove_unused_imports.py","textRange":{"startLine":103,"endLine":103,"startOffset":12,"endOffset":14},"msg":"+2 (incl 1 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/remove_unused_imports.py","textRange":{"startLine":113,"endLine":113,"startOffset":16,"endOffset":18},"msg":"+3 (incl 2 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/remove_unused_imports.py","textRange":{"startLine":115,"endLine":115,"startOffset":16,"endOffset":18},"msg":"+3 (incl 2 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/remove_unused_imports.py","textRange":{"startLine":115,"endLine":115,"startOffset":34,"endOffset":37},"msg":"+1","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Refactor this function to reduce its Cognitive Complexity from 23 to the 15 allowed.","effort":"13min","debt":"13min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["brain-overload"],"creationDate":"2023-10-26T11:19:08-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"FOCUSED","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcWSI9DtgZJSDWS_","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/project_analysis/file_parsers/setup_py_file_parser.py","project":"test","hash":"52a56b667f4f113d16f3209279dcee76","textRange":{"startLine":24,"endLine":24,"startOffset":8,"endOffset":59},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"112832187+clavedeluna@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-10-25T15:42:40-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcRiI9DtgZJSDWSW","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"ebe919da568ed21e702a6c28ca548ebc","textRange":{"startLine":156,"endLine":156,"startOffset":12,"endOffset":68},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-10-25T07:34:25-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcRiI9DtgZJSDWSX","rule":"python:S125","severity":"MAJOR","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"0a0d27fc8736e0d9501ee9f261af287e","textRange":{"startLine":160,"endLine":160,"startOffset":16,"endOffset":92},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this commented out code.","effort":"5min","debt":"5min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["unused"],"creationDate":"2023-10-25T07:34:25-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcRiI9DtgZJSDWSZ","rule":"python:S3776","severity":"CRITICAL","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"685f1120b13fb96aecc914e766298620","textRange":{"startLine":322,"endLine":322,"startOffset":8,"endOffset":20},"flows":[{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":324,"endLine":324,"startOffset":8,"endOffset":10},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":330,"endLine":330,"startOffset":12,"endOffset":14},"msg":"+2 (incl 1 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":333,"endLine":333,"startOffset":16,"endOffset":19},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":336,"endLine":336,"startOffset":16,"endOffset":18},"msg":"+3 (incl 2 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":339,"endLine":339,"startOffset":28,"endOffset":30},"msg":"+5 (incl 4 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":343,"endLine":343,"startOffset":32,"endOffset":34},"msg":"+6 (incl 5 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/sql_parameterization.py","textRange":{"startLine":343,"endLine":343,"startOffset":49,"endOffset":52},"msg":"+1","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Refactor this function to reduce its Cognitive Complexity from 19 to the 15 allowed.","effort":"9min","debt":"9min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["brain-overload"],"creationDate":"2023-10-25T07:34:25-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"FOCUSED","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcRiI9DtgZJSDWSa","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"dff842d2d3d2e587c4549cc5b4d3f4b0","textRange":{"startLine":326,"endLine":326,"startOffset":12,"endOffset":74},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-10-25T07:34:25-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcRiI9DtgZJSDWSb","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"c09bee826d59afe89b5164fdf2c14579","textRange":{"startLine":350,"endLine":350,"startOffset":8,"endOffset":75},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-10-25T07:34:25-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcRjI9DtgZJSDWSd","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/sql_parameterization.py","project":"test","hash":"7375285788564d767e34f8aef28d0bd4","textRange":{"startLine":495,"endLine":495,"startOffset":12,"endOffset":69},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-10-25T07:34:25-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcPmI9DtgZJSDWR-","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/transformations/test_remove_empty_string_concatenation.py","project":"test","hash":"1118bda070b69858e9cd4f8e9c4921c3","textRange":{"startLine":22,"endLine":24,"startOffset":16,"endOffset":11},"flows":[{"locations":[{"component":"test:tests/transformations/test_remove_empty_string_concatenation.py","textRange":{"startLine":75,"endLine":77,"startOffset":17,"endOffset":11},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/transformations/test_remove_empty_string_concatenation.py","textRange":{"startLine":79,"endLine":81,"startOffset":16,"endOffset":11},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"\"\"\n \"world\"\n \"\"\" 3 times.","effort":"6min","debt":"6min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["design"],"creationDate":"2023-10-25T07:34:25-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcWiI9DtgZJSDWTD","rule":"python:S116","severity":"MINOR","component":"test:src/codemodder/change.py","project":"test","hash":"a82a82bf23555880c7db221af687328f","textRange":{"startLine":32,"endLine":32,"startOffset":4,"endOffset":14},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Rename this field \"lineNumber\" to match the regular expression ^[_a-z][_a-z0-9]*$.","effort":"2min","debt":"2min","author":"dan.davella@pixee.ai","tags":["convention"],"creationDate":"2023-10-24T14:47:05-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"IDENTIFIABLE","cleanCodeAttributeCategory":"CONSISTENT","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcWiI9DtgZJSDWTE","rule":"python:S116","severity":"MINOR","component":"test:src/codemodder/change.py","project":"test","hash":"3e216fc5e039b16091f394be50dfed2c","textRange":{"startLine":35,"endLine":35,"startOffset":4,"endOffset":18},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Rename this field \"packageActions\" to match the regular expression ^[_a-z][_a-z0-9]*$.","effort":"2min","debt":"2min","author":"dan.davella@pixee.ai","tags":["convention"],"creationDate":"2023-10-24T14:47:05-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"IDENTIFIABLE","cleanCodeAttributeCategory":"CONSISTENT","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcRUI9DtgZJSDWSP","rule":"python:S4144","severity":"MAJOR","component":"test:src/core_codemods/use_defused_xml.py","project":"test","hash":"fe7eab4e1362f4cbcb9e394c60943748","textRange":{"startLine":26,"endLine":26,"startOffset":8,"endOffset":26},"flows":[{"locations":[{"component":"test:src/core_codemods/use_defused_xml.py","textRange":{"startLine":14,"endLine":14,"startOffset":8,"endOffset":24},"msg":"Original","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Update this function so that its implementation is not identical to update_attribute on line 14.","effort":"15min","debt":"15min","author":"dan.davella@pixee.ai","tags":["confusing","duplicate","suspicious"],"creationDate":"2023-10-23T14:02:06-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcP0I9DtgZJSDWSA","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_code_directory.py","project":"test","hash":"e2cb8bf8980412085b4ca608a4b7ac5e","textRange":{"startLine":45,"endLine":45,"startOffset":44,"endOffset":57},"flows":[{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":56,"endLine":56,"startOffset":42,"endOffset":55},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":68,"endLine":68,"startOffset":42,"endOffset":55},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":75,"endLine":75,"startOffset":44,"endOffset":57},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":82,"endLine":82,"startOffset":48,"endOffset":61},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":87,"endLine":87,"startOffset":44,"endOffset":57},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":99,"endLine":99,"startOffset":27,"endOffset":40},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":123,"endLine":123,"startOffset":54,"endOffset":67},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"**/tests/**\" 8 times.","effort":"16min","debt":"16min","author":"dan.davella@pixee.ai","tags":["design"],"creationDate":"2023-10-18T12:08:21-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcP0I9DtgZJSDWSD","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_code_directory.py","project":"test","hash":"e2cb8bf8980412085b4ca608a4b7ac5e","textRange":{"startLine":45,"endLine":45,"startOffset":59,"endOffset":72},"flows":[{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":87,"endLine":87,"startOffset":59,"endOffset":72},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":92,"endLine":92,"startOffset":58,"endOffset":71},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":99,"endLine":99,"startOffset":42,"endOffset":55},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":100,"endLine":100,"startOffset":27,"endOffset":40},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"*request.py\" 5 times.","effort":"10min","debt":"10min","author":"dan.davella@pixee.ai","tags":["design"],"creationDate":"2023-10-18T12:08:21-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcRUI9DtgZJSDWSQ","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/use_defused_xml.py","project":"test","hash":"13c4a2aa6d56999ff54e6eeae24a79cd","textRange":{"startLine":42,"endLine":42,"startOffset":0,"endOffset":26},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-10-17T17:41:22-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcXwI9DtgZJSDWTO","rule":"python:S1135","severity":"INFO","component":"test:integration_tests/base_test.py","project":"test","hash":"96b05a479486143e5ada499221918739","textRange":{"startLine":91,"endLine":91,"startOffset":8,"endOffset":53},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"112832187+clavedeluna@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-10-16T17:07:48-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcVKI9DtgZJSDWS0","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/codemods/base_codemod.py","project":"test","hash":"9c5eef0f414d06ed3856c860e066ab1a","textRange":{"startLine":27,"endLine":27,"startOffset":4,"endOffset":84},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"112832187+clavedeluna@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-10-16T17:07:48-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcXjI9DtgZJSDWTI","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/codemodder.py","project":"test","hash":"b020c8869015e3bae50b32fc468d8fc3","textRange":{"startLine":68,"endLine":68,"startOffset":4,"endOffset":80},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-10-12T10:16:53-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcLFI9DtgZJSDWRn","rule":"python:S905","severity":"MAJOR","component":"test:tests/samples/unordered_imports.py","project":"test","hash":"a69ecad8d4c393f07611b4a373a17690","textRange":{"startLine":21,"endLine":21,"startOffset":0,"endOffset":8},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove or refactor this statement; it has no side effects.","effort":"10min","debt":"10min","author":"112832187+clavedeluna@users.noreply.github.com","tags":["cwe","unused"],"creationDate":"2023-10-11T08:20:03-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"BUG","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"RELIABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcHwI9DtgZJSDWRS","rule":"python:S4830","severity":"CRITICAL","component":"test:tests/samples/unverified_request.py","project":"test","hash":"ea3b3f3aef1af2433a70e2aa07fb5b73","textRange":{"startLine":3,"endLine":3,"startOffset":46,"endOffset":51},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Enable server certificate validation on this SSL/TLS connection.","effort":"5min","debt":"5min","author":"112832187+clavedeluna@users.noreply.github.com","tags":["cwe","privacy","ssl"],"creationDate":"2023-10-11T08:20:03-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"VULNERABILITY","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"TRUSTWORTHY","cleanCodeAttributeCategory":"RESPONSIBLE","impacts":[{"softwareQuality":"SECURITY","severity":"HIGH"}]},{"key":"AYzPBcHwI9DtgZJSDWRT","rule":"python:S4830","severity":"CRITICAL","component":"test:tests/samples/unverified_request.py","project":"test","hash":"84aa604144fc14abffd3885b983ff327","textRange":{"startLine":4,"endLine":4,"startOffset":74,"endOffset":79},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Enable server certificate validation on this SSL/TLS connection.","effort":"5min","debt":"5min","author":"112832187+clavedeluna@users.noreply.github.com","tags":["cwe","privacy","ssl"],"creationDate":"2023-10-11T08:20:03-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"VULNERABILITY","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"TRUSTWORTHY","cleanCodeAttributeCategory":"RESPONSIBLE","impacts":[{"softwareQuality":"SECURITY","severity":"HIGH"}]},{"key":"AYzPBcXjI9DtgZJSDWTM","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/codemodder.py","project":"test","hash":"d5ed695823aa4a42ba82992e6ba29760","textRange":{"startLine":283,"endLine":283,"startOffset":4,"endOffset":62},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-10-06T10:44:38-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcVvI9DtgZJSDWS8","rule":"python:S1845","severity":"BLOCKER","component":"test:src/codemodder/executor.py","project":"test","hash":"04893828668d065fc909980e52cf0685","textRange":{"startLine":52,"endLine":52,"startOffset":20,"endOffset":27},"flows":[{"locations":[{"component":"test:src/codemodder/executor.py","textRange":{"startLine":51,"endLine":51,"startOffset":8,"endOffset":15},"msg":"Original","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Rename field \"SUMMARY\" to prevent any misunderstanding/clash with method \"summary\" defined on line 51","effort":"10min","debt":"10min","author":"dan.davella@pixee.ai","tags":["confusing"],"creationDate":"2023-10-06T10:44:38-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"IDENTIFIABLE","cleanCodeAttributeCategory":"CONSISTENT","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcVvI9DtgZJSDWS9","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/executor.py","project":"test","hash":"eb7467dab57a08d5a57349ec1151487f","textRange":{"startLine":63,"endLine":63,"startOffset":12,"endOffset":40},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-10-06T10:44:38-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcJhI9DtgZJSDWRc","rule":"python:S1172","severity":"MAJOR","component":"test:tests/samples/multiple_codemods.py","project":"test","hash":"897fcddf59670aac30c79a7627e74ca4","textRange":{"startLine":4,"endLine":4,"startOffset":9,"endOffset":15},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove the unused function parameter \"foo\".","effort":"5min","debt":"5min","author":"dan.davella@pixee.ai","tags":["unused"],"creationDate":"2023-10-06T10:44:38-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcTCI9DtgZJSDWSi","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/with_threading_lock.py","project":"test","hash":"029ad2afce36e51fce7cdcea3794a2a3","textRange":{"startLine":85,"endLine":85,"startOffset":12,"endOffset":30},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-10-02T17:46:33-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcMAI9DtgZJSDWRq","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/codemods/test_secure_random.py","project":"test","hash":"d075d52b2ca7cb6c037e07df851622a7","textRange":{"startLine":18,"endLine":22,"startOffset":26,"endOffset":3},"flows":[{"locations":[{"component":"test:tests/codemods/test_secure_random.py","textRange":{"startLine":32,"endLine":36,"startOffset":26,"endOffset":3},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/codemods/test_secure_random.py","textRange":{"startLine":45,"endLine":49,"startOffset":26,"endOffset":3},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"\"\"import secrets\n\nsecrets.SystemRandom().random()\nvar \u003d \"hello\"\n\"\"\" 3 times.","effort":"6min","debt":"6min","author":"dan.davella@pixee.ai","tags":["design"],"creationDate":"2023-09-28T12:40:21-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcXOI9DtgZJSDWTH","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/registry.py","project":"test","hash":"99436775ca3400ce2f44211ae8af0189","textRange":{"startLine":76,"endLine":76,"startOffset":8,"endOffset":81},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-09-27T10:37:56-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcSkI9DtgZJSDWSh","rule":"python:S3776","severity":"CRITICAL","component":"test:src/core_codemods/fix_mutable_params.py","project":"test","hash":"a779d965b12fae50895ab9634a68d732","textRange":{"startLine":55,"endLine":55,"startOffset":8,"endOffset":33},"flows":[{"locations":[{"component":"test:src/core_codemods/fix_mutable_params.py","textRange":{"startLine":63,"endLine":63,"startOffset":8,"endOffset":11},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/fix_mutable_params.py","textRange":{"startLine":68,"endLine":68,"startOffset":12,"endOffset":14},"msg":"+2 (incl 1 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/fix_mutable_params.py","textRange":{"startLine":69,"endLine":69,"startOffset":16,"endOffset":18},"msg":"+3 (incl 2 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/fix_mutable_params.py","textRange":{"startLine":73,"endLine":73,"startOffset":16,"endOffset":20},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/fix_mutable_params.py","textRange":{"startLine":81,"endLine":81,"startOffset":24,"endOffset":26},"msg":"+4 (incl 3 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/fix_mutable_params.py","textRange":{"startLine":87,"endLine":87,"startOffset":55,"endOffset":57},"msg":"+2 (incl 1 for nesting)","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/fix_mutable_params.py","textRange":{"startLine":89,"endLine":89,"startOffset":44,"endOffset":46},"msg":"+1","msgFormattings":[]}]},{"locations":[{"component":"test:src/core_codemods/fix_mutable_params.py","textRange":{"startLine":95,"endLine":95,"startOffset":16,"endOffset":18},"msg":"+2 (incl 1 for nesting)","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Refactor this function to reduce its Cognitive Complexity from 16 to the 15 allowed.","effort":"6min","debt":"6min","author":"dan.davella@pixee.ai","tags":["brain-overload"],"creationDate":"2023-09-27T09:52:11-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"FOCUSED","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcN-I9DtgZJSDWR0","rule":"python:S4144","severity":"MAJOR","component":"test:tests/codemods/test_fix_mutable_params.py","project":"test","hash":"16ee39db1caaf8decec36f4b43c38053","textRange":{"startLine":40,"endLine":40,"startOffset":8,"endOffset":24},"flows":[{"locations":[{"component":"test:tests/codemods/test_fix_mutable_params.py","textRange":{"startLine":12,"endLine":12,"startOffset":8,"endOffset":27},"msg":"Original","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Update this function so that its implementation is not identical to test_fix_single_arg on line 12.","effort":"15min","debt":"15min","author":"dan.davella@pixee.ai","tags":["confusing","duplicate","suspicious"],"creationDate":"2023-09-27T09:52:11-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcN-I9DtgZJSDWR1","rule":"python:S4144","severity":"MAJOR","component":"test:tests/codemods/test_fix_mutable_params.py","project":"test","hash":"30d26fa325706af7eb5eea1ad815b3e6","textRange":{"startLine":66,"endLine":66,"startOffset":8,"endOffset":52},"flows":[{"locations":[{"component":"test:tests/codemods/test_fix_mutable_params.py","textRange":{"startLine":12,"endLine":12,"startOffset":8,"endOffset":27},"msg":"Original","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Update this function so that its implementation is not identical to test_fix_single_arg on line 12.","effort":"15min","debt":"15min","author":"dan.davella@pixee.ai","tags":["confusing","duplicate","suspicious"],"creationDate":"2023-09-27T09:52:11-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcFxI9DtgZJSDWRH","rule":"python:S5717","severity":"CRITICAL","component":"test:tests/samples/mutable_params.py","project":"test","hash":"167abb9ce3c4bf099dd3608f2d2d5726","textRange":{"startLine":1,"endLine":1,"startOffset":11,"endOffset":15},"flows":[{"locations":[{"component":"test:tests/samples/mutable_params.py","textRange":{"startLine":2,"endLine":2,"startOffset":4,"endOffset":12},"msg":"The parameter is modified.","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Change this default value to \"None\" and initialize this parameter inside the function/method.","effort":"5min","debt":"5min","author":"dan.davella@pixee.ai","tags":[],"creationDate":"2023-09-27T09:52:11-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcKfI9DtgZJSDWRk","rule":"python:S5659","severity":"CRITICAL","component":"test:tests/samples/jwt_decode_verify.py","project":"test","hash":"8598834dd9e7ac08ec3cbeffb8e78ae9","textRange":{"startLine":11,"endLine":11,"startOffset":76,"endOffset":88},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Don\u0027t use a JWT token without verifying its signature.","effort":"30min","debt":"30min","author":"112832187+clavedeluna@users.noreply.github.com","tags":["cwe","privacy"],"creationDate":"2023-09-26T13:18:34-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"VULNERABILITY","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"TRUSTWORTHY","cleanCodeAttributeCategory":"RESPONSIBLE","impacts":[{"softwareQuality":"SECURITY","severity":"HIGH"}]},{"key":"AYzPBcKtI9DtgZJSDWRl","rule":"python:S3457","severity":"MAJOR","component":"test:tests/samples/unnecessary_f_str.py","project":"test","hash":"c39e32ff2d055f520e3af7fd51508c08","textRange":{"startLine":1,"endLine":1,"startOffset":6,"endOffset":14},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Add replacement fields or use a normal string instead of an f-string.","effort":"1min","debt":"1min","author":"dan.davella@pixee.ai","tags":["confusing"],"creationDate":"2023-09-21T11:16:47-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"LOGICAL","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcNHI9DtgZJSDWRv","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/codemods/test_https_connection.py","project":"test","hash":"84389ebc75334ae1ee635437033bed91","textRange":{"startLine":9,"endLine":12,"startOffset":17,"endOffset":3},"flows":[{"locations":[{"component":"test:tests/codemods/test_https_connection.py","textRange":{"startLine":21,"endLine":24,"startOffset":16,"endOffset":3},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/codemods/test_https_connection.py","textRange":{"startLine":45,"endLine":48,"startOffset":16,"endOffset":3},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal r\"\"\"import urllib3\n\nurllib3.HTTPSConnectionPool(\"localhost\", \"80\")\n\"\"\" 3 times.","effort":"6min","debt":"6min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["design"],"creationDate":"2023-09-14T13:20:58-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcXwI9DtgZJSDWTN","rule":"python:S1135","severity":"INFO","component":"test:integration_tests/base_test.py","project":"test","hash":"e1359fc5d357b3494d8a2818515c5a1d","textRange":{"startLine":22,"endLine":22,"startOffset":8,"endOffset":68},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-09-11T17:47:27-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcQoI9DtgZJSDWSI","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_codemodder.py","project":"test","hash":"fee6b861d077bd05e3b46e6afbd56e05","textRange":{"startLine":44,"endLine":44,"startOffset":12,"endOffset":22},"flows":[{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":97,"endLine":97,"startOffset":12,"endOffset":22},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":143,"endLine":143,"startOffset":12,"endOffset":22},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":159,"endLine":159,"startOffset":12,"endOffset":22},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":174,"endLine":174,"startOffset":12,"endOffset":22},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":187,"endLine":187,"startOffset":12,"endOffset":22},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":204,"endLine":204,"startOffset":12,"endOffset":22},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"here.txt\" 7 times.","effort":"14min","debt":"14min","author":"danalitovsky+git@gmail.com","tags":["design"],"creationDate":"2023-09-07T10:36:30-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcQoI9DtgZJSDWSL","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_codemodder.py","project":"test","hash":"1df43442ac0bdd54ab6e83b7a1e666b8","textRange":{"startLine":25,"endLine":25,"startOffset":12,"endOffset":28},"flows":[{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":42,"endLine":42,"startOffset":12,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":75,"endLine":75,"startOffset":12,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":95,"endLine":95,"startOffset":12,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":122,"endLine":122,"startOffset":12,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":141,"endLine":141,"startOffset":12,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":157,"endLine":157,"startOffset":12,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":185,"endLine":185,"startOffset":12,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_codemodder.py","textRange":{"startLine":202,"endLine":202,"startOffset":12,"endOffset":28},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"tests/samples/\" 9 times.","effort":"18min","debt":"18min","author":"danalitovsky+git@gmail.com","tags":["design"],"creationDate":"2023-09-07T10:36:30-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcW2I9DtgZJSDWTF","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/report/codetf_reporter.py","project":"test","hash":"a7dcf5a9174dade2ca2e798e85ae2b36","textRange":{"startLine":32,"endLine":32,"startOffset":8,"endOffset":72},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-09-07T10:27:37-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcQQI9DtgZJSDWSG","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_cli.py","project":"test","hash":"fee6b861d077bd05e3b46e6afbd56e05","textRange":{"startLine":116,"endLine":116,"startOffset":20,"endOffset":30},"flows":[{"locations":[{"component":"test:tests/test_cli.py","textRange":{"startLine":136,"endLine":136,"startOffset":20,"endOffset":30},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_cli.py","textRange":{"startLine":156,"endLine":156,"startOffset":16,"endOffset":26},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"here.txt\" 3 times.","effort":"6min","debt":"6min","author":"112832187+clavedeluna@users.noreply.github.com","tags":["design"],"creationDate":"2023-09-06T10:57:04-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcQQI9DtgZJSDWSH","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_cli.py","project":"test","hash":"1df43442ac0bdd54ab6e83b7a1e666b8","textRange":{"startLine":114,"endLine":114,"startOffset":20,"endOffset":36},"flows":[{"locations":[{"component":"test:tests/test_cli.py","textRange":{"startLine":134,"endLine":134,"startOffset":20,"endOffset":36},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_cli.py","textRange":{"startLine":154,"endLine":154,"startOffset":16,"endOffset":32},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"tests/samples/\" 3 times.","effort":"6min","debt":"6min","author":"112832187+clavedeluna@users.noreply.github.com","tags":["design"],"creationDate":"2023-09-06T10:57:04-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcUwI9DtgZJSDWSv","rule":"python:S125","severity":"MAJOR","component":"test:src/codemodder/codemods/transformations/clean_imports.py","project":"test","hash":"6b66f9b1baacb6376cb584c545a3a380","textRange":{"startLine":112,"endLine":112,"startOffset":12,"endOffset":70},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Remove this commented out code.","effort":"5min","debt":"5min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["unused"],"creationDate":"2023-09-05T11:10:24-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcGjI9DtgZJSDWRN","rule":"python:S5445","severity":"CRITICAL","component":"test:tests/samples/tempfile_mktemp.py","project":"test","hash":"8195d0462d01b50e04cc6ec8ac1afaf6","textRange":{"startLine":3,"endLine":3,"startOffset":0,"endOffset":17},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"\u0027tempfile.mktemp\u0027 is insecure. Use \u0027tempfile.TemporaryFile\u0027 instead","effort":"10min","debt":"10min","author":"112832187+clavedeluna@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-09-01T09:59:16-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"VULNERABILITY","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"SECURITY","severity":"HIGH"}]},{"key":"AYzPBcURI9DtgZJSDWSq","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/codemods/api/__init__.py","project":"test","hash":"5fa929e16492449bb3e8cffebfa0acdf","textRange":{"startLine":27,"endLine":27,"startOffset":4,"endOffset":45},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-08-28T12:18:15-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcURI9DtgZJSDWSr","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/codemods/api/__init__.py","project":"test","hash":"74efb9020568982cfa92a7c6a46b6eed","textRange":{"startLine":51,"endLine":51,"startOffset":12,"endOffset":76},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-08-28T12:18:15-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcURI9DtgZJSDWSs","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/codemods/api/__init__.py","project":"test","hash":"aa12fb226f5e8d551de3044014365b6b","textRange":{"startLine":125,"endLine":125,"startOffset":4,"endOffset":73},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-08-28T12:18:15-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcUdI9DtgZJSDWSt","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/codemods/api/helpers.py","project":"test","hash":"94acc27948b3c58680dc668cdb8cc2ef","textRange":{"startLine":16,"endLine":16,"startOffset":8,"endOffset":66},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-08-28T12:18:15-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcUdI9DtgZJSDWSu","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/codemods/api/helpers.py","project":"test","hash":"ccb50d772fac226af0214acc621ae30b","textRange":{"startLine":24,"endLine":24,"startOffset":8,"endOffset":60},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-08-28T12:18:15-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcVKI9DtgZJSDWSz","rule":"python:S1135","severity":"INFO","component":"test:src/codemodder/codemods/base_codemod.py","project":"test","hash":"48d00285d252348f1942cada697cafbf","textRange":{"startLine":22,"endLine":22,"startOffset":22,"endOffset":59},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-08-28T12:18:15-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcSPI9DtgZJSDWSg","rule":"python:S1135","severity":"INFO","component":"test:src/core_codemods/upgrade_sslcontext_tls.py","project":"test","hash":"03a9883caf45aa1f5eb5b749ba42287f","textRange":{"startLine":24,"endLine":24,"startOffset":4,"endOffset":75},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Complete the task associated to this \"TODO\" comment.","effort":"0min","debt":"0min","author":"dan.davella@pixee.ai","tags":["cwe"],"creationDate":"2023-08-24T12:43:16-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"COMPLETE","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcKVI9DtgZJSDWRj","rule":"python:S4423","severity":"CRITICAL","component":"test:tests/samples/weak_tls.py","project":"test","hash":"1bec38d2dee4147c97dbfa87ca0fce14","textRange":{"startLine":3,"endLine":3,"startOffset":19,"endOffset":33},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Change this code to use a stronger protocol.","effort":"2min","debt":"2min","author":"dan.davella@pixee.ai","tags":["cwe","privacy"],"creationDate":"2023-08-24T12:43:16-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"VULNERABILITY","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"TRUSTWORTHY","cleanCodeAttributeCategory":"RESPONSIBLE","impacts":[{"softwareQuality":"SECURITY","severity":"HIGH"}]},{"key":"AYzPBcNvI9DtgZJSDWRx","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/codemods/test_django_session_cookie_secure_off.py","project":"test","hash":"ac9287e2f92fe7960129543d1b343a46","textRange":{"startLine":35,"endLine":37,"startOffset":21,"endOffset":3},"flows":[{"locations":[{"component":"test:tests/codemods/test_django_session_cookie_secure_off.py","textRange":{"startLine":49,"endLine":51,"startOffset":19,"endOffset":3},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/codemods/test_django_session_cookie_secure_off.py","textRange":{"startLine":61,"endLine":63,"startOffset":19,"endOffset":3},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"\"\"DEFAULT_AUTO_FIELD \u003d \"django.db.models.BigAutoField\"\nSESSION_COOKIE_SECURE \u003d True\n\"\"\" 3 times.","effort":"6min","debt":"6min","author":"danalitovsky+git@gmail.com","tags":["design"],"creationDate":"2023-08-10T11:26:14-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcNvI9DtgZJSDWRy","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/codemods/test_django_session_cookie_secure_off.py","project":"test","hash":"a7ea30bcb2d29bb50a8729268cf59db2","textRange":{"startLine":16,"endLine":16,"startOffset":23,"endOffset":34},"flows":[{"locations":[{"component":"test:tests/codemods/test_django_session_cookie_secure_off.py","textRange":{"startLine":33,"endLine":33,"startOffset":23,"endOffset":34},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/codemods/test_django_session_cookie_secure_off.py","textRange":{"startLine":44,"endLine":44,"startOffset":23,"endOffset":34},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/codemods/test_django_session_cookie_secure_off.py","textRange":{"startLine":57,"endLine":57,"startOffset":23,"endOffset":34},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"manage.py\" 4 times.","effort":"8min","debt":"8min","author":"danalitovsky+git@gmail.com","tags":["design"],"creationDate":"2023-08-10T11:26:14-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcNvI9DtgZJSDWRz","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/codemods/test_django_session_cookie_secure_off.py","project":"test","hash":"c5f399d1950fa0b8fad57500aac0225a","textRange":{"startLine":25,"endLine":25,"startOffset":38,"endOffset":51},"flows":[{"locations":[{"component":"test:tests/codemods/test_django_session_cookie_secure_off.py","textRange":{"startLine":34,"endLine":34,"startOffset":38,"endOffset":51},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/codemods/test_django_session_cookie_secure_off.py","textRange":{"startLine":45,"endLine":45,"startOffset":38,"endOffset":51},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/codemods/test_django_session_cookie_secure_off.py","textRange":{"startLine":58,"endLine":58,"startOffset":38,"endOffset":51},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"settings.py\" 4 times.","effort":"8min","debt":"8min","author":"danalitovsky+git@gmail.com","tags":["design"],"creationDate":"2023-08-10T11:26:14-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcMOI9DtgZJSDWRr","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/codemods/test_django_debug_flag_on.py","project":"test","hash":"f9b26175bac0a12e03a5d14467c289ed","textRange":{"startLine":15,"endLine":15,"startOffset":21,"endOffset":39},"flows":[{"locations":[{"component":"test:tests/codemods/test_django_debug_flag_on.py","textRange":{"startLine":24,"endLine":24,"startOffset":21,"endOffset":39},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/codemods/test_django_debug_flag_on.py","textRange":{"startLine":32,"endLine":32,"startOffset":21,"endOffset":39},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"\"\"DEBUG \u003d True\"\"\" 3 times.","effort":"6min","debt":"6min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["design"],"creationDate":"2023-08-09T08:48:41-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcEuI9DtgZJSDWRG","rule":"secrets:S6687","severity":"BLOCKER","component":"test:tests/samples/django-project/mysite/mysite/settings.py","project":"test","hash":"a676f5d04724d58e9b504e8520fee947","textRange":{"startLine":23,"endLine":23,"startOffset":14,"endOffset":80},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Make sure this Django key gets revoked, changed, and removed from the code.","effort":"30min","debt":"30min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["cwe"],"creationDate":"2023-08-09T08:48:41-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"VULNERABILITY","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"TRUSTWORTHY","cleanCodeAttributeCategory":"RESPONSIBLE","impacts":[{"softwareQuality":"SECURITY","severity":"HIGH"}]},{"key":"AYzPBcUxI9DtgZJSDWSw","rule":"python:S4144","severity":"MAJOR","component":"test:src/codemodder/codemods/transformations/clean_imports.py","project":"test","hash":"6d7881a21b67721a3b5add0fc4fc4b64","textRange":{"startLine":342,"endLine":342,"startOffset":8,"endOffset":24},"flows":[{"locations":[{"component":"test:src/codemodder/codemods/transformations/clean_imports.py","textRange":{"startLine":335,"endLine":335,"startOffset":8,"endOffset":20},"msg":"Original","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Update this function so that its implementation is not identical to leave_Import on line 335.","effort":"15min","debt":"15min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["confusing","duplicate","suspicious"],"creationDate":"2023-07-20T11:20:37-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcUxI9DtgZJSDWSx","rule":"python:S6353","severity":"MINOR","component":"test:src/codemodder/codemods/transformations/clean_imports.py","project":"test","hash":"5c96454e2cbe2fb571bb158b9216c259","textRange":{"startLine":412,"endLine":412,"startOffset":48,"endOffset":53},"flows":[],"resolution":"FIXED","status":"CLOSED","message":"Use concise character class syntax \u0027\\d\u0027 instead of \u0027[0-9]\u0027.","effort":"5min","debt":"5min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["regex"],"creationDate":"2023-07-20T11:20:37-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"CLEAR","cleanCodeAttributeCategory":"INTENTIONAL","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"LOW"}]},{"key":"AYzPBcVBI9DtgZJSDWSy","rule":"python:S4144","severity":"MAJOR","component":"test:src/codemodder/codemods/transformations/remove_unused_imports.py","project":"test","hash":"09872ec59544334f54354abfe606761e","textRange":{"startLine":61,"endLine":61,"startOffset":8,"endOffset":24},"flows":[{"locations":[{"component":"test:src/codemodder/codemods/transformations/remove_unused_imports.py","textRange":{"startLine":53,"endLine":53,"startOffset":8,"endOffset":20},"msg":"Original","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Update this function so that its implementation is not identical to leave_Import on line 53.","effort":"15min","debt":"15min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["confusing","duplicate","suspicious"],"creationDate":"2023-07-20T11:20:37-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"MEDIUM"}]},{"key":"AYzPBcQQI9DtgZJSDWSF","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_cli.py","project":"test","hash":"7032201b6a35b36aebc4955fc2afc82c","textRange":{"startLine":23,"endLine":23,"startOffset":12,"endOffset":27},"flows":[{"locations":[{"component":"test:tests/test_cli.py","textRange":{"startLine":125,"endLine":125,"startOffset":12,"endOffset":27},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_cli.py","textRange":{"startLine":146,"endLine":146,"startOffset":12,"endOffset":27},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"CLI error: %s\" 3 times.","effort":"6min","debt":"6min","author":"danalitovsky+git@gmail.com","tags":["design"],"creationDate":"2023-07-17T11:08:12-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcNVI9DtgZJSDWRw","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/codemods/test_base_visitor.py","project":"test","hash":"d45e1225f6d9479fc887f7829ca4eb93","textRange":{"startLine":42,"endLine":42,"startOffset":21,"endOffset":68},"flows":[{"locations":[{"component":"test:tests/codemods/test_base_visitor.py","textRange":{"startLine":49,"endLine":49,"startOffset":21,"endOffset":68},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/codemods/test_base_visitor.py","textRange":{"startLine":56,"endLine":56,"startOffset":21,"endOffset":68},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"\"\"print(\u0027Hello Earth\u0027)\\nprint(\u0027Hello Mars\u0027)\"\"\" 3 times.","effort":"6min","debt":"6min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["design"],"creationDate":"2023-07-05T08:49:35-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcP0I9DtgZJSDWR_","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_code_directory.py","project":"test","hash":"10fd60b9187ff120a3c92bebec0f9827","textRange":{"startLine":18,"endLine":18,"startOffset":24,"endOffset":46},"flows":[{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":39,"endLine":39,"startOffset":20,"endOffset":42},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":44,"endLine":44,"startOffset":20,"endOffset":42},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":54,"endLine":54,"startOffset":20,"endOffset":42},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":66,"endLine":66,"startOffset":20,"endOffset":42},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":74,"endLine":74,"startOffset":20,"endOffset":42},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":96,"endLine":96,"startOffset":20,"endOffset":42},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"empty_for_testing.py\" 7 times.","effort":"14min","debt":"14min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["design"],"creationDate":"2023-07-05T08:49:35-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcP0I9DtgZJSDWSB","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_code_directory.py","project":"test","hash":"fabf3d3095de8e409c0e44a4e411bbdb","textRange":{"startLine":14,"endLine":14,"startOffset":19,"endOffset":39},"flows":[{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":39,"endLine":39,"startOffset":44,"endOffset":64},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":44,"endLine":44,"startOffset":44,"endOffset":64},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":49,"endLine":49,"startOffset":20,"endOffset":40},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":54,"endLine":54,"startOffset":44,"endOffset":64},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":61,"endLine":61,"startOffset":20,"endOffset":40},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":66,"endLine":66,"startOffset":44,"endOffset":64},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":74,"endLine":74,"startOffset":44,"endOffset":64},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":81,"endLine":81,"startOffset":24,"endOffset":44},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":86,"endLine":86,"startOffset":20,"endOffset":40},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":96,"endLine":96,"startOffset":44,"endOffset":64},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":140,"endLine":140,"startOffset":40,"endOffset":60},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"insecure_random.py\" 12 times.","effort":"24min","debt":"24min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["design"],"creationDate":"2023-07-05T08:49:35-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]},{"key":"AYzPBcP0I9DtgZJSDWSC","rule":"python:S1192","severity":"CRITICAL","component":"test:tests/test_code_directory.py","project":"test","hash":"28a0617e4a0ffe4bae44b9873d41c725","textRange":{"startLine":13,"endLine":13,"startOffset":19,"endOffset":36},"flows":[{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":39,"endLine":39,"startOffset":66,"endOffset":83},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":54,"endLine":54,"startOffset":66,"endOffset":83},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":66,"endLine":66,"startOffset":66,"endOffset":83},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":74,"endLine":74,"startOffset":66,"endOffset":83},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":81,"endLine":81,"startOffset":46,"endOffset":63},"msg":"Duplication","msgFormattings":[]}]},{"locations":[{"component":"test:tests/test_code_directory.py","textRange":{"startLine":91,"endLine":91,"startOffset":20,"endOffset":37},"msg":"Duplication","msgFormattings":[]}]}],"resolution":"FIXED","status":"CLOSED","message":"Define a constant instead of duplicating this literal \"make_request.py\" 7 times.","effort":"14min","debt":"14min","author":"12188364+andrecsilva@users.noreply.github.com","tags":["design"],"creationDate":"2023-07-05T08:49:35-0300","updateDate":"2024-01-05T07:38:55-0300","closeDate":"2024-01-05T07:38:55-0300","type":"CODE_SMELL","scope":"MAIN","quickFixAvailable":false,"messageFormattings":[],"codeVariants":[],"cleanCodeAttribute":"DISTINCT","cleanCodeAttributeCategory":"ADAPTABLE","impacts":[{"softwareQuality":"MAINTAINABILITY","severity":"HIGH"}]}],"components":[{"key":"test:tests/codemods/test_django_session_cookie_secure_off.py","enabled":false,"qualifier":"FIL","name":"test_django_session_cookie_secure_off.py","longName":"tests/codemods/test_django_session_cookie_secure_off.py","path":"tests/codemods/test_django_session_cookie_secure_off.py"},{"key":"test:test2.py","enabled":false,"qualifier":"FIL","name":"test2.py","longName":"test2.py","path":"test2.py"},{"key":"test:test.py","enabled":false,"qualifier":"FIL","name":"test.py","longName":"test.py","path":"test.py"},{"key":"test:tests/codemods/test_tempfile_mktemp.py","enabled":false,"qualifier":"FIL","name":"test_tempfile_mktemp.py","longName":"tests/codemods/test_tempfile_mktemp.py","path":"tests/codemods/test_tempfile_mktemp.py"},{"key":"test:tests/samples/exception_without_raise.py","enabled":false,"qualifier":"FIL","name":"exception_without_raise.py","longName":"tests/samples/exception_without_raise.py","path":"tests/samples/exception_without_raise.py"},{"key":"test:src/codemodder/codemods/utils_mixin.py","enabled":false,"qualifier":"FIL","name":"utils_mixin.py","longName":"src/codemodder/codemods/utils_mixin.py","path":"src/codemodder/codemods/utils_mixin.py"},{"key":"test:tests/samples/multiple_codemods.py","enabled":false,"qualifier":"FIL","name":"multiple_codemods.py","longName":"tests/samples/multiple_codemods.py","path":"tests/samples/multiple_codemods.py"},{"key":"test:src/codemodder/codemods/base_codemod.py","enabled":false,"qualifier":"FIL","name":"base_codemod.py","longName":"src/codemodder/codemods/base_codemod.py","path":"src/codemodder/codemods/base_codemod.py"},{"key":"test","enabled":true,"qualifier":"TRK","name":"test","longName":"test"},{"key":"test:src/codemodder/codemodder.py","enabled":false,"qualifier":"FIL","name":"codemodder.py","longName":"src/codemodder/codemodder.py","path":"src/codemodder/codemodder.py"},{"key":"test:tests/samples/django_receiver_on_top.py","enabled":false,"qualifier":"FIL","name":"django_receiver_on_top.py","longName":"tests/samples/django_receiver_on_top.py","path":"tests/samples/django_receiver_on_top.py"},{"key":"test:src/codemodder/codemods/transformations/remove_unused_imports.py","enabled":false,"qualifier":"FIL","name":"remove_unused_imports.py","longName":"src/codemodder/codemods/transformations/remove_unused_imports.py","path":"src/codemodder/codemods/transformations/remove_unused_imports.py"},{"key":"test:tests/samples/requests_timeout.py","enabled":false,"qualifier":"FIL","name":"requests_timeout.py","longName":"tests/samples/requests_timeout.py","path":"tests/samples/requests_timeout.py"},{"key":"test:src/codemodder/codemods/transformations/clean_imports.py","enabled":false,"qualifier":"FIL","name":"clean_imports.py","longName":"src/codemodder/codemods/transformations/clean_imports.py","path":"src/codemodder/codemods/transformations/clean_imports.py"},{"key":"test:src/codemodder/registry.py","enabled":false,"qualifier":"FIL","name":"registry.py","longName":"src/codemodder/registry.py","path":"src/codemodder/registry.py"},{"key":"test:src/codemodder/cli.py","enabled":false,"qualifier":"FIL","name":"cli.py","longName":"src/codemodder/cli.py","path":"src/codemodder/cli.py"},{"key":"test:src/codemodder/executor.py","enabled":false,"qualifier":"FIL","name":"executor.py","longName":"src/codemodder/executor.py","path":"src/codemodder/executor.py"},{"key":"test:integration_tests/base_test.py","enabled":false,"qualifier":"FIL","name":"base_test.py","longName":"integration_tests/base_test.py","path":"integration_tests/base_test.py"},{"key":"test:tests/codemods/test_fix_mutable_params.py","enabled":false,"qualifier":"FIL","name":"test_fix_mutable_params.py","longName":"tests/codemods/test_fix_mutable_params.py","path":"tests/codemods/test_fix_mutable_params.py"},{"key":"test:src/codemodder/codemods/utils.py","enabled":false,"qualifier":"FIL","name":"utils.py","longName":"src/codemodder/codemods/utils.py","path":"src/codemodder/codemods/utils.py"},{"key":"test:tests/samples/unverified_request.py","enabled":false,"qualifier":"FIL","name":"unverified_request.py","longName":"tests/samples/unverified_request.py","path":"tests/samples/unverified_request.py"},{"key":"test:tests/samples/file_resource_leak.py","enabled":false,"qualifier":"FIL","name":"file_resource_leak.py","longName":"tests/samples/file_resource_leak.py","path":"tests/samples/file_resource_leak.py"},{"key":"test:src/core_codemods/secure_flask_session_config.py","enabled":false,"qualifier":"FIL","name":"secure_flask_session_config.py","longName":"src/core_codemods/secure_flask_session_config.py","path":"src/core_codemods/secure_flask_session_config.py"},{"key":"test:tests/samples/future_imports.py","enabled":false,"qualifier":"FIL","name":"future_imports.py","longName":"tests/samples/future_imports.py","path":"tests/samples/future_imports.py"},{"key":"test:src/codemodder/codemods/api/helpers.py","enabled":false,"qualifier":"FIL","name":"helpers.py","longName":"src/codemodder/codemods/api/helpers.py","path":"src/codemodder/codemods/api/helpers.py"},{"key":"test:src/codemodder/report/codetf_reporter.py","enabled":false,"qualifier":"FIL","name":"codetf_reporter.py","longName":"src/codemodder/report/codetf_reporter.py","path":"src/codemodder/report/codetf_reporter.py"},{"key":"test:tests/samples/literal_or_new_object_identity.py","enabled":false,"qualifier":"FIL","name":"literal_or_new_object_identity.py","longName":"tests/samples/literal_or_new_object_identity.py","path":"tests/samples/literal_or_new_object_identity.py"},{"key":"test:src/codemodder/codemods/api/__init__.py","enabled":false,"qualifier":"FIL","name":"__init__.py","longName":"src/codemodder/codemods/api/__init__.py","path":"src/codemodder/codemods/api/__init__.py"},{"key":"test:integration_tests/test_dependency_manager.py","enabled":false,"qualifier":"FIL","name":"test_dependency_manager.py","longName":"integration_tests/test_dependency_manager.py","path":"integration_tests/test_dependency_manager.py"},{"key":"test:tests/test_codemodder.py","enabled":false,"qualifier":"FIL","name":"test_codemodder.py","longName":"tests/test_codemodder.py","path":"tests/test_codemodder.py"},{"key":"test:src/core_codemods/file_resource_leak.py","enabled":false,"qualifier":"FIL","name":"file_resource_leak.py","longName":"src/core_codemods/file_resource_leak.py","path":"src/core_codemods/file_resource_leak.py"},{"key":"test:src/core_codemods/remove_unused_imports.py","enabled":false,"qualifier":"FIL","name":"remove_unused_imports.py","longName":"src/core_codemods/remove_unused_imports.py","path":"src/core_codemods/remove_unused_imports.py"},{"key":"test:src/core_codemods/with_threading_lock.py","enabled":false,"qualifier":"FIL","name":"with_threading_lock.py","longName":"src/core_codemods/with_threading_lock.py","path":"src/core_codemods/with_threading_lock.py"},{"key":"test:src/core_codemods/flask_json_response_type.py","enabled":false,"qualifier":"FIL","name":"flask_json_response_type.py","longName":"src/core_codemods/flask_json_response_type.py","path":"src/core_codemods/flask_json_response_type.py"},{"key":"test:src/codemodder/dependency_management/setup_py_writer.py","enabled":false,"qualifier":"FIL","name":"setup_py_writer.py","longName":"src/codemodder/dependency_management/setup_py_writer.py","path":"src/codemodder/dependency_management/setup_py_writer.py"},{"key":"test:src/core_codemods/sql_parameterization.py","enabled":false,"qualifier":"FIL","name":"sql_parameterization.py","longName":"src/core_codemods/sql_parameterization.py","path":"src/core_codemods/sql_parameterization.py"},{"key":"test:libcstbug.py","enabled":false,"qualifier":"FIL","name":"libcstbug.py","longName":"libcstbug.py","path":"libcstbug.py"},{"key":"test:src/core_codemods/use_defused_xml.py","enabled":false,"qualifier":"FIL","name":"use_defused_xml.py","longName":"src/core_codemods/use_defused_xml.py","path":"src/core_codemods/use_defused_xml.py"},{"key":"test:tests/transformations/test_remove_empty_string_concatenation.py","enabled":false,"qualifier":"FIL","name":"test_remove_empty_string_concatenation.py","longName":"tests/transformations/test_remove_empty_string_concatenation.py","path":"tests/transformations/test_remove_empty_string_concatenation.py"},{"key":"test:tests/codemods/test_https_connection.py","enabled":false,"qualifier":"FIL","name":"test_https_connection.py","longName":"tests/codemods/test_https_connection.py","path":"tests/codemods/test_https_connection.py"},{"key":"test:tests/codemods/test_secure_flask_session_config.py","enabled":false,"qualifier":"FIL","name":"test_secure_flask_session_config.py","longName":"tests/codemods/test_secure_flask_session_config.py","path":"tests/codemods/test_secure_flask_session_config.py"},{"key":"test:tests/codemods/test_fix_deprecated_abstractproperty.py","enabled":false,"qualifier":"FIL","name":"test_fix_deprecated_abstractproperty.py","longName":"tests/codemods/test_fix_deprecated_abstractproperty.py","path":"tests/codemods/test_fix_deprecated_abstractproperty.py"},{"key":"test:tests/test_code_directory.py","enabled":false,"qualifier":"FIL","name":"test_code_directory.py","longName":"tests/test_code_directory.py","path":"tests/test_code_directory.py"},{"key":"test:tests/conftest.py","enabled":false,"qualifier":"FIL","name":"conftest.py","longName":"tests/conftest.py","path":"tests/conftest.py"},{"key":"test:tests/codemods/test_django_debug_flag_on.py","enabled":false,"qualifier":"FIL","name":"test_django_debug_flag_on.py","longName":"tests/codemods/test_django_debug_flag_on.py","path":"tests/codemods/test_django_debug_flag_on.py"},{"key":"test:tests/test_cli.py","enabled":false,"qualifier":"FIL","name":"test_cli.py","longName":"tests/test_cli.py","path":"tests/test_cli.py"},{"key":"test:tests/test_ancestorpatterns_mixin.py","enabled":false,"qualifier":"FIL","name":"test_ancestorpatterns_mixin.py","longName":"tests/test_ancestorpatterns_mixin.py","path":"tests/test_ancestorpatterns_mixin.py"},{"key":"test:src/codemodder/change.py","enabled":false,"qualifier":"FIL","name":"change.py","longName":"src/codemodder/change.py","path":"src/codemodder/change.py"},{"key":"test:tests/dependency_management/test_pyproject_writer.py","enabled":false,"qualifier":"FIL","name":"test_pyproject_writer.py","longName":"tests/dependency_management/test_pyproject_writer.py","path":"tests/dependency_management/test_pyproject_writer.py"},{"key":"test:tests/dependency_management/test_requirements_txt_writer.py","enabled":false,"qualifier":"FIL","name":"test_requirements_txt_writer.py","longName":"tests/dependency_management/test_requirements_txt_writer.py","path":"tests/dependency_management/test_requirements_txt_writer.py"},{"key":"test:tests/dependency_management/test_setup_py_writer.py","enabled":false,"qualifier":"FIL","name":"test_setup_py_writer.py","longName":"tests/dependency_management/test_setup_py_writer.py","path":"tests/dependency_management/test_setup_py_writer.py"},{"key":"test:tests/codemods/test_base_visitor.py","enabled":false,"qualifier":"FIL","name":"test_base_visitor.py","longName":"tests/codemods/test_base_visitor.py","path":"tests/codemods/test_base_visitor.py"},{"key":"test:src/codemodder/project_analysis/file_parsers/setup_py_file_parser.py","enabled":false,"qualifier":"FIL","name":"setup_py_file_parser.py","longName":"src/codemodder/project_analysis/file_parsers/setup_py_file_parser.py","path":"src/codemodder/project_analysis/file_parsers/setup_py_file_parser.py"},{"key":"test:tests/samples/numpy_nan_equality.py","enabled":false,"qualifier":"FIL","name":"numpy_nan_equality.py","longName":"tests/samples/numpy_nan_equality.py","path":"tests/samples/numpy_nan_equality.py"},{"key":"test:tests/samples/unordered_imports.py","enabled":false,"qualifier":"FIL","name":"unordered_imports.py","longName":"tests/samples/unordered_imports.py","path":"tests/samples/unordered_imports.py"},{"key":"test:src/core_codemods/fix_mutable_params.py","enabled":false,"qualifier":"FIL","name":"fix_mutable_params.py","longName":"src/core_codemods/fix_mutable_params.py","path":"src/core_codemods/fix_mutable_params.py"},{"key":"test:tests/samples/mutable_params.py","enabled":false,"qualifier":"FIL","name":"mutable_params.py","longName":"tests/samples/mutable_params.py","path":"tests/samples/mutable_params.py"},{"key":"test:tests/samples/jwt_decode_verify.py","enabled":false,"qualifier":"FIL","name":"jwt_decode_verify.py","longName":"tests/samples/jwt_decode_verify.py","path":"tests/samples/jwt_decode_verify.py"},{"key":"test:tests/samples/unnecessary_f_str.py","enabled":false,"qualifier":"FIL","name":"unnecessary_f_str.py","longName":"tests/samples/unnecessary_f_str.py","path":"tests/samples/unnecessary_f_str.py"},{"key":"test:tests/samples/weak_tls.py","enabled":false,"qualifier":"FIL","name":"weak_tls.py","longName":"tests/samples/weak_tls.py","path":"tests/samples/weak_tls.py"},{"key":"test:tests/samples/django-project/mysite/mysite/settings.py","enabled":false,"qualifier":"FIL","name":"settings.py","longName":"tests/samples/django-project/mysite/mysite/settings.py","path":"tests/samples/django-project/mysite/mysite/settings.py"},{"key":"test:tests/project_analysis/file_parsers/test_pyproject_toml_file_parser.py","enabled":false,"qualifier":"FIL","name":"test_pyproject_toml_file_parser.py","longName":"tests/project_analysis/file_parsers/test_pyproject_toml_file_parser.py","path":"tests/project_analysis/file_parsers/test_pyproject_toml_file_parser.py"},{"key":"test:tests/codemods/test_secure_random.py","enabled":false,"qualifier":"FIL","name":"test_secure_random.py","longName":"tests/codemods/test_secure_random.py","path":"tests/codemods/test_secure_random.py"},{"key":"test:src/core_codemods/upgrade_sslcontext_tls.py","enabled":false,"qualifier":"FIL","name":"upgrade_sslcontext_tls.py","longName":"src/core_codemods/upgrade_sslcontext_tls.py","path":"src/core_codemods/upgrade_sslcontext_tls.py"},{"key":"test:tests/samples/deprecated_abstractproperty.py","enabled":false,"qualifier":"FIL","name":"deprecated_abstractproperty.py","longName":"tests/samples/deprecated_abstractproperty.py","path":"tests/samples/deprecated_abstractproperty.py"},{"key":"test:tests/samples/tempfile_mktemp.py","enabled":false,"qualifier":"FIL","name":"tempfile_mktemp.py","longName":"tests/samples/tempfile_mktemp.py","path":"tests/samples/tempfile_mktemp.py"},{"key":"test:tests/codemods/test_enable_jinja2_autoescape.py","enabled":false,"qualifier":"FIL","name":"test_enable_jinja2_autoescape.py","longName":"tests/codemods/test_enable_jinja2_autoescape.py","path":"tests/codemods/test_enable_jinja2_autoescape.py"}],"facets":[]} From 771f9cba4e65e30b6290f3f2aa2f8ef9bf870cf7 Mon Sep 17 00:00:00 2001 From: andrecs <12188364+andrecsilva@users.noreply.github.com> Date: Thu, 25 Jan 2024 07:15:38 -0300 Subject: [PATCH 4/7] If json or sarif are present, only sast codemods are included --- integration_tests/test_program.py | 21 +++++++++++++++++ src/codemodder/codemodder.py | 4 +++- src/codemodder/codemods/base_codemod.py | 4 ++-- src/codemodder/codemods/base_visitor.py | 1 - src/codemodder/registry.py | 12 +++++++++- tests/codemods/test_include_exclude.py | 30 +++++++++++++++++++++---- tests/test_cli.py | 3 ++- 7 files changed, 65 insertions(+), 10 deletions(-) diff --git a/integration_tests/test_program.py b/integration_tests/test_program.py index 3d14e931..65aa0b0d 100644 --- a/integration_tests/test_program.py +++ b/integration_tests/test_program.py @@ -1,4 +1,7 @@ import subprocess +from core_codemods.remove_assertion_in_pytest_raises import ( + RemoveAssertionInPytestRaises, +) class TestProgramFails: @@ -21,3 +24,21 @@ def test_codemods_include_exclude_conflict(self): check=False, ) assert completed_process.returncode == 3 + + def test_load_sast_only_by_flag(self, tmp_path): + tmp_file_path = tmp_path / "sonar.json" + tmp_file_path.touch() + completed_process = subprocess.run( + [ + "codemodder", + "tests/samples/", + "--sonar-issues-json", + f"{tmp_file_path}", + "--dry-run", + ], + check=False, + capture_output=True, + text=True, + ) + assert completed_process.returncode == 0 + assert RemoveAssertionInPytestRaises.id not in completed_process.stdout diff --git a/src/codemodder/codemodder.py b/src/codemodder/codemodder.py index 448907d9..ce92e0c5 100644 --- a/src/codemodder/codemodder.py +++ b/src/codemodder/codemodder.py @@ -184,7 +184,9 @@ def run(original_args) -> int: # TODO: this should be a method of CodemodExecutionContext codemods_to_run = codemod_registry.match_codemods( - argv.codemod_include, argv.codemod_exclude + argv.codemod_include, + argv.codemod_exclude, + sast_only=argv.sonar_issues_json or argv.sarif, ) log_section("setup") diff --git a/src/codemodder/codemods/base_codemod.py b/src/codemodder/codemods/base_codemod.py index f2c5b2d2..cdd36a50 100644 --- a/src/codemodder/codemods/base_codemod.py +++ b/src/codemodder/codemods/base_codemod.py @@ -108,10 +108,10 @@ def docs_module(self) -> Traversable: @cached_property def description(self) -> str: - if not self._metadata.description: + if self._metadata.description == None: doc_path = self.docs_module / f"{self.origin}_python_{self.name}.md" return doc_path.read_text() - return self._metadata.description + return self._metadata.description # type: ignore @property def review_guidance(self): diff --git a/src/codemodder/codemods/base_visitor.py b/src/codemodder/codemods/base_visitor.py index a8477634..e50c9178 100644 --- a/src/codemodder/codemods/base_visitor.py +++ b/src/codemodder/codemods/base_visitor.py @@ -35,7 +35,6 @@ def node_is_selected(self, node) -> bool: return False pos_to_match = self.node_position(node) - print(pos_to_match) return self.filter_by_result( pos_to_match ) and self.filter_by_path_includes_or_excludes(pos_to_match) diff --git a/src/codemodder/registry.py b/src/codemodder/registry.py index 1c678f35..15ba125b 100644 --- a/src/codemodder/registry.py +++ b/src/codemodder/registry.py @@ -59,14 +59,24 @@ def match_codemods( self, codemod_include: Optional[list] = None, codemod_exclude: Optional[list] = None, + sast_only=False, ) -> list[BaseCodemod]: codemod_include = codemod_include or [] codemod_exclude = codemod_exclude or DEFAULT_EXCLUDED_CODEMODS + if sast_only: + base_list = [ + codemod for codemod in self.codemods if codemod.origin != "pixee" + ] + else: + base_list = [ + codemod for codemod in self.codemods if codemod.origin == "pixee" + ] + if codemod_exclude and not codemod_include: return [ codemod - for codemod in self.codemods + for codemod in base_list if codemod.name not in codemod_exclude and codemod.id not in codemod_exclude ] diff --git a/tests/codemods/test_include_exclude.py b/tests/codemods/test_include_exclude.py index 8fcd8467..131671f0 100644 --- a/tests/codemods/test_include_exclude.py +++ b/tests/codemods/test_include_exclude.py @@ -1,5 +1,6 @@ import pytest from codemodder.registry import DEFAULT_EXCLUDED_CODEMODS, load_registered_codemods +from core_codemods import registry class TestMatchCodemods: @@ -9,12 +10,31 @@ def setup_class(cls): cls.codemod_map = ( cls.registry._codemods_by_name # pylint: disable=protected-access ) + cls.default_ids = [ + c().id if isinstance(c, type) else c.id for c in registry.codemods + ] def test_no_include_exclude(self): - defaults = set( - x for x in self.registry.codemods if x.id not in DEFAULT_EXCLUDED_CODEMODS + default_codemods = set( + x + for x in self.registry.codemods + if x.id in self.default_ids and x.id not in DEFAULT_EXCLUDED_CODEMODS + ) + assert set(self.registry.match_codemods(None, None)) == default_codemods + + def test_load_sast_codemods(self): + sast_codemods = set( + c for c in self.registry.codemods if c.id not in self.default_ids ) - assert set(self.registry.match_codemods(None, None)) == defaults + assert ( + set(self.registry.match_codemods(None, None, sast_only=True)) + == sast_codemods + ) + + def test_include_non_sast_in_sast(self): + assert set( + self.registry.match_codemods(["secure-random"], None, sast_only=True) + ) == {self.codemod_map["secure-random"]} @pytest.mark.parametrize( "input_str", ["secure-random", "secure-random,url-sandbox"] @@ -44,5 +64,7 @@ def test_include_preserve_order(self, input_str): def test_exclude(self, input_str): excludes = input_str.split(",") assert self.registry.match_codemods(None, excludes) == [ - v for (k, v) in self.codemod_map.items() if k not in excludes + c + for c in self.registry.codemods + if c.name not in excludes and c.id in self.default_ids ] diff --git a/tests/test_cli.py b/tests/test_cli.py index e95c4280..e9124036 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -6,6 +6,7 @@ from codemodder.cli import parse_args from codemodder import __version__ from codemodder.registry import DEFAULT_EXCLUDED_CODEMODS, load_registered_codemods +from core_codemods import registry as core_registry class TestParseArgs: @@ -102,7 +103,7 @@ def test_describe_prints_codemod_metadata(self, mock_print): assert mock_print.call_count == 1 results = json.loads(mock_print.call_args_list[0][0][0]) - assert len(results["results"]) == len(self.registry.codemods) - len( + assert len(results["results"]) == len(core_registry.codemods) - len( DEFAULT_EXCLUDED_CODEMODS ) From d642ec8c741a0f186c12beed30b170097690da7d Mon Sep 17 00:00:00 2001 From: andrecs <12188364+andrecsilva@users.noreply.github.com> Date: Fri, 26 Jan 2024 14:26:06 -0300 Subject: [PATCH 5/7] If json or sarif are present, only sast codemods are included --- integration_tests/base_test.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/integration_tests/base_test.py b/integration_tests/base_test.py index afca6189..ac79cce3 100644 --- a/integration_tests/base_test.py +++ b/integration_tests/base_test.py @@ -83,16 +83,13 @@ def _assert_run_fields(self, run, output_path): assert run["tool"] == "codemodder-python" assert run["version"] == __version__ assert run["elapsed"] != "" - if self.sonar_issues_json: - assert ( - run["commandLine"] - == f"codemodder {SAMPLES_DIR} --output {output_path} --codemod-include={self.codemod_instance.name} --path-include={code_path} --sonar-issues-json={self.sonar_issues_json}" - ) - else: - assert ( - run["commandLine"] - == f"codemodder {SAMPLES_DIR} --output {output_path} --codemod-include={self.codemod_instance.name} --path-include={code_path}" - ) + assert run[ + "commandLine" + ] == f'codemodder {SAMPLES_DIR} --output {output_path} --codemod-include={self.codemod_instance.name} --path-include={code_path} --path-exclude=""' + ( + f" --sonar-issues-json={self.sonar_issues_json}" + if self.sonar_issues_json + else "" + ) assert run["directory"] == os.path.abspath(SAMPLES_DIR) assert run["sarifs"] == [] From 1d316cb773b2b702ab2c8322dd718b1e7df4d5ab Mon Sep 17 00:00:00 2001 From: andrecs <12188364+andrecsilva@users.noreply.github.com> Date: Fri, 26 Jan 2024 14:27:28 -0300 Subject: [PATCH 6/7] Some refactoring --- .../test_sonar_numpy_nan_equality.py | 2 +- src/codemodder/codemodder.py | 8 -------- src/codemodder/codemods/base_codemod.py | 4 ++-- src/codemodder/context.py | 5 +---- src/codemodder/registry.py | 15 ++++++--------- src/core_codemods/__init__.py | 2 +- .../{ => sonar}/sonar_numpy_nan_equality.py | 0 tests/codemods/test_sonar_numpy_nan_equality.py | 2 +- tests/test_codemod_docs.py | 1 - 9 files changed, 12 insertions(+), 27 deletions(-) rename src/core_codemods/{ => sonar}/sonar_numpy_nan_equality.py (100%) diff --git a/integration_tests/test_sonar_numpy_nan_equality.py b/integration_tests/test_sonar_numpy_nan_equality.py index c3365ddc..344d798c 100644 --- a/integration_tests/test_sonar_numpy_nan_equality.py +++ b/integration_tests/test_sonar_numpy_nan_equality.py @@ -1,4 +1,4 @@ -from core_codemods.sonar_numpy_nan_equality import ( +from core_codemods.sonar.sonar_numpy_nan_equality import ( SonarNumpyNanEquality, SonarNumpyNanEqualityTransformer, ) diff --git a/src/codemodder/codemodder.py b/src/codemodder/codemodder.py index ce92e0c5..ff886dee 100644 --- a/src/codemodder/codemodder.py +++ b/src/codemodder/codemodder.py @@ -20,7 +20,6 @@ from codemodder.report.codetf_reporter import report_default from codemodder.result import ResultSet from codemodder.semgrep import run as run_semgrep -from codemodder.sonar_results import SonarResultSet def update_code(file_path, new_code): @@ -137,13 +136,6 @@ def record_dependency_update(dependency_results: dict[Dependency, PackageStore | logger.debug("The following dependencies could not be added: %s", str_list) -def process_sonar_findings(sonar_json_files: list[str]) -> SonarResultSet: - combined_result_set = SonarResultSet() - for file in sonar_json_files or []: - combined_result_set |= SonarResultSet.from_json(file) - return combined_result_set - - def run(original_args) -> int: start = datetime.datetime.now() diff --git a/src/codemodder/codemods/base_codemod.py b/src/codemodder/codemods/base_codemod.py index cdd36a50..9ec3cfbc 100644 --- a/src/codemodder/codemods/base_codemod.py +++ b/src/codemodder/codemods/base_codemod.py @@ -108,10 +108,10 @@ def docs_module(self) -> Traversable: @cached_property def description(self) -> str: - if self._metadata.description == None: + if self._metadata.description is None: doc_path = self.docs_module / f"{self.origin}_python_{self.name}.md" return doc_path.read_text() - return self._metadata.description # type: ignore + return self._metadata.description @property def review_guidance(self): diff --git a/src/codemodder/context.py b/src/codemodder/context.py index a61e80e5..4f077c41 100644 --- a/src/codemodder/context.py +++ b/src/codemodder/context.py @@ -63,10 +63,7 @@ def __init__( self.path_include = path_include self.path_exclude = path_exclude self.max_workers = max_workers - if tool_result_files_map: - self.tool_result_files_map = tool_result_files_map - else: - self.tool_result_files_map = {} + self.tool_result_files_map = tool_result_files_map or {} def add_results(self, codemod_name: str, change_sets: List[ChangeSet]): self._results_by_codemod.setdefault(codemod_name, []).extend(change_sets) diff --git a/src/codemodder/registry.py b/src/codemodder/registry.py index 15ba125b..6b15acbb 100644 --- a/src/codemodder/registry.py +++ b/src/codemodder/registry.py @@ -63,15 +63,12 @@ def match_codemods( ) -> list[BaseCodemod]: codemod_include = codemod_include or [] codemod_exclude = codemod_exclude or DEFAULT_EXCLUDED_CODEMODS - - if sast_only: - base_list = [ - codemod for codemod in self.codemods if codemod.origin != "pixee" - ] - else: - base_list = [ - codemod for codemod in self.codemods if codemod.origin == "pixee" - ] + base_list = [ + codemod + for codemod in self.codemods + if (sast_only and codemod.origin != "pixee") + or (not sast_only and codemod.origin == "pixee") + ] if codemod_exclude and not codemod_include: return [ diff --git a/src/core_codemods/__init__.py b/src/core_codemods/__init__.py index 174c3767..a71c611d 100644 --- a/src/core_codemods/__init__.py +++ b/src/core_codemods/__init__.py @@ -50,7 +50,7 @@ from .remove_assertion_in_pytest_raises import RemoveAssertionInPytestRaises from .fix_assert_tuple import FixAssertTuple -from .sonar_numpy_nan_equality import SonarNumpyNanEquality +from .sonar.sonar_numpy_nan_equality import SonarNumpyNanEquality registry = CodemodCollection( origin="pixee", diff --git a/src/core_codemods/sonar_numpy_nan_equality.py b/src/core_codemods/sonar/sonar_numpy_nan_equality.py similarity index 100% rename from src/core_codemods/sonar_numpy_nan_equality.py rename to src/core_codemods/sonar/sonar_numpy_nan_equality.py diff --git a/tests/codemods/test_sonar_numpy_nan_equality.py b/tests/codemods/test_sonar_numpy_nan_equality.py index 52d25bf3..1378c20a 100644 --- a/tests/codemods/test_sonar_numpy_nan_equality.py +++ b/tests/codemods/test_sonar_numpy_nan_equality.py @@ -1,5 +1,5 @@ import json -from core_codemods.sonar_numpy_nan_equality import SonarNumpyNanEquality +from core_codemods.sonar.sonar_numpy_nan_equality import SonarNumpyNanEquality from tests.codemods.base_codemod_test import BaseSASTCodemodTest from textwrap import dedent diff --git a/tests/test_codemod_docs.py b/tests/test_codemod_docs.py index a2fa46f2..963116ce 100644 --- a/tests/test_codemod_docs.py +++ b/tests/test_codemod_docs.py @@ -12,7 +12,6 @@ def pytest_generate_tests(metafunc): def test_load_codemod_docs_info(codemod: BaseCodemod): - print(codemod.name) if codemod.name in ["order-imports"]: pytest.xfail(reason=f"{codemod.name} has no description") From 7e7d411157219aa8e2be6318430da28c454894ab Mon Sep 17 00:00:00 2001 From: andrecs <12188364+andrecsilva@users.noreply.github.com> Date: Mon, 29 Jan 2024 08:29:58 -0300 Subject: [PATCH 7/7] Changed how ResultSet are combined and added tests --- src/codemodder/result.py | 15 ++++++++++- tests/test_results.py | 55 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 tests/test_results.py diff --git a/src/codemodder/result.py b/src/codemodder/result.py index b268c7d2..0c1743ed 100644 --- a/src/codemodder/result.py +++ b/src/codemodder/result.py @@ -1,5 +1,6 @@ from dataclasses import dataclass from pathlib import Path +from typing import Any from .utils.abc_dataclass import ABCDataclass @@ -49,4 +50,16 @@ def all_rule_ids(self) -> list[str]: return list(self.keys()) def __or__(self, other): - return ResultSet(super().__or__(other)) + result = ResultSet(super().__or__(other)) + for k in self.keys() | other.keys(): + result[k] = list_dict_or(self[k], other[k]) + return result + + +def list_dict_or( + dictionary: dict[Any, list[Any]], other: dict[Any, list[Any]] +) -> dict[Path, list[Any]]: + result_dict = other | dictionary + for k in other.keys() | dictionary.keys(): + result_dict[k] = dictionary[k] + other[k] + return result_dict diff --git a/tests/test_results.py b/tests/test_results.py new file mode 100644 index 00000000..5f34bfd6 --- /dev/null +++ b/tests/test_results.py @@ -0,0 +1,55 @@ +import json +from pathlib import Path +from codemodder.sonar_results import SonarResultSet + + +class TestResults: + def test_or(self, tmpdir): + issues1 = { + "issues": [ + { + "rule": "rule", + "component": "code.py", + "textRange": { + "startLine": 2, + "endLine": 2, + "startOffset": 2, + "endOffset": 2, + }, + } + ] + } + issues2 = { + "issues": [ + { + "rule": "rule", + "component": "code.py", + "textRange": { + "startLine": 1, + "endLine": 1, + "startOffset": 1, + "endOffset": 1, + }, + } + ] + } + sonar_json1 = Path(tmpdir) / "sonar1.json" + sonar_json1.write_text(json.dumps(issues1)) + sonar_json2 = Path(tmpdir) / "sonar2.json" + sonar_json2.write_text(json.dumps(issues2)) + + result1 = SonarResultSet.from_json(sonar_json1) + result2 = SonarResultSet.from_json(sonar_json2) + + combined = result1 | result2 + assert len(combined["rule"][Path("code.py")]) == 2 + assert result2["rule"][Path("code.py")][0] in combined["rule"][Path("code.py")] + assert result1["rule"][Path("code.py")][0] in combined["rule"][Path("code.py")] + + def test_sonar_robustness(self, tmpdir): + sonar_json = Path(tmpdir) / "sonar1.json" + # not a valid json + sonar_json.touch() + result = SonarResultSet.from_json(sonar_json) + # did not crash and returned an empty ResultSet + assert not result