Skip to content

Commit

Permalink
Merge pull request #3606 from fable-compiler/fix/record_equality
Browse files Browse the repository at this point in the history
  • Loading branch information
MangelMaxime authored Nov 22, 2023
2 parents f73d6a9 + e811e82 commit 43f34f9
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/Fable.Cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Fixed char to string type regression with binary operator (by @dbrattli)
* Fix `DateTime(..., DateTimeKind.Local).ToString("O")` (by @MangelMaxime)
* Fix calling `value.ToString(CultureInfo.InvariantCulture)` (by @MangelMaxime)
* Fix #3605: Fix record equality comparison to works with optional fields (by @MangelMaxime & @dbrattli)

## 4.5.0 - 2023-11-07

Expand Down
29 changes: 21 additions & 8 deletions src/fable-library-py/fable_library/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,19 +118,32 @@ def record_compare_to(self: Record, other: Record) -> int:
if self is other:
return 0

elif hasattr(self, "__dict__") and self.__dict__:
for name in self.__dict__.keys():
if self.__dict__[name] < other.__dict__.get(name):
def compare_values(self_value: Any, other_value: Any) -> int:
match (self_value, other_value):
case (None, None):
return 0
case (None, _):
return -1
case (_, None):
return 1
case (self_value, other_value) if self_value < other_value:
return -1
elif self.__dict__[name] > other.__dict__.get(name):
case (self_value, other_value) if self_value > other_value:
return 1
case _:
return 0

if hasattr(self, "__dict__") and self.__dict__:
for name in self.__dict__.keys():
result = compare_values(self.__dict__[name], other.__dict__[name])
if result != 0:
return result

elif hasattr(self, "__slots__") and self.__slots__:
for name in self.__slots__:
if getattr(self, name) < getattr(other, name):
return -1
elif getattr(self, name) > getattr(other, name):
return 1
result = compare_values(getattr(self, name), getattr(other, name))
if result != 0:
return result

return 0

Expand Down
14 changes: 14 additions & 0 deletions tests/Python/TestRecordType.fs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ type Time =
type CarInterior = { Seats: int }
type Car = { Interior: CarInterior }

type RecordA =
{ OptionalField : string option }

[<Fact>]
let ``test Anonymous records work`` () =
let r = makeAnonRec()
Expand Down Expand Up @@ -144,3 +147,14 @@ let ``test Nested record field copy and update works for anonymous records`` =
let car2 =
{| car with Interior.Seats = 5 |}
equal 5 car2.Interior.Seats

[<Fact>]
let ``test Record equality when it has optional field`` =
let a = { OptionalField = None }
let b = { OptionalField = None }
let c = { OptionalField = Some "test" }

equal a b
equal true (a = b)
equal false (a = c)
equal false (c = b)

0 comments on commit 43f34f9

Please sign in to comment.