Repository: conan-io/conan
Pull request #16272 (2024-05-16 08:21:16)

Disallow info access in source() method
Changelog: Bugfix: Disallow `self.info` access in `source()` method
Docs: Omit


As mentioned in https://github.com/conan-io/conan/issues/15666, `self.info` access in the `source()` method was a leak - it was not intended to be used inside said method, and accesses to the attribute were a bug by design, as the source method must not rely on configuration values to change its behaviour

Also adds some more beloved light=True in this file for those tests that pass with it



Patch:
diff --git a/conans/client/source.py b/conans/client/source.py
index ab812a45c..6c7617242 100644
--- a/conans/client/source.py
+++ b/conans/client/source.py
@@ -82,6 +82,6 @@ def run_source_method(conanfile, hook_manager):
         if hasattr(conanfile, "source"):
             conanfile.output.highlight("Calling source() in {}".format(conanfile.source_folder))
             with conanfile_exception_formatter(conanfile, "source"):
-                with conanfile_remove_attr(conanfile, ['settings', "options"], "source"):
+                with conanfile_remove_attr(conanfile, ['info', 'settings', "options"], "source"):
                     conanfile.source()
         hook_manager.execute("post_source", conanfile=conanfile)


Test patch:
diff --git a/conans/test/integration/command/source_test.py b/conans/test/integration/command/source_test.py
index 57644154e..1cc684d24 100644
--- a/conans/test/integration/command/source_test.py
+++ b/conans/test/integration/command/source_test.py
@@ -35,7 +35,7 @@ class TestexportConan(ConanFile):
         python = os.path.join(self.recipe_folder, "mypython.py")
         self.output.info("PYTHON: %s" % load(self, python))
 """
-        client = TestClient()
+        client = TestClient(light=True)
         client.save({"conanfile.py": conanfile,
                      "patch.patch": "mypatch",
                      "mypython.py": "mypython"})
@@ -53,7 +53,7 @@ class TestexportConan(ConanFile):
         # https://github.com/conan-io/conan/issues/2327
         # Test if a patch can be applied in source() both in create
         # and local flow
-        client = TestClient()
+        client = TestClient(light=True)
         conanfile = """from conan import ConanFile
 from conan.tools.files import load
 import os
@@ -78,13 +78,13 @@ class Pkg(ConanFile):
 class ConanLib(ConanFile):
     pass
 '''
-        client = TestClient()
+        client = TestClient(light=True)
         client.save({CONANFILE: conanfile})
         client.run("source .")
         self.assertNotIn("This package defines both 'os' and 'os_build'", client.out)
 
     def test_source_with_path_errors(self):
-        client = TestClient()
+        client = TestClient(light=True)
         client.save({"conanfile.txt": "contents"}, clean_first=True)
 
         # Path with conanfile.txt
@@ -107,7 +107,7 @@ class ConanLib(ConanFile):
         self.output.info("Running source!")
         self.output.info("cwd=>%s" % os.getcwd())
 '''
-        client = TestClient()
+        client = TestClient(light=True)
         client.save({CONANFILE: conanfile})
 
         client.run("install .")
@@ -128,7 +128,7 @@ class ConanLib(ConanFile):
         save("file1.txt", "Hello World")
 '''
         # First, failing source()
-        client = TestClient()
+        client = TestClient(light=True)
         client.save({CONANFILE: conanfile})
 
         client.run("source .", assert_error=True)
@@ -229,7 +229,7 @@ class ConanLib(ConanFile):
                     assert False
             ''')
 
-        client = TestClient()
+        client = TestClient(light=True)
         client.save({CONANFILE: conanfile})
 
         client.run("create . --name=lib --version=1.0", assert_error=True)
@@ -294,3 +294,18 @@ def test_source_python_requires():
     c.run("source . ")
     assert "pytool/0.1: Not found in local cache, looking in remotes" in c.out
     assert "pytool/0.1: Downloaded recipe" in c.out
+
+
+@pytest.mark.parametrize("attribute", ["info", "settings", "options"])
+def test_source_method_forbidden_attributes(attribute):
+    conanfile = textwrap.dedent(f"""
+    from conan import ConanFile
+    class Package(ConanFile):
+        def source(self):
+            self.output.info(self.{attribute})
+    """)
+    client = TestClient(light=True)
+    client.save({"conanfile.py": conanfile})
+
+    client.run("source .", assert_error=True)
+    assert f"'self.{attribute}' access in 'source()' method is forbidden" in client.out