From 9e74a0a063fca65f7abf87336460ea80ccc80a9f Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Wed, 18 Oct 2023 08:25:24 +0200 Subject: [PATCH 1/3] Add back Fable.Core.Py.python --- src/Fable.Core/Fable.Core.Py.fs | 4 ++ src/Fable.Transforms/Python/Replacements.fs | 6 +++ src/fable-library-py/fable_library/async_.py | 41 +++++++++++++------- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/Fable.Core/Fable.Core.Py.fs b/src/Fable.Core/Fable.Core.Py.fs index aabe6ea038..3285f22e0a 100644 --- a/src/Fable.Core/Fable.Core.Py.fs +++ b/src/Fable.Core/Fable.Core.Py.fs @@ -43,3 +43,7 @@ module Py = /// https://code.visualstudio.com/docs/python/jupyter-support-py [] let NEW_CELL: unit = nativeOnly + + /// Embeds literal Python code into F#. Code will be printed as statements, + /// if you want to return a value use Python `return` keyword within a function. + let python (template: string): 'T = nativeOnly diff --git a/src/Fable.Transforms/Python/Replacements.fs b/src/Fable.Transforms/Python/Replacements.fs index 9ee23b2a96..56a1c41af6 100644 --- a/src/Fable.Transforms/Python/Replacements.fs +++ b/src/Fable.Transforms/Python/Replacements.fs @@ -867,6 +867,12 @@ let fableCoreLib (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Exp | "typedArrays" -> makeBoolConst com.Options.TypedArrays |> Some | "extension" -> makeStrConst com.Options.FileExtension |> Some | _ -> None + | "Fable.Core.Py", ("python" | "expr_python" as meth) -> + let isStatement = meth <> "expr_python" + match args with + | RequireStringConstOrTemplate com ctx r template::_ -> + emitTemplate r t [] isStatement template |> Some + | _ -> None | "Fable.Core.PyInterop", _ -> match i.CompiledName, args with | Naming.StartsWith "import" suffix, _ -> diff --git a/src/fable-library-py/fable_library/async_.py b/src/fable-library-py/fable_library/async_.py index 3b14735d14..dd91ee38c6 100644 --- a/src/fable-library-py/fable_library/async_.py +++ b/src/fable-library-py/fable_library/async_.py @@ -34,6 +34,7 @@ _T = TypeVar("_T") +_U = TypeVar("_U") def cancellation_token() -> Async[CancellationToken]: @@ -110,6 +111,15 @@ def delayed() -> Async[list[_T]]: return delay(delayed) +def parallel2(a: Async[_T], b: Async[_U]) -> Async[list[_T | _U]]: + def delayed() -> Async[list[_T, _T]]: + tasks: Iterable[Future[_T]] = map(start_as_task, [a, b]) # type: ignore + all: Future[list[_T]] = asyncio.gather(*tasks) + return await_task(all) + + return delay(delayed) + + def sequential(computations: Iterable[Async[_T]]) -> Async[list[_T | None]]: def delayed() -> Async[list[_T | None]]: results: list[_T] = [] @@ -266,28 +276,33 @@ def cancel(_: OperationCanceledError) -> None: return tcs.get_task() +def throw_after(milliseconds_due_time: int) -> Async[None]: + def cont(ctx: IAsyncContext[None]) -> None: + def cancel() -> None: + ctx.on_cancel(OperationCanceledError()) + + token_id = ctx.cancel_token.add_listener(cancel) + + def timeout() -> None: + ctx.cancel_token.remove_listener(token_id) + ctx.on_error(TimeoutError()) + + ctx.trampoline.run_later(timeout, milliseconds_due_time / 1000.0) + + return protected_cont(cont) + + def start_child(computation: Async[_T], ms: int | None = None) -> Async[Async[_T]]: if ms: computation_with_timeout = protected_bind( - parallel(computation, throw_after(ms)), lambda xs: protected_return(xs[0]) + parallel2(computation, throw_after(ms)), lambda xs: protected_return(xs[0]) ) return start_child(computation_with_timeout) task = start_as_task(computation) def cont(ctx: IAsyncContext[Async[_T]]) -> None: - def on_success(_: Async[_T]) -> None: - ctx.on_success(await_task(task)) - - on_error = ctx.on_error - on_cancel = ctx.on_cancel - trampoline = ctx.trampoline - cancel_token = ctx.cancel_token - - ctx_ = IAsyncContext.create( - on_success, on_error, on_cancel, trampoline, cancel_token - ) - computation(ctx_) + protected_return(await_task(task))(ctx) return protected_cont(cont) From 459f04b3fc22644797e7e019292e12d9792d42b1 Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Wed, 18 Oct 2023 08:31:12 +0200 Subject: [PATCH 2/3] Update changelog --- src/Fable.Cli/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md index cc20f46445..f5de987c08 100644 --- a/src/Fable.Cli/CHANGELOG.md +++ b/src/Fable.Cli/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +* Fix #3482: Revert removal of `Py.python` (by @dbrattli) + ### Fixed #### JavaScript From 91086adbe8bf01d47a002aa6b22888cbf390a3ed Mon Sep 17 00:00:00 2001 From: Maxime Mangel Date: Wed, 18 Oct 2023 10:47:06 +0200 Subject: [PATCH 3/3] Update the changelogs --- src/Fable.Cli/CHANGELOG.md | 3 +-- src/Fable.Core/CHANGELOG.md | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md index f5de987c08..d7a347baf0 100644 --- a/src/Fable.Cli/CHANGELOG.md +++ b/src/Fable.Cli/CHANGELOG.md @@ -6,8 +6,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -* Fix #3482: Revert removal of `Py.python` (by @dbrattli) - ### Fixed #### JavaScript @@ -38,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 #### Python * Added `Async.StartChild` (by @dbrattli) +* Fix #3482: Revert removal of `Py.python` and `Py.expr_python` (by @dbrattli) ## 4.2.2 - 2023-10-14 diff --git a/src/Fable.Core/CHANGELOG.md b/src/Fable.Core/CHANGELOG.md index 7b7568f8d4..dafc51e774 100644 --- a/src/Fable.Core/CHANGELOG.md +++ b/src/Fable.Core/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +#### Python + +* Fix #3482: Revert removal of `Py.python` and `Py.expr_python` (by @dbrattli) + ## 4.1.0 * Fix #3482: Remove `Py.python` and `Py.expr_python`