commit:     eb95e06748bf39b6a708cfc9ae9e87afb13da9f2
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Sat Jul 26 05:37:12 2025 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Sat Jul 26 06:13:55 2025 +0000
URL:        
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=eb95e067

PythonCheck: check for redundant PYTEST_DISABLE_PLUGIN_AUTOLOAD

Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>
Closes: https://github.com/pkgcore/pkgcheck/pull/753
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org>

 src/pkgcheck/checks/python.py                      | 38 ++++++++++++++++++++++
 .../expected.json                                  |  1 +
 .../RedundantPyTestDisablePluginAutoload/fix.patch | 12 +++++++
 .../RedundantPyTestDisablePluginAutoload-0.ebuild  | 20 ++++++++++++
 .../RedundantPyTestDisablePluginAutoload-1.ebuild  | 23 +++++++++++++
 .../RedundantPyTestDisablePluginAutoload-2.ebuild  | 22 +++++++++++++
 6 files changed, 116 insertions(+)

diff --git a/src/pkgcheck/checks/python.py b/src/pkgcheck/checks/python.py
index 281df257..9a451c11 100644
--- a/src/pkgcheck/checks/python.py
+++ b/src/pkgcheck/checks/python.py
@@ -279,6 +279,21 @@ class ShadowedEPyTestTimeout(results.LineResult, 
results.Warning):
         )
 
 
