py_context (erlang_python v2.3.1)
View SourcePython context process.
A py_context process owns a Python context (subinterpreter or worker). Each process has exclusive access to its context, eliminating mutex contention and enabling true N-way parallelism.
The context is created when the process starts and destroyed when it stops. All Python operations are serialized through message passing.
Callback Handling
When Python code calls erlang.call()`, the NIF returns a `{suspended, ...}` tuple instead of blocking. The context process handles the callback inline using a recursive receive pattern, enabling arbitrarily deep callback nesting. This approach is inspired by PyO3s suspension mechanism and avoids the deadlock issues that occur with separate callback handler processes.
Summary
Functions
Call a Python function with empty kwargs.
Call a Python function.
Call a Python function with timeout.
Call a Python function with a process-local environment.
Call a method on a Python object reference.
Create a process-local Python environment for this context.
Alias for stop/1 for API consistency.
Evaluate a Python expression with empty locals.
Evaluate a Python expression.
Evaluate a Python expression with timeout.
Evaluate a Python expression with a process-local environment.
Execute Python statements.
Execute Python statements with a process-local environment.
Get the interpreter ID for this context.
Get the NIF context reference from a context process. This is useful for calling low-level py_nif functions directly.
Check if this context is a subinterpreter.
Create a new context with options map.
Start a new py_context process.
Stop a py_context process.
Convert a Python object reference to an Erlang term.
Types
-type context() :: pid().
-type context_mode() :: worker | subinterp | owngil.
Functions
-spec call(context(), atom() | binary(), atom() | binary(), list()) -> {ok, term()} | {error, term()}.
Call a Python function with empty kwargs.
This is a convenience wrapper for call/5 that defaults Kwargs to #{}.
-spec call(context(), atom() | binary(), atom() | binary(), list(), map()) -> {ok, term()} | {error, term()}.
Call a Python function.
-spec call(context(), atom() | binary(), atom() | binary(), list(), map(), timeout()) -> {ok, term()} | {error, term()}.
Call a Python function with timeout.
-spec call(context(), atom() | binary(), atom() | binary(), list(), map(), timeout(), reference()) -> {ok, term()} | {error, term()}.
Call a Python function with a process-local environment.
-spec call_method(context(), reference(), atom() | binary(), list()) -> {ok, term()} | {error, term()}.
Call a method on a Python object reference.
Create a process-local Python environment for this context.
The environment is created inside the context's interpreter to ensure the correct memory allocator is used. This is critical for subinterpreters where each interpreter has its own memory allocator.
The returned EnvRef should be stored in the calling process's dictionary, keyed by interpreter ID.
-spec destroy(context()) -> ok.
Alias for stop/1 for API consistency.
Evaluate a Python expression with empty locals.
This is a convenience wrapper for eval/3 that defaults Locals to #{}.
Evaluate a Python expression.
Evaluate a Python expression with timeout.
-spec eval(context(), binary() | string(), map(), timeout(), reference()) -> {ok, term()} | {error, term()}.
Evaluate a Python expression with a process-local environment.
Execute Python statements.
Execute Python statements with a process-local environment.
-spec get_interp_id(context()) -> {ok, non_neg_integer()} | {error, term()}.
Get the interpreter ID for this context.
Get the NIF context reference from a context process. This is useful for calling low-level py_nif functions directly.
Check if this context is a subinterpreter.
Returns true for subinterpreter mode, false for worker mode. In worker mode, process-local environments are used. In subinterpreter mode, each context has its own isolated namespace.
Create a new context with options map.
Options: - mode - Context mode (worker | subinterp | owngil), default: worker
-spec start_link(pos_integer(), context_mode()) -> {ok, pid()} | {error, term()}.
Start a new py_context process.
The process creates a Python context based on the mode: - worker - Create a thread-state worker (main interpreter namespace) - subinterp - Create a sub-interpreter with shared GIL (Python 3.12+) - owngil - Create a sub-interpreter with its own GIL (Python 3.14+)
The owngil mode creates a dedicated pthread for each context, allowing true parallel Python execution. Requires Python 3.14+.
-spec stop(context()) -> ok.
Stop a py_context process.
Convert a Python object reference to an Erlang term.