Skip to content

Commit

Permalink
[Python] Fix dictionary delete with tuples as keys (#3621)
Browse files Browse the repository at this point in the history
* Fix python dictionary delete

* Update changelog
  • Loading branch information
dbrattli authored Nov 28, 2023
1 parent be95758 commit cd5d962
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 18 deletions.
2 changes: 2 additions & 0 deletions src/Fable.Cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
#### Python

* Fix #3617: Fix comparaison between list option when one is None
* Fix #3615: Fix remove from dictionary with tuple as key
* Fix #3598: Using obj () now generated an empty dict instead of None

## 4.6.0 - 2023-11-27

Expand Down
4 changes: 2 additions & 2 deletions src/Fable.Transforms/Python/Fable2Python.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,7 @@ module Util =
| "set" -> Expression.identifier "__setitem__"
| "get" -> Expression.identifier "__getitem__"
| "has" -> Expression.identifier "__contains__"
| "delete" -> Expression.identifier "__delitem__"
| n when n.EndsWith "get_Count" -> Expression.identifier "__len__" // TODO: find a better way
| n when n.StartsWith("Symbol.iterator") ->
let name = Identifier "__iter__"
Expand Down Expand Up @@ -1859,7 +1860,6 @@ module Util =

let getUnionExprTag (com: IPythonCompiler) ctx r (fableExpr: Fable.Expr) =
let expr, stmts = com.TransformAsExpr(ctx, fableExpr)

let expr, stmts' = getExpr com ctx r expr (Expression.constant "tag")

expr, stmts @ stmts'
Expand Down Expand Up @@ -3934,7 +3934,7 @@ module Util =
transformFunctionWithAnnotations com ctx name args body
|||> makeArrowFunctionExpression com ctx name

| Fable.ObjectExpr([], _typ, None) -> Expression.none, []
| Fable.ObjectExpr([], _typ, None) -> Expression.dict (), []
| Fable.ObjectExpr(members, typ, baseCall) ->
// printfn "members: %A" (members, typ)
transformObjectExpr com ctx members typ baseCall
Expand Down
2 changes: 2 additions & 0 deletions src/Fable.Transforms/Python/Python.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,8 @@ module PythonExtensions =
}
|> Dict

static member dict() : Expression = Expression.dict ([], [])

static member tuple(elts, ?loc) : Expression =
{
Elements = elts
Expand Down
30 changes: 17 additions & 13 deletions src/Fable.Transforms/Python/PythonPrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -479,23 +479,27 @@ module PrinterExtensions =

member printer.Print(node: Dict) =
printer.Print("{")
printer.PrintNewLine()
printer.PushIndentation()

let nodes =
List.zip node.Keys node.Values |> List.mapi (fun i n -> (i, n))
if not node.Keys.IsEmpty then
printer.PrintNewLine()
printer.PushIndentation()

for i, (key, value) in nodes do
printer.Print(key)
printer.Print(": ")
printer.Print(value)
let nodes =
List.zip node.Keys node.Values
|> List.mapi (fun i n -> (i, n))

if i < nodes.Length - 1 then
printer.Print(",")
printer.PrintNewLine()
for i, (key, value) in nodes do
printer.Print(key)
printer.Print(": ")
printer.Print(value)

if i < nodes.Length - 1 then
printer.Print(",")
printer.PrintNewLine()

printer.PrintNewLine()
printer.PopIndentation()

printer.PrintNewLine()
printer.PopIndentation()
printer.Print("}")

member printer.Print(node: Name) =
Expand Down
7 changes: 4 additions & 3 deletions src/fable-library-py/fable_library/date.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
from re import Match
from typing import Any

from .time_span import TimeSpan
from .time_span import create as create_time_span
from .types import FSharpRef
from .util import DateKind
from .time_span import TimeSpan, create as create_time_span


formatRegExp = re.compile(r"(\w)\1*")
Expand All @@ -17,8 +18,8 @@ def op_subtraction(x: datetime, y: datetime) -> TimeSpan:
delta = x - y
# ts.microseconds only contains the microseconds provided to the constructor
# so we need to calculate the total microseconds ourselves
delta_microseconds = delta.days * (24*3600) + delta.seconds * 10**6 + delta.microseconds
return create_time_span(0,0,0,0,0,delta_microseconds)
delta_microseconds = delta.days * (24 * 3600) + delta.seconds * 10**6 + delta.microseconds
return create_time_span(0, 0, 0, 0, 0, delta_microseconds)


def create(
Expand Down
7 changes: 7 additions & 0 deletions tests/Python/TestDictionary.fs
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,10 @@ let ``test Dictionary.Delete works`` () =
dic.ContainsValue("Hello") |> equal true
dic.Remove("A") |> equal true
dic.ContainsValue("Hello") |> equal false

[<Fact>]
let ``test Dictionary.Delete works with tuples as keys`` () =
let my_dict = Dictionary((Map [for i in 0..10 do yield (i,i), sprintf "Number: %i" i]))
my_dict.ContainsKey((0,0)) |> equal true
my_dict.Remove((0,0)) |> equal true
my_dict.ContainsKey((0,0)) |> equal false

0 comments on commit cd5d962

Please sign in to comment.