Skip to content

Commit

Permalink
Merge pull request #3551 from fable-compiler/python-fixes-string-inte…
Browse files Browse the repository at this point in the history
…rpolation
  • Loading branch information
MangelMaxime authored Oct 18, 2023
2 parents 5fcd0a1 + 91086ad commit 0814230
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 13 deletions.
1 change: 1 addition & 0 deletions src/Fable.Cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,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

Expand Down
6 changes: 6 additions & 0 deletions src/Fable.Core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
4 changes: 4 additions & 0 deletions src/Fable.Core/Fable.Core.Py.fs
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ module Py =
/// https://code.visualstudio.com/docs/python/jupyter-support-py
[<Emit("# %%", isStatement=true)>]
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
6 changes: 6 additions & 0 deletions src/Fable.Transforms/Python/Replacements.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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, _ ->
Expand Down
41 changes: 28 additions & 13 deletions src/fable-library-py/fable_library/async_.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@


_T = TypeVar("_T")
_U = TypeVar("_U")


def cancellation_token() -> Async[CancellationToken]:
Expand Down Expand Up @@ -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] = []
Expand Down Expand Up @@ -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)

Expand Down

0 comments on commit 0814230

Please sign in to comment.