Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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[]{
4, 5, 6, 16, 21, 28, 29
};
int[] endLines = new int[]{
4, 5, 6, 16, 21, 28, 29
Copy link

Copilot AI Oct 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The line numbers in the integration test don't match the actual wildcard import lines in the test file. Based on the test file, wildcard imports are on lines 2, 3, 5, and 8, not the specified lines.

Suggested change
4, 5, 6, 16, 21, 28, 29
};
int[] endLines = new int[]{
4, 5, 6, 16, 21, 28, 29
2, 3, 5, 8
};
int[] endLines = new int[]{
2, 3, 5, 8

Copilot uses AI. Check for mistakes.
};

checkIssuesForFile(filePath, ruleId, ruleMsg, startLines, endLines, SEVERITY, TYPE, EFFORT_5MIN);
}

}
Original file line number Diff line number Diff line change
@@ -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()

Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"GCI106",
"GCI107",
"GCI108",
"GCI110",
"GCI203",
"GCI404"
]
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/
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());
}
}

33 changes: 33 additions & 0 deletions src/test/resources/checks/avoidWildcardImports.py
Original file line number Diff line number Diff line change
@@ -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