Repository: conan-io/conan

Issue:
[error] Error when calling conanfile.info.clone()
I am trying to achieve VS downward compatibility by using the new feature in package info.
I have the following method:

```
def enable_visual_studio_downward_compatibility(conanfile):
    if conanfile.settings.compiler == "Visual Studio" and conanfile.settings.compiler.version == "16":
        for version in ("15", "14"):
            compatible_pkg = conanfile.info.clone()
            compatible_pkg.settings.compiler.version = version
            conanfile.compatible_packages.append(compatible_pkg)
    if conanfile.settings.compiler == "Visual Studio" and conanfile.settings.compiler.version == "15":
        for version in ("14"):
            compatible_pkg = conanfile.info.clone()
            compatible_pkg.settings.compiler.version = version
            conanfile.compatible_packages.append(compatible_pkg)
```

And the package uses:

```
 def package_id(self):
   enable_visual_studio_downward_compatibility(self)
```

From my understanding and reading the documentation, this is the right way to enable compatibility.
However, when a VS2019 consumer tries to consume a VS2015 package, I get the following error:

```
ERROR: package/version@user/stable: Error in package_id() method, line 53
        enable_visual_studio_downward_compatibility(self)
while calling 'enable_visual_studio_downward_compatibility', line 8
        compatible_pkg = conanfile.info.clone()
        ConanException: 'minor_mode' is not a known package_id_mode
```

Is this a bug or am I doing something wrong here? (I am using Conan 1.22.2)


Discussion:

Resolving patch:
diff --git a/conans/model/info.py b/conans/model/info.py
--- a/conans/model/info.py
+++ b/conans/model/info.py
@@ -352,7 +352,8 @@ def __init__(self, refs, default_package_id_mode):
 
     def copy(self):
         # For build_id() implementation
-        return PythonRequiresInfo(self._refs, self._default_package_id_mode)
+        refs = [r._ref for r in self._refs] if self._refs else None
+        return PythonRequiresInfo(refs, self._default_package_id_mode)
 
     def __bool__(self):
         return bool(self._refs)


Test patch:
diff --git a/conans/test/functional/package_id/compatible_test.py b/conans/test/functional/package_id/compatible_test.py
--- a/conans/test/functional/package_id/compatible_test.py
+++ b/conans/test/functional/package_id/compatible_test.py
@@ -465,3 +465,31 @@ def package_id(self):
         self.assertIn("pkg/0.1@user/testing:cb054d0b3e1ca595dc66bc2339d40f1f8f04ab31 - Cache",
                       client.out)
         self.assertIn("pkg/0.1@user/testing: Already installed!", client.out)
+
+    def compatible_package_python_requires_test(self):
+        # https://github.com/conan-io/conan/issues/6609
+        client = TestClient()
+        client.save({"conanfile.py": GenConanfile()})
+        client.run("export . tool/0.1@")
+        conanfile = textwrap.dedent("""
+            from conans import ConanFile
+
+            class Conan(ConanFile):
+                settings = "os"
+                python_requires = "tool/0.1"
+
+                def package_id(self):
+                   if self.settings.os == "Windows":
+                       compatible = self.info.clone()
+                       compatible.settings.os = "Linux"
+                       self.compatible_packages.append(compatible)
+                """)
+
+        client.save({"conanfile.py": conanfile})
+        client.run("create . pkg/0.1@user/testing -s os=Linux")
+
+        client.save({"conanfile.py": GenConanfile().with_require_plain("pkg/0.1@user/testing")})
+        client.run("install . -s os=Windows")
+        self.assertIn("pkg/0.1@user/testing:1ebf4db7209535776307f9cd06e00d5a8034bc84 - Cache",
+                      client.out)
+        self.assertIn("pkg/0.1@user/testing: Already installed!", client.out)
diff --git a/conans/test/functional/py_requires/python_requires_test.py b/conans/test/functional/py_requires/python_requires_test.py
--- a/conans/test/functional/py_requires/python_requires_test.py
+++ b/conans/test/functional/py_requires/python_requires_test.py
@@ -752,3 +752,21 @@ def build(self):
         client2.run("build .")
         self.assertIn("conanfile.py: Build: tool header: myheader", client2.out)
         self.assertIn("conanfile.py: Build: tool other: otherheader", client2.out)
+
+    def test_build_id(self):
+        client = TestClient(default_server_user=True)
+        self._define_base(client)
+        reuse = textwrap.dedent("""
+            from conans import ConanFile
+            class PkgTest(ConanFile):
+                python_requires = "base/1.1@user/testing"
+                python_requires_extend = "base.MyConanfileBase"
+                def build_id(self):
+                    pass
+            """)
+        client.save({"conanfile.py": reuse}, clean_first=True)
+        client.run("create . Pkg/0.1@user/testing")
+        self.assertIn("Pkg/0.1@user/testing: My cool source!", client.out)
+        self.assertIn("Pkg/0.1@user/testing: My cool build!", client.out)
+        self.assertIn("Pkg/0.1@user/testing: My cool package!", client.out)
+        self.assertIn("Pkg/0.1@user/testing: My cool package_info!", client.out)