From aa958ba0a94ac3217148ccfd1440e933fb6ef297 Mon Sep 17 00:00:00 2001
From: Arun Babu Neelicattu <arun.neelicattu@gmail.com>
Date: Fri, 20 May 2022 21:48:06 +0200
Subject: [PATCH 1/2] mixology: choose direct ref deps when merging

---
 src/poetry/mixology/term.py | 35 ++++++++++++++++++++++++++++-------
 tests/puzzle/test_solver.py |  6 +++++-
 2 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/src/poetry/mixology/term.py b/src/poetry/mixology/term.py
index 260567b1b7f..b208c2635ca 100644
--- a/src/poetry/mixology/term.py
+++ b/src/poetry/mixology/term.py
@@ -127,17 +127,17 @@ def intersect(self, other: Term) -> Term | None:
                 negative = other if self.is_positive() else self
 
                 return self._non_empty_term(
-                    positive.constraint.difference(negative.constraint), True
+                    positive.constraint.difference(negative.constraint), True, other
                 )
             elif self.is_positive():
                 # foo ^1.0.0 ∩ foo >=1.5.0 <3.0.0 → foo ^1.5.0
                 return self._non_empty_term(
-                    self.constraint.intersect(other.constraint), True
+                    self.constraint.intersect(other.constraint), True, other
                 )
             else:
                 # not foo ^1.0.0 ∩ not foo >=1.5.0 <3.0.0 → not foo >=1.0.0 <3.0.0
                 return self._non_empty_term(
-                    self.constraint.union(other.constraint), False
+                    self.constraint.union(other.constraint), False, other
                 )
         elif self.is_positive() != other.is_positive():
             return self if self.is_positive() else other
@@ -151,21 +151,42 @@ def difference(self, other: Term) -> Term | None:
         """
         return self.intersect(other.inverse)
 
+    @staticmethod
+    def _is_direct_origin(dependency: Dependency) -> bool:
+        return dependency.source_type in ["directory", "file", "url", "git"]
+
     def _compatible_dependency(self, other: Dependency) -> bool:
-        compatible: bool = (
+        return (
             self.dependency.is_root
             or other.is_root
             or other.is_same_package_as(self.dependency)
+            or (
+                # we do this here to indicate direct origin dependencies are
+                # compatible with NVR dependencies
+                self.dependency.complete_name == other.complete_name
+                and self._is_direct_origin(self.dependency)
+                != self._is_direct_origin(other)
+                and (
+                    self.dependency.constraint.allows_all(other.constraint)
+                    or other.constraint.allows_all(self.dependency.constraint)
+                )
+            )
         )
-        return compatible
 
     def _non_empty_term(
-        self, constraint: VersionConstraint, is_positive: bool
+        self, constraint: VersionConstraint, is_positive: bool, other: Term
     ) -> Term | None:
         if constraint.is_empty():
             return None
 
-        return Term(self.dependency.with_constraint(constraint), is_positive)
+        # when creating a new term prefer direct-reference dependencies
+        dependency = (
+            other.dependency
+            if not self._is_direct_origin(self.dependency)
+            and self._is_direct_origin(other.dependency)
+            else self.dependency
+        )
+        return Term(dependency.with_constraint(constraint), is_positive)
 
     def __str__(self) -> str:
         prefix = "not " if not self.is_positive() else ""
diff --git a/tests/puzzle/test_solver.py b/tests/puzzle/test_solver.py
index fe47e8bd220..2ca281be0e6 100644
--- a/tests/puzzle/test_solver.py
+++ b/tests/puzzle/test_solver.py
@@ -22,6 +22,7 @@
 from poetry.repositories.pool import Pool
 from poetry.repositories.repository import Repository
 from poetry.utils.env import MockEnv
+from tests.compat import is_poetry_core_1_1_0a7_compat
 from tests.helpers import get_dependency
 from tests.helpers import get_package
 from tests.repositories.test_legacy_repository import (
@@ -1383,7 +1384,10 @@ def test_solver_duplicate_dependencies_different_sources_types_are_preserved(
 
     assert len(complete_package.all_requires) == 2
 
-    pypi, git = complete_package.all_requires
+    if is_poetry_core_1_1_0a7_compat:
+        pypi, git = complete_package.all_requires
+    else:
+        git, pypi = complete_package.all_requires
 
     assert isinstance(pypi, Dependency)
     assert pypi == dependency_pypi

From 95e167ef322cd1bc1c9305e1a01e43cd223ab281 Mon Sep 17 00:00:00 2001
From: Arun Babu Neelicattu <arun.neelicattu@gmail.com>
Date: Sun, 22 May 2022 01:00:35 +0200
Subject: [PATCH 2/2] Update src/poetry/mixology/term.py

---
 src/poetry/mixology/term.py | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/src/poetry/mixology/term.py b/src/poetry/mixology/term.py
index b208c2635ca..d19a190024d 100644
--- a/src/poetry/mixology/term.py
+++ b/src/poetry/mixology/term.py
@@ -166,10 +166,6 @@ def _compatible_dependency(self, other: Dependency) -> bool:
                 self.dependency.complete_name == other.complete_name
                 and self._is_direct_origin(self.dependency)
                 != self._is_direct_origin(other)
-                and (
-                    self.dependency.constraint.allows_all(other.constraint)
-                    or other.constraint.allows_all(self.dependency.constraint)
-                )
             )
         )