From 51e08426ce34103253349cb07d4562f2aa2c3002 Mon Sep 17 00:00:00 2001 From: Maxime Mangel Date: Tue, 28 Nov 2023 14:36:34 +0100 Subject: [PATCH 1/2] Fix comparaison between optional list when one is None Fix #3617 --- src/Fable.Cli/CHANGELOG.md | 6 ++ src/fable-library-py/fable_library/util.py | 12 +++ tests/Python/TestComparison.fs | 107 +++++++++++++++++++++ 3 files changed, 125 insertions(+) diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md index 8803e07ca4..0c22937797 100644 --- a/src/Fable.Cli/CHANGELOG.md +++ b/src/Fable.Cli/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Fixed + +#### Python + +* Fix #3617: Fix comparaison between list option when one is None + ## 4.6.0 - 2023-11-27 ### Changed diff --git a/src/fable-library-py/fable_library/util.py b/src/fable-library-py/fable_library/util.py index 1d465d139c..45cc9775bb 100644 --- a/src/fable-library-py/fable_library/util.py +++ b/src/fable-library-py/fable_library/util.py @@ -220,6 +220,18 @@ def equals(a: Any, b: Any) -> bool: if a is b: return True + # Check for NoneTypes (ex Some [1] = None) + match (a, b): + # Don't test (None, None) here, because a is b already covers that + # case (None, None): + # return True + case (None, _): + return False + case (_, None): + return False + case (_, _): + pass + if is_array_like(a): return equal_arrays(a, b) diff --git a/tests/Python/TestComparison.fs b/tests/Python/TestComparison.fs index 202c08ec4f..a26e24c476 100644 --- a/tests/Python/TestComparison.fs +++ b/tests/Python/TestComparison.fs @@ -81,6 +81,24 @@ let ``test Typed array equality works`` () = equal false (xs1 <> xs2) equal true (xs1 <> xs4) +[] +let ``test Typed array option equality works`` () = + let xs1 = Some [| 1; 2; 3 |] + let xs2 = Some [| 1; 2; 3 |] + let xs3 = Some [| 1; 2; 4 |] + let xs4 = Some [| 1; 2 |] + let xs5 = None + equal true (xs1 = xs2) + equal false (xs1 = xs3) + equal true (xs1 <> xs3) + equal false (xs1 <> xs2) + equal false (xs1 = xs4) + equal true (xs1 <> xs4) + equal false (xs1 = xs5) + equal true (xs1 <> xs5) + equal true (xs5 = None) + equal false (xs5 <> None) + [] let ``test Array equality works`` () = let xs1 = [| "1"; "2"; "3" |] @@ -93,6 +111,24 @@ let ``test Array equality works`` () = equal false (xs1 <> xs2) equal true (xs1 <> xs4) +[] +let ``test Array option equality works`` () = + let xs1 = Some [| "1"; "2"; "3" |] + let xs2 = Some [| "1"; "2"; "3" |] + let xs3 = Some [| "1"; "2"; "4" |] + let xs4 = Some [| "1"; "2" |] + let xs5 = None + equal true (xs1 = xs2) + equal false (xs1 = xs3) + equal true (xs1 <> xs3) + equal false (xs1 <> xs2) + equal false (xs1 = xs4) + equal true (xs1 <> xs4) + equal false (xs1 = xs5) + equal true (xs1 <> xs5) + equal true (xs5 = None) + equal false (xs5 <> None) + [] let ``test Tuple equality works`` () = let xs1 = ( 1, 2, 3 ) @@ -103,6 +139,21 @@ let ``test Tuple equality works`` () = equal true (xs1 <> xs3) equal false (xs1 <> xs2) +[] +let ``test Tuple option equality works``() = + let xs1 = Some ( 1, 2, 3 ) + let xs2 = Some ( 1, 2, 3 ) + let xs3 = Some ( 1, 2, 4 ) + let xs5 = None + equal true (xs1 = xs2) + equal false (xs1 = xs3) + equal true (xs1 <> xs3) + equal false (xs1 <> xs2) + equal false (xs1 = xs5) + equal true (xs1 <> xs5) + equal true (xs5 = None) + equal false (xs5 <> None) + [] let ``test List equality works`` () = let xs1 = [ 1; 2; 3 ] @@ -113,6 +164,24 @@ let ``test List equality works`` () = equal true (xs1 <> xs3) equal false (xs1 <> xs2) +[] +let ``test List option equality works``() = + let xs1 = Some [ 1; 2; 3 ] + let xs2 = Some [ 1; 2; 3 ] + let xs3 = Some [ 1; 2; 4 ] + let xs4 = Some [ 1; 2; 3; 1 ] + let xs5 = None + equal true (xs1 = xs2) + equal false (xs1 = xs3) + equal true (xs1 <> xs3) + equal false (xs1 <> xs2) + equal false (xs1 = xs4) + equal true (xs1 <> xs4) + equal false (xs1 = xs5) + equal true (xs1 <> xs5) + equal true (xs5 = None) + equal false (xs5 <> None) + [] let ``test Set equality works`` () = let xs1 = Set [ 1; 2; 3 ] @@ -127,6 +196,25 @@ let ``test Set equality works`` () = equal true (xs1 = xs4) equal false (xs1 <> xs5) +[] +let ``test Set option equality works`` () = + let xs1 = Some (Set [ 1; 2; 3 ]) + let xs2 = Some (Set [ 1; 2; 3 ]) + let xs3 = Some (Set [ 1; 2; 4 ]) + let xs4 = Some (Set [ 3; 2; 1 ]) + let xs5 = Some (Set [ 1; 2; 3; 1 ]) + let xs6 = None + equal true (xs1 = xs2) + equal false (xs1 = xs3) + equal true (xs1 <> xs3) + equal false (xs1 <> xs2) + equal true (xs1 = xs4) + equal false (xs1 <> xs5) + equal false (xs1 = xs6) + equal true (xs1 <> xs6) + equal true (xs6 = None) + equal false (xs6 <> None) + [] let ``test Map equality works`` () = let xs1 = Map [ ("a", 1); ("b", 2); ("c", 3) ] @@ -139,6 +227,25 @@ let ``test Map equality works`` () = equal false (xs1 <> xs2) equal true (xs1 = xs4) +[] +let ``test Map option equality works`` () = + let xs1 = Some (Map [ ("a", 1); ("b", 2); ("c", 3) ]) + let xs2 = Some (Map [ ("a", 1); ("b", 2); ("c", 3) ]) + let xs3 = Some (Map [ ("a", 1); ("b", 2); ("c", 4) ]) + let xs4 = Some (Map [ ("c", 3); ("b", 2); ("a", 1) ]) + let xs5 = Some (Map [ ("a", 1); ("b", 2); ("c", 3); ("d", 1) ]) + let xs6 = None + equal true (xs1 = xs2) + equal false (xs1 = xs3) + equal true (xs1 <> xs3) + equal false (xs1 <> xs2) + equal true (xs1 = xs4) + equal true (xs1 <> xs5) + equal false (xs1 = xs6) + equal true (xs1 <> xs6) + equal true (xs6 = None) + equal false (xs6 <> None) + [] let ``test Union equality works`` () = let u1 = A 2 From b00beae561deeba3fb8dd7e214c17e404c10a703 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Tue, 28 Nov 2023 15:44:04 +0100 Subject: [PATCH 2/2] Move all logic inside match statement --- src/fable-library-py/fable_library/util.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/fable-library-py/fable_library/util.py b/src/fable-library-py/fable_library/util.py index 45cc9775bb..2fd2be0d3b 100644 --- a/src/fable-library-py/fable_library/util.py +++ b/src/fable-library-py/fable_library/util.py @@ -217,11 +217,9 @@ class DateKind(IntEnum): def equals(a: Any, b: Any) -> bool: - if a is b: - return True - - # Check for NoneTypes (ex Some [1] = None) match (a, b): + case (a, b) if a is b: + return True # Don't test (None, None) here, because a is b already covers that # case (None, None): # return True @@ -229,13 +227,10 @@ def equals(a: Any, b: Any) -> bool: return False case (_, None): return False - case (_, _): - pass - - if is_array_like(a): - return equal_arrays(a, b) - - return a == b + case (a, b) if is_array_like(a): + return equal_arrays(a, b) + case _: + return a == b def is_comparable(x: Any) -> bool: