Repository: conan-io/conan
Pull request #17338 (2024-11-18 22:05:58)

trying to fix is_test
Changelog: Bugfix: Fixing ``is_test`` computation affecting to components checks
Docs: Omit

Close https://github.com/conan-io/conan/issues/17312



Patch:
diff --git a/conans/__init__.py b/conans/__init__.py
index 01522d5b7..92b87aef0 100644
--- a/conans/__init__.py
+++ b/conans/__init__.py
@@ -1,4 +1,4 @@
 CHECKSUM_DEPLOY = "checksum_deploy"  # Only when v2
 REVISIONS = "revisions"  # Only when enabled in config, not by default look at server_launcher.py
 
-__version__ = '2.9.2'
+__version__ = '2.9.3'
diff --git a/conans/model/requires.py b/conans/model/requires.py
index cb819d74e..9d98a6711 100644
--- a/conans/model/requires.py
+++ b/conans/model/requires.py
@@ -254,6 +254,7 @@ class Requirement:
         self.transitive_libs = self.transitive_libs or other.transitive_libs
         if not other.test:
             self.test = False  # it it was previously a test, but also required by non-test
+        # necessary even if no propagation, order of requires matter
         self.is_test = self.is_test or other.is_test
         # package_id_mode is not being propagated downstream. So it is enough to check if the
         # current require already defined it or not
@@ -345,7 +346,6 @@ class Requirement:
 
         if self.test:
             downstream_require.test = True
-        downstream_require.is_test = require.is_test
 
         # If the current one is resolving conflicts, the downstream one will be too
         downstream_require.force = require.force


Test patch:
diff --git a/test/integration/graph/test_test_requires.py b/test/integration/graph/test_test_requires.py
index 5342bc3ad..d74bec93a 100644
--- a/test/integration/graph/test_test_requires.py
+++ b/test/integration/graph/test_test_requires.py
@@ -203,6 +203,8 @@ def test_requires_transitive_diamond_components_order():
     like the above, but in different order
      libc  --(test-requires)---> liba
        |-----> libb -----------/
+    libc->liba => test=False, direct=True, is_test=True
+    direct_dependencies (components check) => False
     https://github.com/conan-io/conan/issues/17164
     """
     c = TestClient(light=True)
@@ -230,6 +232,48 @@ def test_requires_transitive_diamond_components_order():
     assert "libc/0.1: Created package" in c.out
 
 
+def test_wrong_requirement_test_requires():
+    """ https://github.com/conan-io/conan/issues/17312
+
+    app --------> etas --------------> enum
+      \\-->hwinfo-/---(test_requires)---/
+       \\-----------------------------/
+
+    app->enum => test=False, direct=True, is_test=True
+    direct_dependencies (components check) => True
+    """
+    c = TestClient(light=True)
+    app = textwrap.dedent("""
+        from conan import ConanFile
+        class Pkg(ConanFile):
+            name = "app"
+            version = "0.1"
+            requires = "etas/0.1", "enum/0.1", "hwinfo/0.1"
+
+            def generate(self):
+                for r, d in self.dependencies.items():
+                    assert not (r.direct and r.is_test)
+
+            def package_info(self):
+                self.cpp_info.requires = ["etas::etas", "enum::enum", "hwinfo::hwinfo"]
+            """)
+    files = {
+        "enum/conanfile.py": GenConanfile("enum", "0.1"),
+        "etas/conanfile.py": GenConanfile("etas", "0.1").with_requirement("enum/0.1"),
+        "hwinfo/conanfile.py": GenConanfile("hwinfo", "0.1").with_requirement("etas/0.1")
+                                                            .with_test_requires("enum/0.1"),
+        "app/conanfile.py": app,
+    }
+    c.save(files)
+    c.run("create enum")
+    c.run("create etas")
+    c.run("create hwinfo")
+    # The assert in generate() doesnt fail
+    c.run("install app")
+    # the package_info() doesn't fail
+    c.run("create app")
+
+
 def test_test_requires_options():
     """ the default_options = {} values also propagate to ``test_requires()`` """
     c = TestClient(light=True)