@@ -723,9 +723,21 @@ def union_simplify(self, other: BaseMarker) -> BaseMarker | None:
723723 - union between two multimarkers where there are some common markers
724724 and the union of unique markers is a single marker
725725 """
726+ from poetry .core .packages .utils .utils import get_python_constraint_from_marker
727+
726728 if other in self ._markers :
727729 return other
728730
731+ if isinstance (other , SingleMarker ) and other .name in PYTHON_VERSION_MARKERS :
732+ # Convert 'python_version >= "3.8" and sys_platform == "linux" or python_version > "3.6"'
733+ # to 'python_version > "3.6"'
734+ for m in self ._markers :
735+ if isinstance (m , SingleMarker ) and m .name in PYTHON_VERSION_MARKERS :
736+ constraint = get_python_constraint_from_marker (m )
737+ other_constraint = get_python_constraint_from_marker (other )
738+ if other_constraint .allows_all (constraint ):
739+ return other
740+
729741 if isinstance (other , MultiMarker ):
730742 our_markers = set (self .markers )
731743 their_markers = set (other .markers )
@@ -746,7 +758,13 @@ def union_simplify(self, other: BaseMarker) -> BaseMarker | None:
746758 unique_union = MultiMarker (* unique_markers ).union (
747759 MultiMarker (* other_unique_markers )
748760 )
749- if isinstance (unique_union , (SingleMarkerLike , AnyMarker )):
761+ if isinstance (unique_union , (SingleMarkerLike , AnyMarker )) or (
762+ # Convert 'python_version >= "3.8" and python_version < "3.10"
763+ # or python_version >= "3.10" and python_version < "3.12"'
764+ # to 'python_version >= "3.6" and python_version < "3.12"'
765+ isinstance (unique_union , MultiMarker )
766+ and unique_union .complexity <= (2 , 2 )
767+ ):
750768 common_markers = [
751769 marker for marker in self .markers if marker in shared_markers
752770 ]
@@ -856,12 +874,19 @@ def of(cls, *markers: BaseMarker) -> BaseMarker:
856874
857875 # If we have a SingleMarker then with any luck after union it'll
858876 # become another SingleMarker.
877+ # Especially, for `python_version` markers a multi marker is also
878+ # an improvement. E.g. the union of 'python_version == "3.6"' and
879+ # 'python_version == "3.7" or python_version == "3.8"' is
880+ # 'python_version >= "3.6" and python_version < "3.9"'.
859881 if not is_one_multi and isinstance (mark , SingleMarkerLike ):
860882 new_marker = mark .union (marker )
861883 if new_marker .is_any ():
862884 return AnyMarker ()
863885
864- if isinstance (new_marker , SingleMarkerLike ):
886+ if isinstance (new_marker , SingleMarkerLike ) or (
887+ isinstance (new_marker , MultiMarker )
888+ and new_marker .complexity <= (2 , 2 )
889+ ):
865890 new_markers [i ] = new_marker
866891 included = True
867892 break
@@ -903,9 +928,21 @@ def intersect_simplify(self, other: BaseMarker) -> BaseMarker | None:
903928 - intersection between two markerunions where there are some common markers
904929 and the intersection of unique markers is not a single marker
905930 """
931+ from poetry .core .packages .utils .utils import get_python_constraint_from_marker
932+
906933 if other in self ._markers :
907934 return other
908935
936+ if isinstance (other , SingleMarker ) and other .name in PYTHON_VERSION_MARKERS :
937+ # Convert '(python_version >= "3.6" or sys_platform == "linux") and python_version > "3.8"'
938+ # to 'python_version > "3.8"'
939+ for m in self ._markers :
940+ if isinstance (m , SingleMarker ) and m .name in PYTHON_VERSION_MARKERS :
941+ constraint = get_python_constraint_from_marker (m )
942+ other_constraint = get_python_constraint_from_marker (other )
943+ if constraint .allows_all (other_constraint ):
944+ return other
945+
909946 if isinstance (other , MarkerUnion ):
910947 our_markers = set (self .markers )
911948 their_markers = set (other .markers )
@@ -926,7 +963,14 @@ def intersect_simplify(self, other: BaseMarker) -> BaseMarker | None:
926963 unique_intersection = MarkerUnion (* unique_markers ).intersect (
927964 MarkerUnion (* other_unique_markers )
928965 )
929- if isinstance (unique_intersection , (SingleMarkerLike , EmptyMarker )):
966+ if isinstance (unique_intersection , (SingleMarkerLike , EmptyMarker )) or (
967+ # Convert '(python_version == "3.6" or python_version >= "3.8)"
968+ # and (python_version >= "3.6" and python_version < "3.8"
969+ # or python_version == "3.9")'
970+ # to 'python_version == "3.6" or python_version == "3.9"'
971+ isinstance (unique_intersection , MarkerUnion )
972+ and unique_intersection .complexity <= (2 , 2 )
973+ ):
930974 common_markers = [
931975 marker for marker in self .markers if marker in shared_markers
932976 ]
@@ -1247,16 +1291,38 @@ def _merge_single_markers(
12471291 result_marker = EmptyMarker ()
12481292
12491293 elif isinstance (result_constraint , VersionUnion ) and merge_class == MarkerUnion :
1250- # Convert 'python_version == "3.8" or python_version >= "3.9"'
1251- # to 'python_version >= "3.8"'.
1252- # Convert 'python_version <= "3.8" or python_version >= "3.9"' to "any".
12531294 result_constraint = get_python_constraint_from_marker (marker1 ).union (
12541295 get_python_constraint_from_marker (marker2 )
12551296 )
12561297 if result_constraint .is_any ():
1298+ # Convert 'python_version <= "3.8" or python_version >= "3.9"' to "any".
12571299 result_marker = AnyMarker ()
12581300 elif result_constraint .is_simple ():
1301+ # Convert 'python_version == "3.8" or python_version >= "3.9"'
1302+ # to 'python_version >= "3.8"'.
12591303 result_marker = SingleMarker (marker1 .name , result_constraint )
1304+ elif isinstance (result_constraint , VersionRange ):
1305+ # Convert 'python_version' == "3.8" or python_version == "3.9"'
1306+ # to 'python_version >= "3.8" and python_version < "3.10"'.
1307+ # Although both markers have the same complexity, the latter behaves
1308+ # better if it is merged with 'python_version == "3.10' in a next step
1309+ # for example.
1310+ result_marker = MultiMarker (
1311+ SingleMarker (
1312+ marker1 .name ,
1313+ VersionRange (
1314+ min = result_constraint .min ,
1315+ include_min = result_constraint .include_min ,
1316+ ),
1317+ ),
1318+ SingleMarker (
1319+ marker1 .name ,
1320+ VersionRange (
1321+ max = result_constraint .max ,
1322+ include_max = result_constraint .include_max ,
1323+ ),
1324+ ),
1325+ )
12601326
12611327 return result_marker
12621328
0 commit comments