From 5d309a0adff213c22de2fed9cf08db3d8fbe478a Mon Sep 17 00:00:00 2001
From: Dag Brattli <dag@brattli.net>
Date: Tue, 31 Oct 2023 08:35:40 +0100
Subject: [PATCH] [Python] Generic typing fixes (#3577)

- Use Any type for all non-repeated generic parameters
- Don't generate unnecessary type type-vars if generic type is replaced by Any
- Generate new style _T | None instead of Optional[_T]
---
 src/Fable.Cli/CHANGELOG.md                  |  6 ++++++
 src/Fable.Transforms/Python/Fable2Python.fs | 19 ++++---------------
 2 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md
index 66e475c87f..4c6132263c 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
 
+#### Python
+
+* Use `Any` type for all non-repeated generic arguments (by @dbrattli)
+* Don't generate unnecessary type type-vars if generic type is replaced by `Any` (by @dbrattli)
+* Generate new style `_T | None` instead of `Optional[_T]` (by @dbrattli)
+
 ### Fixed
 
 #### JavaScript
diff --git a/src/Fable.Transforms/Python/Fable2Python.fs b/src/Fable.Transforms/Python/Fable2Python.fs
index 5113d7912e..e93dc9c582 100644
--- a/src/Fable.Transforms/Python/Fable2Python.fs
+++ b/src/Fable.Transforms/Python/Fable2Python.fs
@@ -579,9 +579,6 @@ module Annotation =
             com.GetImportExpr(ctx, "typing", "Generic")
             |> ignore
 
-            com.GetImportExpr(ctx, "typing", "TypeVar")
-            |> ignore
-
             let genParams =
                 genParams
                 |> Set.toList
@@ -695,7 +692,7 @@ module Annotation =
         |> Helpers.unzipArgs
 
     let typeAnnotation (com: IPythonCompiler) ctx (repeatedGenerics: Set<string> option) (t: Fable.Type) : Expression * Statement list =
-        // printfn "typeAnnotation: %A" t
+        // printfn "typeAnnotation: %A" (t, repeatedGenerics)
         match t with
         | Fable.Measure _
         | Fable.Any -> stdlibModuleTypeHint com ctx "typing" "Any" []
@@ -704,16 +701,10 @@ module Annotation =
         | Fable.GenericParam (name = name) ->
             match repeatedGenerics with
             | Some names when names.Contains name ->
-                com.GetImportExpr(ctx, "typing", "TypeVar")
-                |> ignore
-
                 let name = Helpers.clean name
                 com.AddTypeVar(ctx, name), []
             | Some _ -> stdlibModuleTypeHint com ctx "typing" "Any" []
             | None ->
-                com.GetImportExpr(ctx, "typing", "TypeVar")
-                |> ignore
-
                 let name = Helpers.clean name
                 com.AddTypeVar(ctx, name), []
         | Fable.Unit -> Expression.none, []
@@ -726,7 +717,7 @@ module Annotation =
             stdlibModuleTypeHint com ctx "typing" "Callable" (argTypes @ [ returnType ])
         | Fable.DelegateType (argTypes, returnType) -> stdlibModuleTypeHint com ctx "typing" "Callable" (argTypes @ [ returnType ])
         | Fable.Option (genArg, _) ->
-            let resolved, stmts = resolveGenerics com ctx [genArg] None
+            let resolved, stmts = resolveGenerics com ctx [genArg] repeatedGenerics
             Expression.binOp(resolved[0], BitOr, Expression.none), stmts
         | Fable.Tuple (genArgs, _) -> makeGenericTypeAnnotation com ctx "tuple" genArgs None, []
         | Fable.Array (genArg, _) ->
@@ -1048,9 +1039,8 @@ module Util =
             discardUnitArg args
             |> List.map (fun arg ->
                 let name = getUniqueNameInDeclarationScope ctx (arg.Name + "_mut")
-
-                let ta, _ = typeAnnotation com ctx None arg.Type
-                Arg.arg (name, ta))
+                // Ignore type annotation here as it generates unnecessary typevars
+                Arg.arg name)
 
         interface ITailCallOpportunity with
             member _.Label = name
@@ -3288,7 +3278,6 @@ module Util =
                 BoundVars = ctx.BoundVars.EnterScope()
                 ScopedTypeParams = Set.union ctx.ScopedTypeParams newTypeParams }
 
-        // printfn "Args: %A" args
         let body =
             if body.Type = Fable.Unit then
                 transformBlock com ctx (Some ReturnUnit) body