Place choices that do not pull in new slots into a preferred
choice bin, so that they will not be mixed with choices that
contain unnecessary upgrades. This fixes the included test
case so that an unnecessary new python slot is not pulled in.

Bug: https://bugs.gentoo.org/828136
Signed-off-by: Zac Medico <zmed...@gentoo.org>
---
 lib/portage/dep/dep_check.py                  |  6 +-
 .../resolver/test_unecessary_slot_upgrade.py  | 62 +++++++++++++++++++
 2 files changed, 67 insertions(+), 1 deletion(-)
 create mode 100644 lib/portage/tests/resolver/test_unecessary_slot_upgrade.py

diff --git a/lib/portage/dep/dep_check.py b/lib/portage/dep/dep_check.py
index 9fccda08b..8ca4c0b9d 100644
--- a/lib/portage/dep/dep_check.py
+++ b/lib/portage/dep/dep_check.py
@@ -376,6 +376,7 @@ def dep_zapdeps(
     # c) contains masked installed packages
     # d) is the first item
 
+    no_new_slots = []
     preferred_in_graph = []
     preferred_installed = preferred_in_graph
     preferred_any_slot = preferred_in_graph
@@ -391,6 +392,7 @@ def dep_zapdeps(
     # unsat_use_* must come after preferred_non_installed
     # for correct ordering in cases like || ( foo[a] foo[b] ).
     choice_bins = (
+        no_new_slots,
         preferred_in_graph,
         preferred_non_installed,
         unsat_use_in_graph,
@@ -689,7 +691,9 @@ def dep_zapdeps(
                     other.append(this_choice)
                 else:
                     if all_use_satisfied:
-                        if all_in_graph:
+                        if new_slot_count == 0 and not want_update:
+                            no_new_slots.append(this_choice)
+                        elif all_in_graph:
                             preferred_in_graph.append(this_choice)
                         elif all_installed:
                             if all_installed_slots:
diff --git a/lib/portage/tests/resolver/test_unecessary_slot_upgrade.py 
b/lib/portage/tests/resolver/test_unecessary_slot_upgrade.py
new file mode 100644
index 000000000..f8b8b346a
--- /dev/null
+++ b/lib/portage/tests/resolver/test_unecessary_slot_upgrade.py
@@ -0,0 +1,62 @@
+# Copyright 2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+from portage.tests import TestCase
+from portage.tests.resolver.ResolverPlayground import (
+    ResolverPlayground,
+    ResolverPlaygroundTestCase,
+)
+
+
+class UnnecessarySlotrUpgradeTestCase(TestCase):
+    def testUnnecessarySlotUpgrade(self):
+        ebuilds = {
+            "app-misc/a-1": {
+                "EAPI": "8",
+                "RDEPEND": "|| ( dev-lang/python:3.10 dev-lang/python:3.9 ) || 
( dev-lang/python:3.10 dev-lang/python:3.9 )",
+            },
+            "dev-lang/python-3.9": {"SLOT": "3.9"},
+            "dev-lang/python-3.10": {"SLOT": "3.10"},
+        }
+
+        installed = {
+            "dev-lang/python-3.9": {"SLOT": "3.9"},
+        }
+
+        test_cases = (
+            # Test bug 828136, where an unnecessary python slot upgrade
+            # was triggered.
+            ResolverPlaygroundTestCase(
+                [
+                    "app-misc/a",
+                ],
+                success=True,
+                mergelist=("app-misc/a-1",),
+            ),
+            ResolverPlaygroundTestCase(
+                [
+                    "app-misc/a",
+                ],
+                success=True,
+                mergelist=(
+                    "dev-lang/python-3.10",
+                    "app-misc/a-1",
+                ),
+                options={
+                    "--deep": True,
+                    "--update": True,
+                },
+            ),
+        )
+
+        playground = ResolverPlayground(
+            debug=False, ebuilds=ebuilds, installed=installed
+        )
+
+        try:
+            for test_case in test_cases:
+                playground.run_TestCase(test_case)
+                self.assertEqual(test_case.test_success, True, 
test_case.fail_msg)
+        finally:
+            playground.debug = False
+            playground.cleanup()
-- 
2.32.0


Reply via email to