+class RedundantPyTestDisablePluginAutoload(results.LineResult, 
results.Warning):
+    """Redundant ``PYTEST_DISABLE_PLUGIN_AUTOLOAD``
+
+    The package uses ``EPYTEST_PLUGINS`` to disable plugin autoloading already,
+    so ``PYTEST_DISABLE_PLUGIN_AUTOLOAD`` is redundant.
+    """
+
+    @property
+    def desc(self):
+        return (
+            f"line {self.lineno}: PYTEST_DISABLE_PLUGIN_AUTOLOAD is redundant, 
"
+            "autoloading disabled via EPYTEST_PLUGINS already"
+        )
+
+
 class PythonCheck(Check):
     """Python eclass checks.
 
@@ -302,6 +317,7 @@ class PythonCheck(Check):
             PythonMissingSCMDependency,
             MisplacedEPyTestVar,
             ShadowedEPyTestTimeout,
+            RedundantPyTestDisablePluginAutoload,
         }
     )
 
@@ -472,12 +488,34 @@ class PythonCheck(Check):
                     line = pkg.node_str(var_node)
                     yield MisplacedEPyTestVar(var_name, line=line, 
lineno=lineno + 1, pkg=pkg)
 
+        have_epytest_plugins = False
+        have_epytest_plugin_autoload = False
+        found_pytest_disable_plugin_autoload = []
+
         for var_node in 
bash.var_assign_query.captures(pkg.tree.root_node).get("assign", ()):
             var_name = pkg.node_str(var_node.child_by_field_name("name"))
             if var_name == "EPYTEST_TIMEOUT":
                 lineno, _ = var_node.start_point
                 line = pkg.node_str(var_node)
                 yield ShadowedEPyTestTimeout(line=line, lineno=lineno + 1, 
pkg=pkg)
+            elif var_name == "EPYTEST_PLUGINS":
+                have_epytest_plugins = True
+            elif var_name == "EPYTEST_PLUGIN_AUTOLOAD":
+                if value_node := var_node.child_by_field_name("value"):
+                    value = pkg.node_str(value_node)
+                    if value not in ('""', "''"):
+                        have_epytest_plugin_autoload = True
+            elif var_name == "PYTEST_DISABLE_PLUGIN_AUTOLOAD":
+                lineno, _ = var_node.start_point
+                line = pkg.node_str(var_node)
+                found_pytest_disable_plugin_autoload.append((line, lineno))
+
+        # EAPI 9+ defaults to disabled autoloading, in earlier EAPIs 
EPYTEST_PLUGINS does that.
+        if (
+            str(pkg.eapi) not in ("7", "8") or have_epytest_plugins
+        ) and not have_epytest_plugin_autoload:
+            for line, lineno in found_pytest_disable_plugin_autoload:
+                yield RedundantPyTestDisablePluginAutoload(line=line, 
lineno=lineno + 1, pkg=pkg)
 
     @staticmethod
     def _prepare_deps(deps: str):

diff --git 
a/testdata/data/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/expected.json
 
b/testdata/data/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/expected.json
new file mode 100644
index 00000000..3929a193
--- /dev/null
+++ 
b/testdata/data/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/expected.json
@@ -0,0 +1 @@
+{"__class__": "RedundantPyTestDisablePluginAutoload", "category": 
"PythonCheck", "package": "RedundantPyTestDisablePluginAutoload", "version": 
"0", "line": "PYTEST_DISABLE_PLUGIN_AUTOLOAD=1", "lineno": 18}

diff --git 
a/testdata/data/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/fix.patch
 
b/testdata/data/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/fix.patch
new file mode 100644
index 00000000..e6265c4b
--- /dev/null
+++ 
b/testdata/data/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/fix.patch
@@ -0,0 +1,12 @@
+diff '--color=auto' -Naur 
python/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-0.ebuild
 
fixed/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-0.ebuild
+--- 
python/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-0.ebuild
      2025-07-26 07:27:39.236976885 +0200
++++ 
fixed/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-0.ebuild
       2025-07-26 07:32:32.758757644 +0200
+@@ -13,8 +13,3 @@
+ EPYTEST_PLUGINS=()
+ 
+ distutils_enable_tests pytest
+-
+-python_test() {
+-      local -x PYTEST_DISABLE_PLUGIN_AUTOLOAD=1
+-      epytest
+-}

diff --git 
a/testdata/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-0.ebuild
 
b/testdata/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-0.ebuild
new file mode 100644
index 00000000..6f941115
--- /dev/null
+++ 
b/testdata/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-0.ebuild
@@ -0,0 +1,20 @@
+EAPI=8
+
+DISTUTILS_USE_PEP517=flit
+PYTHON_COMPAT=( python3_10 )
+
+inherit distutils-r1
+
+DESCRIPTION="Ebuild with redundant disable-autoload"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+LICENSE="BSD"
+SLOT="0"
+
+EPYTEST_PLUGINS=()
+
+distutils_enable_tests pytest
+
+python_test() {
+       local -x PYTEST_DISABLE_PLUGIN_AUTOLOAD=1
+       epytest
+}

diff --git 
a/testdata/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-1.ebuild
 
b/testdata/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-1.ebuild
new file mode 100644
index 00000000..219159cd
--- /dev/null
+++ 
b/testdata/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-1.ebuild
@@ -0,0 +1,23 @@
+EAPI=8
+
+DISTUTILS_USE_PEP517=flit
+PYTHON_COMPAT=( python3_10 )
+
+inherit distutils-r1
+
+DESCRIPTION="Ebuild with non-redundant disable-autoload"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+LICENSE="BSD"
+SLOT="0"
+
+EPYTEST_PLUGINS=()
+EPYTEST_PLUGIN_AUTOLOAD=1
+
+distutils_enable_tests pytest
+
+python_test() {
+       epytest test_one.py
+
+       local -x PYTEST_DISABLE_PLUGIN_AUTOLOAD=1
+       epytest test_two.py
+}

diff --git 
a/testdata/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-2.ebuild
 
b/testdata/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-2.ebuild
new file mode 100644
index 00000000..70add61b
--- /dev/null
+++ 
b/testdata/repos/python/PythonCheck/RedundantPyTestDisablePluginAutoload/RedundantPyTestDisablePluginAutoload-2.ebuild
@@ -0,0 +1,22 @@
+EAPI=8
+
+DISTUTILS_USE_PEP517=flit
+PYTHON_COMPAT=( python3_10 )
+
+inherit distutils-r1
+
+DESCRIPTION="Ebuild reenabling autoload"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+LICENSE="BSD"
+SLOT="0"
+
+EPYTEST_PLUGINS=()
+
+distutils_enable_tests pytest
+
+python_test() {
+       epytest test_one.py
+
+       unset PYTEST_DISABLE_PLUGIN_AUTOLOAD
+       epytest test_two.py
+}

Reply via email to