@@ -2,7 +2,7 @@ use std::cmp::Ordering;
2
2
use std:: fmt:: { self , Display , Formatter } ;
3
3
use std:: ops:: { Bound , Deref } ;
4
4
use std:: str:: FromStr ;
5
-
5
+ use std :: sync :: LazyLock ;
6
6
use itertools:: Itertools ;
7
7
use serde:: { de, Deserialize , Deserializer , Serialize , Serializer } ;
8
8
use uv_normalize:: ExtraName ;
@@ -16,9 +16,7 @@ use crate::marker::lowering::{
16
16
LoweredMarkerValueExtra , LoweredMarkerValueString , LoweredMarkerValueVersion ,
17
17
} ;
18
18
use crate :: marker:: parse;
19
- use crate :: {
20
- MarkerEnvironment , Pep508Error , Pep508ErrorSource , Pep508Url , Reporter , TracingReporter ,
21
- } ;
19
+ use crate :: { MarkerEnvironment , Pep508Error , Pep508ErrorSource , Pep508Url , Reporter , TracingReporter , VerbatimUrl } ;
22
20
23
21
/// Ways in which marker evaluation can fail
24
22
#[ derive( Copy , Clone , Debug , Eq , Hash , PartialEq , PartialOrd , Ord ) ]
@@ -685,6 +683,150 @@ impl MarkerTree {
685
683
self . 0 . is_false ( )
686
684
}
687
685
686
+ /// Whether the marker is known to be unsatisfiable.
687
+ ///
688
+ /// For example, while the marker specification and grammar do not _forbid_ it, we know that
689
+ /// both `sys_platform == 'win32'` and `platform_system == 'Darwin'` will never true at the
690
+ /// same time.
691
+ ///
692
+ /// This method thus encodes assumptions about the environment that are not guaranteed by the
693
+ /// PEP 508 specification alone.
694
+ pub fn is_conflicting ( & self ) -> bool {
695
+ static MUTUAL_EXCLUSIONS : LazyLock < MarkerTree > = LazyLock :: new ( || {
696
+ let mut tree = MarkerTree :: FALSE ;
697
+ for ( a, b) in [
698
+ // sys_platform == 'darwin' and platform_system == 'Windows'
699
+ ( MarkerExpression :: String {
700
+ key : MarkerValueString :: SysPlatform ,
701
+ operator : MarkerOperator :: Equal ,
702
+ value : "darwin" . to_string ( ) ,
703
+ } , MarkerExpression :: String {
704
+ key : MarkerValueString :: PlatformSystem ,
705
+ operator : MarkerOperator :: Equal ,
706
+ value : "Windows" . to_string ( ) ,
707
+ } ) ,
708
+ // sys_platform == 'darwin' and platform_system == 'Linux'
709
+ ( MarkerExpression :: String {
710
+ key : MarkerValueString :: SysPlatform ,
711
+ operator : MarkerOperator :: Equal ,
712
+ value : "darwin" . to_string ( ) ,
713
+ } , MarkerExpression :: String {
714
+ key : MarkerValueString :: PlatformSystem ,
715
+ operator : MarkerOperator :: Equal ,
716
+ value : "Linux" . to_string ( ) ,
717
+ } ) ,
718
+ // sys_platform == 'win32' and platform_system == 'Darwin'
719
+ ( MarkerExpression :: String {
720
+ key : MarkerValueString :: SysPlatform ,
721
+ operator : MarkerOperator :: Equal ,
722
+ value : "win32" . to_string ( ) ,
723
+ } , MarkerExpression :: String {
724
+ key : MarkerValueString :: PlatformSystem ,
725
+ operator : MarkerOperator :: Equal ,
726
+ value : "Darwin" . to_string ( ) ,
727
+ } ) ,
728
+ // sys_platform == 'win32' and platform_system == 'Linux'
729
+ ( MarkerExpression :: String {
730
+ key : MarkerValueString :: SysPlatform ,
731
+ operator : MarkerOperator :: Equal ,
732
+ value : "win32" . to_string ( ) ,
733
+ } , MarkerExpression :: String {
734
+ key : MarkerValueString :: PlatformSystem ,
735
+ operator : MarkerOperator :: Equal ,
736
+ value : "Linux" . to_string ( ) ,
737
+ } ) ,
738
+ // sys_platform == 'linux' and platform_system == 'Darwin'
739
+ ( MarkerExpression :: String {
740
+ key : MarkerValueString :: SysPlatform ,
741
+ operator : MarkerOperator :: Equal ,
742
+ value : "linux" . to_string ( ) ,
743
+ } , MarkerExpression :: String {
744
+ key : MarkerValueString :: PlatformSystem ,
745
+ operator : MarkerOperator :: Equal ,
746
+ value : "Darwin" . to_string ( ) ,
747
+ } ) ,
748
+ // sys_platform == 'linux' and platform_system == 'Windows'
749
+ ( MarkerExpression :: String {
750
+ key : MarkerValueString :: SysPlatform ,
751
+ operator : MarkerOperator :: Equal ,
752
+ value : "linux" . to_string ( ) ,
753
+ } , MarkerExpression :: String {
754
+ key : MarkerValueString :: PlatformSystem ,
755
+ operator : MarkerOperator :: Equal ,
756
+ value : "Windows" . to_string ( ) ,
757
+ } ) ,
758
+ // os_name == 'nt' and sys_platform == 'darwin'
759
+ ( MarkerExpression :: String {
760
+ key : MarkerValueString :: OsName ,
761
+ operator : MarkerOperator :: Equal ,
762
+ value : "nt" . to_string ( ) ,
763
+ } , MarkerExpression :: String {
764
+ key : MarkerValueString :: SysPlatform ,
765
+ operator : MarkerOperator :: Equal ,
766
+ value : "darwin" . to_string ( ) ,
767
+ } ) ,
768
+ // os_name == 'nt' and sys_platform == 'linux'
769
+ ( MarkerExpression :: String {
770
+ key : MarkerValueString :: OsName ,
771
+ operator : MarkerOperator :: Equal ,
772
+ value : "nt" . to_string ( ) ,
773
+ } , MarkerExpression :: String {
774
+ key : MarkerValueString :: SysPlatform ,
775
+ operator : MarkerOperator :: Equal ,
776
+ value : "linux" . to_string ( ) ,
777
+ } ) ,
778
+ // os_name == 'posix' and sys_platform == 'win32'
779
+ ( MarkerExpression :: String {
780
+ key : MarkerValueString :: OsName ,
781
+ operator : MarkerOperator :: Equal ,
782
+ value : "posix" . to_string ( ) ,
783
+ } , MarkerExpression :: String {
784
+ key : MarkerValueString :: SysPlatform ,
785
+ operator : MarkerOperator :: Equal ,
786
+ value : "win32" . to_string ( ) ,
787
+ } ) ,
788
+ // os_name == 'nt' and platform_system == 'Darwin'
789
+ ( MarkerExpression :: String {
790
+ key : MarkerValueString :: OsName ,
791
+ operator : MarkerOperator :: Equal ,
792
+ value : "nt" . to_string ( ) ,
793
+ } , MarkerExpression :: String {
794
+ key : MarkerValueString :: PlatformSystem ,
795
+ operator : MarkerOperator :: Equal ,
796
+ value : "Darwin" . to_string ( ) ,
797
+ } ) ,
798
+ // os_name == 'nt' and platform_system == 'Linux'
799
+ ( MarkerExpression :: String {
800
+ key : MarkerValueString :: OsName ,
801
+ operator : MarkerOperator :: Equal ,
802
+ value : "nt" . to_string ( ) ,
803
+ } , MarkerExpression :: String {
804
+ key : MarkerValueString :: PlatformSystem ,
805
+ operator : MarkerOperator :: Equal ,
806
+ value : "Linux" . to_string ( ) ,
807
+ } ) ,
808
+ // os_name == 'posix' and platform_system == 'Windows'
809
+ ( MarkerExpression :: String {
810
+ key : MarkerValueString :: OsName ,
811
+ operator : MarkerOperator :: Equal ,
812
+ value : "posix" . to_string ( ) ,
813
+ } , MarkerExpression :: String {
814
+ key : MarkerValueString :: PlatformSystem ,
815
+ operator : MarkerOperator :: Equal ,
816
+ value : "Windows" . to_string ( ) ,
817
+ } ) ,
818
+ ] {
819
+ let mut a = MarkerTree :: expression ( a) ;
820
+ let b = MarkerTree :: expression ( b) ;
821
+ a. and ( b) ;
822
+ tree. or ( a) ;
823
+ }
824
+ tree. negate ( )
825
+ } ) ;
826
+
827
+ self . is_disjoint ( & MUTUAL_EXCLUSIONS )
828
+ }
829
+
688
830
/// Returns a new marker tree that is the negation of this one.
689
831
#[ must_use]
690
832
pub fn negate ( & self ) -> MarkerTree {
@@ -727,6 +869,7 @@ impl MarkerTree {
727
869
INTERNER . lock ( ) . is_disjoint ( self . 0 , other. 0 )
728
870
}
729
871
872
+
730
873
/// Returns the contents of this marker tree, if it contains at least one expression.
731
874
///
732
875
/// If the marker is `true`, this method will return `None`.
0 commit comments