Skip to content

Commit 0272f7d

Browse files
authored
[Python] Code refactor and curry fix (#4329)
1 parent 132a224 commit 0272f7d

38 files changed

Lines changed: 653 additions & 2388 deletions

src/Fable.Cli/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919

2020
### Fixed
2121

22+
* [Python] Fix curry/uncurry to handle arbitrary number of arguments (by @dbrattli)
2223
* [Python] Fix type annotations for protocols, Option casting, and abstract classes (by @dbrattli)
2324
* [Python] Fix type annotations for curried functions and numeric types (by @dbrattli)
2425
* [Python] Fix type annotations for inref, IList, DateKind, and regex collections (by @dbrattli)

src/Fable.Compiler/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919

2020
### Fixed
2121

22+
* [Python] Fix curry/uncurry to handle arbitrary number of arguments (by @dbrattli)
2223
* [Python] Fix type annotations for protocols, Option casting, and abstract classes (by @dbrattli)
2324
* [Python] Fix type annotations for curried functions and numeric types (by @dbrattli)
2425
* [Python] Fix type annotations for inref, IList, DateKind, and regex collections (by @dbrattli)

src/Fable.Transforms/Python/Fable2Python.Annotation.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ let makeNumberTypeAnnotation com ctx kind info =
451451
match name with
452452
| "int"
453453
| "float" -> Expression.name name
454-
| _ -> fableModuleAnnotation com ctx "types" name []
454+
| _ -> fableModuleAnnotation com ctx "core" name []
455455

456456

457457
match kind, info with
@@ -631,7 +631,7 @@ let makeBuiltinTypeAnnotation com ctx typ repeatedGenerics kind =
631631
| Replacements.Util.BclGuid -> stdlibModuleTypeHint com ctx "uuid" "UUID" [] repeatedGenerics
632632
| Replacements.Util.FSharpReference genArg ->
633633
let resolved, stmts = resolveGenerics com ctx [ genArg ] repeatedGenerics
634-
fableModuleAnnotation com ctx "types" "FSharpRef" resolved, stmts
634+
fableModuleAnnotation com ctx "core" "FSharpRef" resolved, stmts
635635
(*
636636
| Replacements.Util.BclTimeSpan -> NumberTypeAnnotation
637637
| Replacements.Util.BclDateTime -> makeSimpleTypeAnnotation com ctx "Date"

src/Fable.Transforms/Python/Fable2Python.Reflection.fs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ let private libReflectionCall (com: IPythonCompiler) ctx r memberName args =
1717

1818
/// Wraps a Python list expression in Array(...) constructor
1919
let private arrayExpr (com: IPythonCompiler) ctx (items: Expression list) =
20-
Expression.call (libValue com ctx "types" "Array", [ Expression.list items ])
20+
Expression.call (libValue com ctx "array_" "Array", [ Expression.list items ])
2121

2222
let private transformRecordReflectionInfo com ctx r (ent: Fable.Entity) generics =
2323
// TODO: Refactor these three bindings to reuse in transformUnionReflectionInfo
@@ -318,18 +318,18 @@ let transformTypeTest (com: IPythonCompiler) ctx range expr (typ: Fable.Type) :
318318
| Fable.String -> pyTypeof "<class 'str'>" expr
319319
| Fable.Number(kind, _b) ->
320320
match kind, typ with
321-
| _, Fable.Type.Number(UInt8, _) -> pyInstanceof (libValue com ctx "types" "uint8") expr
322-
| _, Fable.Type.Number(Int8, _) -> pyInstanceof (libValue com ctx "types" "int8") expr
323-
| _, Fable.Type.Number(Int16, _) -> pyInstanceof (libValue com ctx "types" "int16") expr
324-
| _, Fable.Type.Number(UInt16, _) -> pyInstanceof (libValue com ctx "types" "uint16") expr
325-
| _, Fable.Type.Number(Int32, _) -> pyInstanceof (libValue com ctx "types" "int32") expr
326-
| _, Fable.Type.Number(UInt32, _) -> pyInstanceof (libValue com ctx "types" "uint32") expr
321+
| _, Fable.Type.Number(UInt8, _) -> pyInstanceof (libValue com ctx "core" "uint8") expr
322+
| _, Fable.Type.Number(Int8, _) -> pyInstanceof (libValue com ctx "core" "int8") expr
323+
| _, Fable.Type.Number(Int16, _) -> pyInstanceof (libValue com ctx "core" "int16") expr
324+
| _, Fable.Type.Number(UInt16, _) -> pyInstanceof (libValue com ctx "core" "uint16") expr
325+
| _, Fable.Type.Number(Int32, _) -> pyInstanceof (libValue com ctx "core" "int32") expr
326+
| _, Fable.Type.Number(UInt32, _) -> pyInstanceof (libValue com ctx "core" "uint32") expr
327327
| _, Fable.Type.Number(NativeInt, _)
328328
| _, Fable.Type.Number(UNativeInt, _) -> pyInstanceof (Expression.name "int") expr
329-
| _, Fable.Type.Number(Int64, _) -> pyInstanceof (libValue com ctx "types" "int64") expr
330-
| _, Fable.Type.Number(UInt64, _) -> pyInstanceof (libValue com ctx "types" "uint64") expr
331-
| _, Fable.Type.Number(Float32, _) -> pyInstanceof (libValue com ctx "types" "float32") expr
332-
| _, Fable.Type.Number(Float64, _) -> pyInstanceof (libValue com ctx "types" "float64") expr
329+
| _, Fable.Type.Number(Int64, _) -> pyInstanceof (libValue com ctx "core" "int64") expr
330+
| _, Fable.Type.Number(UInt64, _) -> pyInstanceof (libValue com ctx "core" "uint64") expr
331+
| _, Fable.Type.Number(Float32, _) -> pyInstanceof (libValue com ctx "core" "float32") expr
332+
| _, Fable.Type.Number(Float64, _) -> pyInstanceof (libValue com ctx "core" "float64") expr
333333
| _, Fable.Type.Number(Decimal, _) -> pyTypeof "<class 'decimal.Decimal'>" expr
334334
| _ -> pyInstanceof (Expression.name "int") expr
335335

@@ -338,7 +338,7 @@ let transformTypeTest (com: IPythonCompiler) ctx range expr (typ: Fable.Type) :
338338
| Fable.DelegateType _ -> pyTypeof "<class 'function'>" expr
339339
| Fable.Array _ ->
340340
// Use isinstance(x, Array) where Array is from fable_library.types
341-
pyInstanceof (libValue com ctx "types" "Array") expr
341+
pyInstanceof (libValue com ctx "array_" "Array") expr
342342
| Fable.Tuple _ ->
343343
// Use isinstance(x, tuple) for Python tuple type test
344344
pyInstanceof (Expression.name "tuple") expr
@@ -366,10 +366,10 @@ let transformTypeTest (com: IPythonCompiler) ctx range expr (typ: Fable.Type) :
366366
[ expr ] |> libCall com ctx None "util" "isIterable", stmts
367367
| Types.array ->
368368
// Use isinstance(x, Array) where Array is from fable_library.types
369-
pyInstanceof (libValue com ctx "types" "Array") expr
369+
pyInstanceof (libValue com ctx "array_" "Array") expr
370370
| Types.exception_ ->
371371
let expr, stmts = com.TransformAsExpr(ctx, expr)
372-
[ expr ] |> libCall com ctx None "types" "isException", stmts
372+
[ expr ] |> libCall com ctx None "exceptions" "is_exception", stmts
373373
| Types.datetime -> pyInstanceof (com.GetImportExpr(ctx, "datetime", "datetime")) expr
374374
| _ ->
375375
let ent = com.GetEntity(ent)

src/Fable.Transforms/Python/Fable2Python.Transforms.fs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ let makeArrowFunctionExpression
111111
let args =
112112
match args.PosOnlyArgs, args.Args with
113113
| [], [] ->
114-
let ta = com.GetImportExpr(ctx, "typing", "Any")
114+
let ta = com.GetImportExpr(ctx, getLibPath com "util", "Unit")
115115

116-
Arguments.arguments (args = [ Arg.arg ("__unit", annotation = ta) ], defaults = [ Expression.none ])
116+
Arguments.arguments (args = [ Arg.arg ("__unit", annotation = ta) ], defaults = [ Expression.tuple [] ])
117117
| _ -> args
118118

119119
let allDefaultsAreNone =
@@ -320,15 +320,15 @@ let transformCast (com: IPythonCompiler) (ctx: Context) t e : Expression * State
320320

321321
| _ -> com.TransformAsExpr(ctx, e)
322322
| Fable.Number(Float32, _), _ ->
323-
let cons = libValue com ctx "types" "float32"
323+
let cons = libValue com ctx "core" "float32"
324324
let value, stmts = com.TransformAsExpr(ctx, e)
325325
Expression.call (cons, [ value ], ?loc = None), stmts
326326
| Fable.Number(Float64, _), _ ->
327-
let cons = libValue com ctx "types" "float64"
327+
let cons = libValue com ctx "core" "float64"
328328
let value, stmts = com.TransformAsExpr(ctx, e)
329329
Expression.call (cons, [ value ], ?loc = None), stmts
330330
| Fable.Number(Int32, _), _ ->
331-
let cons = libValue com ctx "types" "int32"
331+
let cons = libValue com ctx "core" "int32"
332332
let value, stmts = com.TransformAsExpr(ctx, e)
333333
Expression.call (cons, [ value ], ?loc = None), stmts
334334
| _ -> com.TransformAsExpr(ctx, e)
@@ -393,9 +393,9 @@ let transformValue (com: IPythonCompiler) (ctx: Context) r value : Expression *
393393
| Fable.NumberValue.Float64 x when x = -infinity -> libValue com ctx "double" "float64.negative_infinity", []
394394
| Fable.NumberValue.Float64 x when Double.IsNaN(x) -> libValue com ctx "double" "float64.nan", []
395395
| Fable.NumberValue.Float32 x when Single.IsNaN(x) ->
396-
libCall com ctx r "types" "float32" [ Expression.stringConstant "nan" ], []
396+
libCall com ctx r "core" "float32" [ Expression.stringConstant "nan" ], []
397397
| Fable.NumberValue.Float16 x when Single.IsNaN(x) ->
398-
libCall com ctx r "types" "float32" [ Expression.stringConstant "nan" ], []
398+
libCall com ctx r "core" "float32" [ Expression.stringConstant "nan" ], []
399399
| Fable.NumberValue.Float16 x -> makeFloat com ctx r value.Type "float32" (float x)
400400
| Fable.NumberValue.Float32 x -> makeFloat com ctx r value.Type "float32" (float x)
401401
| Fable.NumberValue.Float64 x -> makeFloat com ctx r value.Type "float64" (float x)
@@ -2977,21 +2977,23 @@ let transformFunction
29772977
args', finalDefaults, body
29782978

29792979
let arguments =
2980+
let unitDefault = libValue com ctx "util" "UNIT"
2981+
29802982
match args, isUnitOrGeneric, tcArgs with
29812983
// No args and no tail-call args: add __unit parameter
29822984
| [], _, [] ->
2983-
let unitDefault = libValue com ctx "util" "UNIT"
2984-
Arguments.arguments (args = [ Arg.arg (Identifier("__unit")) ], defaults = [ unitDefault ])
2985+
let unitType = com.GetImportExpr(ctx, getLibPath com "util", "Unit")
2986+
2987+
Arguments.arguments (
2988+
args = [ Arg.arg (Identifier("__unit"), annotation = unitType) ],
2989+
defaults = [ unitDefault ]
2990+
)
29852991
// No args but has tail-call args: skip __unit, tcArgs are sufficient
29862992
| [], _, _ -> Arguments.arguments (args = tcArgs, defaults = tcDefaults)
2987-
// Single generic/unit arg with no tail-call args: keep it with UNIT default
2988-
| [ arg ], true, [] ->
2989-
let unitDefault = libValue com ctx "util" "UNIT"
2990-
Arguments.arguments (args = args, defaults = [ unitDefault ])
2993+
// Single generic/unit arg with no tail-call args: keep it with () default
2994+
| [ arg ], true, [] -> Arguments.arguments (args = args, defaults = [ unitDefault ])
29912995
// Single generic/unit arg with tail-call args: keep arg (body may reference it)
2992-
| [ arg ], true, _ ->
2993-
let unitDefault = libValue com ctx "util" "UNIT"
2994-
Arguments.arguments (args @ tcArgs, defaults = unitDefault :: tcDefaults)
2996+
| [ arg ], true, _ -> Arguments.arguments (args @ tcArgs, defaults = unitDefault :: tcDefaults)
29952997
| _ -> Arguments.arguments (args @ tcArgs, defaults = defaults @ tcDefaults)
29962998

29972999
arguments, body
@@ -3828,7 +3830,7 @@ let transformUnion (com: IPythonCompiler) ctx (ent: Fable.Entity) (entName: stri
38283830
decoratorList = decorators
38293831
)
38303832

3831-
let baseExpr = libValue com ctx "types" "Union" |> Some
3833+
let baseExpr = libValue com ctx "union" "Union" |> Some
38323834
let classMembers = List.append [ cases ] classMembers
38333835

38343836
declareType com ctx ent entName args isOptional body baseExpr classMembers None [] []
@@ -3853,9 +3855,9 @@ let transformClassWithCompilerGeneratedConstructor
38533855

38543856
let baseExpr =
38553857
if ent.IsFSharpExceptionDeclaration then
3856-
libValue com ctx "types" "FSharpException" |> Some
3858+
libValue com ctx "exceptions" "FSharpException" |> Some
38573859
elif ent.IsFSharpRecord || ent.IsValueType then
3858-
libValue com ctx "types" "Record" |> Some
3860+
libValue com ctx "record" "Record" |> Some
38593861
else
38603862
None
38613863

@@ -4055,7 +4057,7 @@ let transformClassWithPrimaryConstructor
40554057
|> extractBaseExprFromBaseCall com ctx classEnt.BaseType
40564058
|> Option.orElseWith (fun () ->
40574059
if classEnt.IsValueType then
4058-
Some(libValue com ctx "Types" "Record", ([], [], []))
4060+
Some(libValue com ctx "record" "Record", ([], [], []))
40594061
else
40604062
None
40614063
)

src/Fable.Transforms/Python/Fable2Python.Util.fs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ module Util =
489489

490490
let ofInt (com: IPythonCompiler) (ctx: Context) (i: int) =
491491
//Expression.intConstant (int i)
492-
libCall com ctx None "types" "int32" [ Expression.intConstant (int i) ]
492+
libCall com ctx None "core" "int32" [ Expression.intConstant (int i) ]
493493

494494
let ofString (s: string) = Expression.stringConstant s
495495

@@ -560,7 +560,7 @@ module Util =
560560
if l = "Any" then
561561
com.GetImportExpr(ctx, "typing", "Any")
562562
else
563-
libValue com ctx "types" l
563+
libValue com ctx "core" l
564564

565565
let types_array = Expression.subscript (value = array, slice = type_obj, ctx = Load)
566566
Expression.call (types_array, [ expr ])
@@ -803,7 +803,7 @@ module Util =
803803
Expression.attribute (expr, Identifier field, ctx = Load), []
804804

805805
let makeInteger (com: IPythonCompiler) (ctx: Context) r _t intName (x: obj) =
806-
let cons = libValue com ctx "types" intName
806+
let cons = libValue com ctx "core" intName
807807
let value = Expression.intConstant (x, ?loc = r)
808808

809809
// Added support for a few selected literals for performance reasons
@@ -927,7 +927,7 @@ module Util =
927927
| _ -> Expression.call (cons, [ value ], ?loc = r), []
928928

929929
let makeFloat (com: IPythonCompiler) (ctx: Context) r _t floatName x =
930-
let cons = libValue com ctx "types" floatName
930+
let cons = libValue com ctx "core" floatName
931931
let value = Expression.floatConstant (x, ?loc = r)
932932
Expression.call (cons, [ value ], ?loc = r), []
933933

0 commit comments

Comments
 (0)