pub struct MainPythonInterpreter<'interpreter, 'resources: 'interpreter> { /* private fields */ }
Expand description

Manages an embedded Python interpreter.

Python interpreters have global state and there can only be a single instance of this type per process. There exists a global lock enforcing this. Calling new() will block waiting for this lock. The lock is released when the instance is dropped.

Instances must only be constructed through MainPythonInterpreter::new().

This type and its various functionality is a glorified wrapper around the Python C API. But there’s a lot of added functionality on top of what the C API provides.

Usage

Construct instances via MainPythonInterpreter::new(). This will acquire a global lock and initialize the main Python interpreter in the current process.

Python code can then be executed in the interpreter in any number of different ways.

If you want to run whatever was configured to run via the OxidizedPythonInterpreterConfig used to construct the instance, call MainPythonInterpreter::run() or MainPythonInterpreter::py_runmain(). The former will honor “multiprocessing worker” and is necessary for multiprocessing to work. MainPythonInterpreter::py_runmain() bypasses multiprocessing mode checks.

If you want to execute arbitrary Python code or want to run Rust code with the GIL held, call MainPythonInterpreter::with_gil(). The provided function will be provided a pyo3::Python, which represents a handle on the Python interpreter. This function is just a wrapper around pyo3::Python::with_gil(). But since the function holds a reference to self, it prevents MainPythonInterpreter from being dropped prematurely.

Safety

Dropping a MainPythonInterpreter instance will call Py_FinalizeEx() to finalize the Python interpreter and prevent it from running any more Python code.

If a Python C API is called after interpreter finalization, a segfault can occur.

If you use pyo3 APIs like Python::with_gil() directly, you may inadvertently attempt to operate on a finalized interpreter. Therefore it is recommended to always go through a method on an MainPythonInterpreter instance in order to interact with the Python interpreter.

Implementations§

Construct a Python interpreter from a configuration.

The Python interpreter is initialized as a side-effect. The GIL is held.

Proxy for Python::with_gil().

This allows running Python code via the PyO3 Rust APIs. Alternatively, this can be used to run code when the Python GIL is held.

Runs Py_RunMain() and finalizes the interpreter.

This will execute whatever is configured by the Python interpreter config and return an integer suitable for use as a process exit code.

Calling this function will finalize the interpreter and only gives you an exit code: there is no opportunity to inspect the return value or handle an uncaught exception. If you want to keep the interpreter alive or inspect the evaluation result, consider calling a function on the interpreter handle that executes code.

Run in “multiprocessing worker” mode.

This should be called when sys.argv[1] == "--multiprocessing-fork". It will parse arguments for the worker from sys.argv and call into the multiprocessing module to perform work.

Whether the Python interpreter is in “multiprocessing worker” mode.

The multiprocessing module can work by spawning new processes with arguments --multiprocessing-fork [key=value] .... This function detects if the current Python interpreter is configured for said execution.

Runs the Python interpreter.

If multiprocessing dispatch is enabled, this will check if the current process invocation appears to be a spawned multiprocessing worker and dispatch to multiprocessing accordingly.

Otherwise, this delegates to Self::py_runmain.

Trait Implementations§

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.