|
40 | 40 | create_task/3, create_task/4, |
41 | 41 | run/3, run/4, |
42 | 42 | spawn_task/3, spawn_task/4, |
43 | | - await/1, await/2 |
| 43 | + await/1, await/2, |
| 44 | + %% Per-process namespace API |
| 45 | + exec/1, exec/2, |
| 46 | + eval/1, eval/2 |
44 | 47 | ]). |
45 | 48 |
|
46 | 49 | %% Legacy API |
@@ -272,6 +275,63 @@ await(Ref, Timeout) -> |
272 | 275 | {error, timeout} |
273 | 276 | end. |
274 | 277 |
|
| 278 | +%%% ============================================================================ |
| 279 | +%%% Per-Process Namespace API |
| 280 | +%%% ============================================================================ |
| 281 | + |
| 282 | +%% @doc Execute Python code in the calling process's event loop namespace. |
| 283 | +%% |
| 284 | +%% Each Erlang process gets an isolated Python namespace for its assigned |
| 285 | +%% event loop. Functions defined via exec/1 can be called via create_task/3 |
| 286 | +%% with the `__main__' module. |
| 287 | +%% |
| 288 | +%% Example: |
| 289 | +%% <pre> |
| 290 | +%% ok = py_event_loop_pool:exec(<<" |
| 291 | +%% async def my_async_func(x): |
| 292 | +%% return x * 2 |
| 293 | +%% ">>), |
| 294 | +%% Ref = py_event_loop_pool:create_task('__main__', my_async_func, [21]), |
| 295 | +%% {ok, 42} = py_event_loop_pool:await(Ref) |
| 296 | +%% </pre> |
| 297 | +-spec exec(Code :: binary() | iolist()) -> ok | {error, term()}. |
| 298 | +exec(Code) -> |
| 299 | + case get_loop() of |
| 300 | + {ok, LoopRef} -> |
| 301 | + exec(LoopRef, Code); |
| 302 | + {error, not_available} -> |
| 303 | + %% Fallback to default event loop |
| 304 | + py_event_loop:exec(Code) |
| 305 | + end. |
| 306 | + |
| 307 | +-spec exec(LoopRef :: reference(), Code :: binary() | iolist()) -> ok | {error, term()}. |
| 308 | +exec(LoopRef, Code) -> |
| 309 | + py_nif:event_loop_exec(LoopRef, Code). |
| 310 | + |
| 311 | +%% @doc Evaluate a Python expression in the calling process's namespace. |
| 312 | +%% |
| 313 | +%% Returns the result of evaluating the expression. |
| 314 | +%% |
| 315 | +%% Example: |
| 316 | +%% <pre> |
| 317 | +%% ok = py_event_loop_pool:exec(<<"x = 42">>), |
| 318 | +%% {ok, 42} = py_event_loop_pool:eval(<<"x">>), |
| 319 | +%% {ok, 84} = py_event_loop_pool:eval(<<"x * 2">>) |
| 320 | +%% </pre> |
| 321 | +-spec eval(Expr :: binary() | iolist()) -> {ok, term()} | {error, term()}. |
| 322 | +eval(Expr) -> |
| 323 | + case get_loop() of |
| 324 | + {ok, LoopRef} -> |
| 325 | + eval(LoopRef, Expr); |
| 326 | + {error, not_available} -> |
| 327 | + %% Fallback to default event loop |
| 328 | + py_event_loop:eval(Expr) |
| 329 | + end. |
| 330 | + |
| 331 | +-spec eval(LoopRef :: reference(), Expr :: binary() | iolist()) -> {ok, term()} | {error, term()}. |
| 332 | +eval(LoopRef, Expr) -> |
| 333 | + py_nif:event_loop_eval(LoopRef, Expr). |
| 334 | + |
275 | 335 | %%% ============================================================================ |
276 | 336 | %%% Legacy API |
277 | 337 | %%% ============================================================================ |
|
0 commit comments