pyoxidizer 0.24.0

Package self-contained Python applications
Documentation
#![windows_subsystem = "{{{ windows_subsystem }}}"]

use pyembed::{MainPythonInterpreter, OxidizedPythonInterpreterConfig};

// Various cargo features can be defined to install a custom global allocator
// for Rust.
//
// Note that this *only* controls Rust's allocator: the Python interpreter
// has its own memory allocator settings on the
// `pyembed::OxidizedPythonInterpreterConfig` that will need to be set in
// order to fully leverage a custom allocator.

#[cfg(feature = "global-allocator-jemalloc")]
#[global_allocator]
static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc;

#[cfg(feature = "global-allocator-mimalloc")]
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;

#[cfg(feature = "global-allocator-snmalloc")]
#[global_allocator]
static GLOBAL: snmalloc_rs::SnMalloc = snmalloc_rs::SnMalloc;

// Include an auto-generated file defining a
// `fn default_python_config<'a>() -> pyembed::OxidizedPythonInterpreterConfig<'a>`
// which returns an `OxidizedPythonInterpreterConfig` derived by the PyOxidizer
// configuration file.
//
// If you do not want your application to use this generated file or wish
// to explicitly instantiate the `OxidizedPythonInterpreterConfig` used to
// initialize the embedded Python interpreter, simply remove this line and
// the call to `default_python_config()` below.
include!(env!("DEFAULT_PYTHON_CONFIG_RS"));

fn main() {
    // The following code is in a block so the MainPythonInterpreter is destroyed in an
    // orderly manner, before process exit.
    let exit_code = {
        // Load the default Python configuration as derived by the PyOxidizer config
        // file used at build time.
        let config: OxidizedPythonInterpreterConfig = default_python_config();

        // Construct a new Python interpreter using that config, handling any errors
        // from construction.
        match MainPythonInterpreter::new(config) {
            Ok(interp) => {
                // And run it using the default run configuration as specified by the
                // configuration.
                //
                // This will either call `interp.py_runmain()` or
                // `interp.run_multiprocessing()`. If `interp.py_runmain()` is called,
                // the interpreter is guaranteed to be finalized.
                interp.run()
            }
            Err(msg) => {
                eprintln!("error instantiating embedded Python interpreter: {}", msg);
                1
            }
        }
    };

    // And exit the process according to code execution results.
    std::process::exit(exit_code);
}