@@ -723,9 +723,21 @@ def union_simplify(self, other: BaseMarker) -> BaseMarker | None:
723
723
- union between two multimarkers where there are some common markers
724
724
and the union of unique markers is a single marker
725
725
"""
726
+ from poetry .core .packages .utils .utils import get_python_constraint_from_marker
727
+
726
728
if other in self ._markers :
727
729
return other
728
730
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
+
729
741
if isinstance (other , MultiMarker ):
730
742
our_markers = set (self .markers )
731
743
their_markers = set (other .markers )
@@ -746,7 +758,13 @@ def union_simplify(self, other: BaseMarker) -> BaseMarker | None:
746
758
unique_union = MultiMarker (* unique_markers ).union (
747
759
MultiMarker (* other_unique_markers )
748
760
)
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
+ ):
750
768
common_markers = [
751
769
marker for marker in self .markers if marker in shared_markers
752
770
]
@@ -856,12 +874,19 @@ def of(cls, *markers: BaseMarker) -> BaseMarker:
856
874
857
875
# If we have a SingleMarker then with any luck after union it'll
858
876
# 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"'.
859
881
if not is_one_multi and isinstance (mark , SingleMarkerLike ):
860
882
new_marker = mark .union (marker )
861
883
if new_marker .is_any ():
862
884
return AnyMarker ()
863
885
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
+ ):
865
890
new_markers [i ] = new_marker
866
891
included = True
867
892
break
@@ -903,9 +928,21 @@ def intersect_simplify(self, other: BaseMarker) -> BaseMarker | None:
903
928
- intersection between two markerunions where there are some common markers
904
929
and the intersection of unique markers is not a single marker
905
930
"""
931
+ from poetry .core .packages .utils .utils import get_python_constraint_from_marker
932
+
906
933
if other in self ._markers :
907
934
return other
908
935
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
+
909
946
if isinstance (other , MarkerUnion ):
910
947
our_markers = set (self .markers )
911
948
their_markers = set (other .markers )
@@ -926,7 +963,14 @@ def intersect_simplify(self, other: BaseMarker) -> BaseMarker | None:
926
963
unique_intersection = MarkerUnion (* unique_markers ).intersect (
927
964
MarkerUnion (* other_unique_markers )
928
965
)
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
+ ):
930
974
common_markers = [
931
975
marker for marker in self .markers if marker in shared_markers
932
976
]
@@ -1247,16 +1291,38 @@ def _merge_single_markers(
1247
1291
result_marker = EmptyMarker ()
1248
1292
1249
1293
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".
1253
1294
result_constraint = get_python_constraint_from_marker (marker1 ).union (
1254
1295
get_python_constraint_from_marker (marker2 )
1255
1296
)
1256
1297
if result_constraint .is_any ():
1298
+ # Convert 'python_version <= "3.8" or python_version >= "3.9"' to "any".
1257
1299
result_marker = AnyMarker ()
1258
1300
elif result_constraint .is_simple ():
1301
+ # Convert 'python_version == "3.8" or python_version >= "3.9"'
1302
+ # to 'python_version >= "3.8"'.
1259
1303
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
+ )
1260
1326
1261
1327
return result_marker
1262
1328
0 commit comments