diff --git a/src/it/java/org/greencodeinitiative/creedengo/python/integration/tests/GCIRulesIT.java b/src/it/java/org/greencodeinitiative/creedengo/python/integration/tests/GCIRulesIT.java index 4fab77f..1cdee13 100644 --- a/src/it/java/org/greencodeinitiative/creedengo/python/integration/tests/GCIRulesIT.java +++ b/src/it/java/org/greencodeinitiative/creedengo/python/integration/tests/GCIRulesIT.java @@ -462,4 +462,19 @@ void testGCI108(){ checkIssuesForFile(filePath, ruleId, ruleMsg, startLines, endLines, SEVERITY, TYPE, EFFORT_10MIN); } + @Test + void testGCI110(){ + String filePath = "src/avoidWildcardImports.py"; + String ruleId = "creedengo-python:GCI110"; + String ruleMsg = "Avoid wildcard imports"; + int[] startLines = new int[]{ + 2, 3, 5, 8 + }; + int[] endLines = new int[]{ + 2, 3, 5, 8 + }; + + checkIssuesForFile(filePath, ruleId, ruleMsg, startLines, endLines, SEVERITY, TYPE, EFFORT_5MIN); + } + } diff --git a/src/it/test-projects/creedengo-python-plugin-test-project/src/avoidWildcardImports.py b/src/it/test-projects/creedengo-python-plugin-test-project/src/avoidWildcardImports.py new file mode 100644 index 0000000..6cfdbed --- /dev/null +++ b/src/it/test-projects/creedengo-python-plugin-test-project/src/avoidWildcardImports.py @@ -0,0 +1,22 @@ +### Non-compliant cases ### +from math import * # Noncompliant {{Avoid wildcard imports}} +from my_module import * # Noncompliant {{Avoid wildcard imports}} +def some_function(): + from collections import * # Noncompliant {{Avoid wildcard imports}} + return deque() +if True: + from json import * # Noncompliant {{Avoid wildcard imports}} + + +### Compliant cases ### +from math import sqrt, pi, sin, cos +import os + +import my_module + +from datetime import datetime as dt + +def another_function(): + from collections import deque + return deque() + diff --git a/src/main/java/org/greencodeinitiative/creedengo/python/PythonRuleRepository.java b/src/main/java/org/greencodeinitiative/creedengo/python/PythonRuleRepository.java index ad4955e..95842fb 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/python/PythonRuleRepository.java +++ b/src/main/java/org/greencodeinitiative/creedengo/python/PythonRuleRepository.java @@ -50,7 +50,8 @@ public record PythonRuleRepository(SonarRuntime sonarRuntime) implements RulesDe DisableGradientForModelEval.class, StringConcatenation.class, PreferAppendLeft.class, - AvoidCreatingTensorUsingNumpyOrNativePython.class + AvoidCreatingTensorUsingNumpyOrNativePython.class, + AvoidWildcardImportsCheck.class ); public static final String LANGUAGE = "py"; diff --git a/src/main/java/org/greencodeinitiative/creedengo/python/checks/AvoidWildcardImportsCheck.java b/src/main/java/org/greencodeinitiative/creedengo/python/checks/AvoidWildcardImportsCheck.java new file mode 100644 index 0000000..ef64e53 --- /dev/null +++ b/src/main/java/org/greencodeinitiative/creedengo/python/checks/AvoidWildcardImportsCheck.java @@ -0,0 +1,44 @@ +/* + * creedengo - Python language - Provides rules to reduce the environmental footprint of your Python programs + * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.creedengo.python.checks; + +import org.sonar.check.Rule; +import org.sonar.plugins.python.api.PythonSubscriptionCheck; +import org.sonar.plugins.python.api.SubscriptionContext; +import org.sonar.plugins.python.api.tree.ImportFrom; +import org.sonar.plugins.python.api.tree.Tree; + +@Rule(key = "GCI110") +public class AvoidWildcardImportsCheck extends PythonSubscriptionCheck { + + public static final String DESCRIPTION = "Avoid wildcard imports"; + + @Override + public void initialize(Context context) { + context.registerSyntaxNodeConsumer(Tree.Kind.IMPORT_FROM, this::visitImportFrom); + } + + private void visitImportFrom(SubscriptionContext context) { + ImportFrom importFrom = (ImportFrom) context.syntaxNode(); + + if (importFrom.isWildcardImport()) { + context.addIssue(importFrom, DESCRIPTION); + } + } +} + diff --git a/src/main/resources/org/greencodeinitiative/creedengo/python/creedengo_way_profile.json b/src/main/resources/org/greencodeinitiative/creedengo/python/creedengo_way_profile.json index d33223c..d691b21 100644 --- a/src/main/resources/org/greencodeinitiative/creedengo/python/creedengo_way_profile.json +++ b/src/main/resources/org/greencodeinitiative/creedengo/python/creedengo_way_profile.json @@ -22,6 +22,7 @@ "GCI106", "GCI107", "GCI108", + "GCI110", "GCI203", "GCI404" ] diff --git a/src/test/java/org/greencodeinitiative/creedengo/python/checks/AvoidWildcardImportsCheckTest.java b/src/test/java/org/greencodeinitiative/creedengo/python/checks/AvoidWildcardImportsCheckTest.java new file mode 100644 index 0000000..0a5a56b --- /dev/null +++ b/src/test/java/org/greencodeinitiative/creedengo/python/checks/AvoidWildcardImportsCheckTest.java @@ -0,0 +1,30 @@ +/* + * creedengo - Python language - Provides rules to reduce the environmental footprint of your Python programs + * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.greencodeinitiative.creedengo.python.checks; + +import org.junit.jupiter.api.Test; +import org.sonar.python.checks.utils.PythonCheckVerifier; + +public class AvoidWildcardImportsCheckTest { + + @Test + public void test() { + PythonCheckVerifier.verify("src/test/resources/checks/avoidWildcardImports.py", new AvoidWildcardImportsCheck()); + } +} + diff --git a/src/test/resources/checks/avoidWildcardImports.py b/src/test/resources/checks/avoidWildcardImports.py new file mode 100644 index 0000000..7a0d6ff --- /dev/null +++ b/src/test/resources/checks/avoidWildcardImports.py @@ -0,0 +1,33 @@ +### Non-compliant cases ### +from math import * # Noncompliant {{Avoid wildcard imports}} +from os import * # Noncompliant {{Avoid wildcard imports}} +from sys import * # Noncompliant {{Avoid wildcard imports}} +from my_module import * # Noncompliant {{Avoid wildcard imports}} +def some_function(): + from collections import * # Noncompliant {{Avoid wildcard imports}} + return deque() +from typing import * # Noncompliant {{Avoid wildcard imports}} +from itertools import * # Noncompliant {{Avoid wildcard imports}} +if True: + from json import * # Noncompliant {{Avoid wildcard imports}} + + + +### Compliant cases ### +from math import sqrt, pi, sin, cos +from os import path, listdir +import math +import os + +import my_module + +from datetime import datetime as dt + +def another_function(): + from collections import deque + return deque() + +from typing import List, Dict, Optional + + +import collections