@@ -273,6 +273,20 @@ impl InternerGuard<'_> {
273
273
value,
274
274
} => {
275
275
// Normalize `platform_system` markers to `sys_platform` nodes.
276
+ //
277
+ // The `platform` module is "primarily intended for diagnostic information to be
278
+ // read by humans."
279
+ //
280
+ // We only normalize when we can confidently guarantee that the values are
281
+ // exactly equivalent. For example, we normalize `platform_system == 'Windows'`
282
+ // to `sys_platform == 'win32'`, but we do not normalize `platform_system == 'FreeBSD'`
283
+ // to `sys_platform == 'freebsd'`, since FreeBSD typically includes a major version
284
+ // in its `sys.platform` output.
285
+ //
286
+ // For cases that aren't normalized, we do our best to encode known-incompatible
287
+ // values in `exclusions`.
288
+ //
289
+ // See: https://discuss.python.org/t/clarify-usage-of-platform-system/70900
276
290
let ( key, value) = match ( key, value. as_str ( ) ) {
277
291
( MarkerValueString :: PlatformSystem , "Windows" ) => {
278
292
( CanonicalMarkerValueString :: SysPlatform , "win32" . to_string ( ) )
@@ -284,36 +298,18 @@ impl InternerGuard<'_> {
284
298
( MarkerValueString :: PlatformSystem , "Linux" ) => {
285
299
( CanonicalMarkerValueString :: SysPlatform , "linux" . to_string ( ) )
286
300
}
287
- ( MarkerValueString :: PlatformSystem , "Java" ) => {
288
- ( CanonicalMarkerValueString :: SysPlatform , "java" . to_string ( ) )
289
- }
290
301
( MarkerValueString :: PlatformSystem , "AIX" ) => {
291
302
( CanonicalMarkerValueString :: SysPlatform , "aix" . to_string ( ) )
292
303
}
293
- ( MarkerValueString :: PlatformSystem , "FreeBSD" ) => (
294
- CanonicalMarkerValueString :: SysPlatform ,
295
- "freebsd" . to_string ( ) ,
296
- ) ,
297
- ( MarkerValueString :: PlatformSystem , "NetBSD" ) => (
298
- CanonicalMarkerValueString :: SysPlatform ,
299
- "netbsd" . to_string ( ) ,
300
- ) ,
301
- ( MarkerValueString :: PlatformSystem , "OpenBSD" ) => (
304
+ ( MarkerValueString :: PlatformSystem , "Emscripten" ) => (
302
305
CanonicalMarkerValueString :: SysPlatform ,
303
- "openbsd " . to_string ( ) ,
306
+ "emscripten " . to_string ( ) ,
304
307
) ,
305
- ( MarkerValueString :: PlatformSystem , "SunOS" ) => {
306
- ( CanonicalMarkerValueString :: SysPlatform , "sunos" . to_string ( ) )
307
- }
308
308
// See: https://peps.python.org/pep-0738/#sys
309
309
( MarkerValueString :: PlatformSystem , "Android" ) => (
310
310
CanonicalMarkerValueString :: SysPlatform ,
311
311
"android" . to_string ( ) ,
312
312
) ,
313
- // See: https://peps.python.org/pep-0730/#sys
314
- ( MarkerValueString :: PlatformSystem , "iOS" ) => {
315
- ( CanonicalMarkerValueString :: SysPlatform , "ios" . to_string ( ) )
316
- }
317
313
_ => ( key. into ( ) , value) ,
318
314
} ;
319
315
( Variable :: String ( key) , Edges :: from_string ( operator, value) )
@@ -864,8 +860,23 @@ impl InternerGuard<'_> {
864
860
return exclusions;
865
861
}
866
862
let mut tree = NodeId :: FALSE ;
867
- for ( a, b) in [
868
- // os_name == 'nt' and sys_platform == 'darwin'
863
+
864
+ // Pairs of `os_name` and `sys_platform` that are known to be incompatible.
865
+ //
866
+ // For example: `os_name == 'nt' and sys_platform == 'darwin'`
867
+ let mut pairs = vec ! [
868
+ (
869
+ MarkerExpression :: String {
870
+ key: MarkerValueString :: OsName ,
871
+ operator: MarkerOperator :: Equal ,
872
+ value: "nt" . to_string( ) ,
873
+ } ,
874
+ MarkerExpression :: String {
875
+ key: MarkerValueString :: SysPlatform ,
876
+ operator: MarkerOperator :: Equal ,
877
+ value: "linux" . to_string( ) ,
878
+ } ,
879
+ ) ,
869
880
(
870
881
MarkerExpression :: String {
871
882
key: MarkerValueString :: OsName ,
@@ -878,7 +889,6 @@ impl InternerGuard<'_> {
878
889
value: "darwin" . to_string( ) ,
879
890
} ,
880
891
) ,
881
- // os_name == 'nt' and sys_platform == 'linux'
882
892
(
883
893
MarkerExpression :: String {
884
894
key: MarkerValueString :: OsName ,
@@ -888,10 +898,9 @@ impl InternerGuard<'_> {
888
898
MarkerExpression :: String {
889
899
key: MarkerValueString :: SysPlatform ,
890
900
operator: MarkerOperator :: Equal ,
891
- value : "linux " . to_string ( ) ,
901
+ value: "ios " . to_string( ) ,
892
902
} ,
893
903
) ,
894
- // os_name == 'posix' and sys_platform == 'win32'
895
904
(
896
905
MarkerExpression :: String {
897
906
key: MarkerValueString :: OsName ,
@@ -904,7 +913,55 @@ impl InternerGuard<'_> {
904
913
value: "win32" . to_string( ) ,
905
914
} ,
906
915
) ,
907
- ] {
916
+ ] ;
917
+
918
+ // Pairs of `platform_system` and `sys_platform` that are known to be incompatible.
919
+ //
920
+ // For example: `platform_system == 'FreeBSD' and sys_platform == 'darwin'`
921
+ //
922
+ // Any `platform_system` values that we normalize away (like `Windows` to `win32`) are
923
+ // omitted, since we never expect them to be present in the tree.
924
+ //
925
+ // Unfortunately, we can't include Cygwin here, since Cygwin appears to use a
926
+ // `platform_system` value with versions encoded (e.g., `CYGWIN_NT-10.0-22631).
927
+ //
928
+ for platform_system in [ "FreeBSD" , "NetBSD" , "OpenBSD" , "SunOS" , "iOS" , "iPadOS" ] {
929
+ // An enumeration of known values, excluding FreeBSD, SunOS, and other Unix systems,
930
+ // which use the lowercased `uname -s`, which typically includes a version (e.g.,
931
+ // `freebsd8`).
932
+ //
933
+ // See: https://docs.python.org/3/library/sys.html#sys.platform
934
+ for sys_platform in [
935
+ "aix" ,
936
+ "android" ,
937
+ "emscripten" ,
938
+ "ios" ,
939
+ "linux" ,
940
+ "darwin" ,
941
+ "win32" ,
942
+ "cygwin" ,
943
+ "wasi" ,
944
+ ] {
945
+ // Some of the above pairs are actually compatible.
946
+ if matches ! ( ( platform_system, sys_platform) , ( "iOS" | "iPadOS" , "ios" ) ) {
947
+ continue ;
948
+ }
949
+ pairs. push ( (
950
+ MarkerExpression :: String {
951
+ key : MarkerValueString :: PlatformSystem ,
952
+ operator : MarkerOperator :: Equal ,
953
+ value : platform_system. to_string ( ) ,
954
+ } ,
955
+ MarkerExpression :: String {
956
+ key : MarkerValueString :: SysPlatform ,
957
+ operator : MarkerOperator :: Equal ,
958
+ value : sys_platform. to_string ( ) ,
959
+ } ,
960
+ ) ) ;
961
+ }
962
+ }
963
+
964
+ for ( a, b) in pairs {
908
965
let a = self . expression ( a) ;
909
966
let b = self . expression ( b) ;
910
967
let a_and_b = conjunction ( self , a, b) ;
0 commit comments