PythonInterpreterConfig

This type configures the default behavior of the embedded Python interpreter.

Embedded Python interpreters are configured and instantiated using a Rust pyembed::OxidizedPythonInterpreterConfig data structure. The pyembed crate defines a default instance of this data structure with parameters defined by the settings in this type.

Note

If you are writing custom Rust code and constructing a custom pyembed::OxidizedPythonInterpreterConfig instance and don’t use the default instance, this config type is not relevant to you and can be omitted from your config file.

Danger

Some of the settings exposed by Python’s initialization APIs are extremely low level and brittle. Various combinations can cause the process to crash/exit ungracefully. Be very cautious when setting these low-level settings.

Constructors

Instances are constructed by calling PythonDistribution.make_python_interpreter_config().

Attributes

The PythonInterpreterConfig state is managed via attributes.

There are a ton of attributes and most attributes are not relevant to most applications. The bulk of the attributes exist to give full control over Python interpreter initialization.

Attributes For Controlling pyembed Features

This section documents attributes for controlling features provided by the pyembed Rust crate, which manages the embedded Python interpreter at run-time.

These attributes provide features and level of control over embedded Python interpreters beyond what is possible with Python’s initialization C API.

raw_allocator

(string)

Configures the low-level raw allocator used by Python. Internally, Python has its own allocator that manages pools of memory. But that allocator gets its memory from some other allocator. This attribute defines what that other allocator is. In Python C API speak, this defines the allocator for the PYMEM_DOMAIN_RAW allocator.

Accepted values are:

system
Use the default allocator functions exposed to the binary (malloc(), free(), etc).
jemalloc
Use the jemalloc allocator.
rust
Use Rust’s global allocator (whatever that may be).

The jemalloc allocator requires the jemalloc-sys crate to be available. A run-time error will occur if jemalloc is configured but this allocator isn’t available.

Important

The rust allocator is not recommended because it introduces performance overhead. But it may help with debugging in some situations.

Default is jemalloc on non-Windows targets and system on Windows. (The jemalloc-sys crate doesn’t work on Windows MSVC targets.)

oxidized_importer

(bool)

Whether to install the oxidized_importer meta path importer (oxidized_importer Python Extension) on sys.meta_path during interpreter initialization.

Defaults to True.

filesystem_importer

(bool)

Whether to install the standard library path-based importer for loading Python modules from the filesystem.

If not enabled, Python modules will not be loaded from the filesystem (via sys.path discovery): only modules indexed by oxidized_importer will be loadable.

The filesystem importer is enabled automatically if module_search_paths is non-empty.

argvb

(bool)

Whether to expose a sys.argvb attribute containing bytes versions of process arguments.

On platforms where the process receives char * arguments, Python normalizes these values to unicode and makes them available via sys.argv. On platforms where the process receives wchar_t * arguments, Python may interpret the bytes as a certain encoding. This encoding normalization can be lossy.

Enabling this feature will give Python applications access to the raw bytes values of arguments that are actually used. The single or double width bytes nature of the data is preserved.

Unlike sys.argv which may chomp off leading arguments depending on the Python execution mode, sys.argvb has all the arguments used to initialize the process. The first argument is always the executable.

sys_frozen

(bool)

Controls whether to set the sys.frozen attribute to True. If false, sys.frozen is not set.

Default is False.

sys_meipass

(bool)

Controls whether to set the sys._MEIPASS attribute to the path of the executable.

Setting this and sys_frozen to True will emulate the behavior of PyInstaller and could possibly help self-contained applications that are aware of PyInstaller also work with PyOxidizer.

Default is False.

terminfo_resolution

(string)

Defines how the terminal information database (terminfo) should be configured.

See Terminfo Database for more about terminal databases.

Accepted values are:

dynamic

Looks at the currently running operating system and attempts to do something reasonable.

For example, on Debian based distributions, it will look for the terminfo database in /etc/terminfo, /lib/terminfo, and /usr/share/terminfo, which is how Debian configures ncurses to behave normally. Similar behavior exists for other recognized operating systems.

If the operating system is unknown, PyOxidizer falls back to looking for the terminfo database in well-known directories that often contain the database (like /usr/share/terminfo).

none
The value none indicates that no configuration of the terminfo database path should be performed. This is useful for applications that don’t interact with terminals. Using none can prevent some filesystem I/O at application startup.
static:<path>

Indicates that a static path should be used for the path to the terminfo database.

This values consists of a : delimited list of filesystem paths that ncurses should be configured to use. This value will be used to populate the TERMINFO_DIRS environment variable at application run time.

terminfo is not used on Windows and this setting is ignored on that platform.

write_modules_directory_env

(string or None)

Environment variable that defines a directory where modules-<UUID> files containing a \n delimited list of loaded Python modules (from sys.modules) will be written upon interpreter shutdown.

If this setting is not defined or if the environment variable specified by its value is not present at run-time, no special behavior will occur. Otherwise, the environment variable’s value is interpreted as a directory, that directory and any of its parents will be created, and a modules-<UUID> file will be written to the directory.

This setting is useful for determining which Python modules are loaded when running Python code.

run_mode

(string)

This attribute controls what the Python interpreter should do after initializing.

Accepted values are:

none
Don’t do anything after initialization.
repl

Run a Python REPL.

This should be equivalent to python.

module:<module>

Run a named Python module as __main__.

This is roughly equivalent to python -m <module>.

python -m <module> has additional functionality compared to PyOxidizer. For example, Python will look for <module>.__main__ whereas PyOxidizer does not. Therefore an exact module name must be used.

eval:<code>

Run Python code via eval().

This should be equivalent to python -c <code>.

An example value would be eval:import mymodule; mymodule.main().

file:<path>

Run Python code in a file.

This should be equivalent to python <path>.

The filename is resolved at run-time using whatever mechanism the Python interpreter applies.

Attributes From PyPreConfig

Attributes in this section correspond to fields of the PyPreConfig C struct used to initialize the Python interpreter.

config_profile

(string)

This attribute controls which set of default values to use for attributes that aren’t explicitly defined. It effectively controls which C API to use to initialize the PyPreConfig instance.

Accepted values are:

isolated

Use the isolated configuration.

This configuration is appropriate for applications existing in isolation and not behaving like python executables.

python

Use the Python configuration.

This configuration is appropriate for applications attempting to behave like a python executable would.

allocator

(string or None)

Controls the value of PyPreConfig.allocator.

Accepted values are:

None
Use the default.
not-set
PYMEM_ALLOCATOR_NOT_SET
default
PYMEM_ALLOCATOR_DEFAULT
debug
PYMEM_ALLOCATOR_DEBUG
malloc
PYMEM_ALLOCATOR_MALLOC
malloc-debug
PYMEM_ALLOCATOR_MALLOC_DEBUG
py-malloc
PYMEM_ALLOCATOR_PYMALLOC
py-malloc-debug
PYMEM_ALLOCATOR_PYMALLOC_DEBUG

configure_locale

(bool or None)

Controls the value of PyPreConfig.configure_locale.

coerce_c_locale

(string or None)

Controls the value of PyPreConfig.coerce_c_locale.

Accepted values are:

LC_CTYPE
Read LC_CTYPE
C
Coerce the C locale.

coerce_c_locale_warn

(bool or None)

Controls the value of PyPreConfig.coerce_c_locale_warn.

development_mode

(bool or None)

Controls the value of PyPreConfig.development_mode.

isolated

(bool or None)

Controls the value of PyPreConfig.isolated.

legacy_windows_fs_encoding

(bool or None)

Controls the value of PyPreConfig.legacy_windows_fs_encoding.

parse_argv

(bool or None)

Controls the value of PyPreConfig.parse_argv.

use_environment

(bool or None)

Controls the value of PyPreConfig.use_environment.

utf8_mode

(bool or None)

Controls the value of PyPreConfig.utf8_mode.

Attributes From PyConfig

Attributes in this section correspond to fields of the PyConfig C struct used to initialize the Python interpreter.

base_exec_prefix

(string or None)

Controls the value of PyConfig.base_exec_prefix.

base_executable

(string or None)

Controls the value of PyConfig.base_exectuable.

base_prefix

(string or None)

Controls the value of PyConfig.base_prefix.

buffered_stdio

(bool or None)

Controls the value of PyConfig.buffered_stdio.

bytes_warning

(string or None)

Controls the value of PyConfig.bytes_warning.

Accepted values are:

  • None
  • none
  • warn
  • raise

check_hash_pycs_mode

(string or None)

Controls the value of PyConfig.check_hash_pycs_mode.

Accepted values are:

  • None
  • always
  • never
  • default

configure_c_stdio

(bool or None)

Controls the value of PyConfig.configure_c_stdio.

dump_refs

(bool or None)

Controls the value of PyConfig.dump_refs.

exec_prefix

(string or None)

Controls the value of PyConfig.exec_prefix.

executable

(string or None)

Controls the value of PyConfig.executable.

fault_handler

(bool or None)

Controls the value of PyConfig.fault_handler.

filesystem_encoding

(string or None)

Controls the value of PyConfig.filesystem_encoding.

filesystem_errors

(string or None)

Controls the value of PyConfig.filesystem_errors.

hash_seed

(int or None)

Controls the value of PyConfig.hash_seed.

PyConfig.use_hash_seed will automatically be set if this attribute is defined.

home

(string or None)

Controls the value of PyConfig.home.

import_time

(bool or None)

Controls the value of PyConfig.import_time.

inspect

(bool or None)

Controls the value of PyConfig.inspect.

install_signal_handlers

(bool or None)

Controls the value of PyConfig.install_signal_handlers.

interactive

(bool or None)

Controls the value of PyConfig.interactive.

legacy_windows_stdio

(bool or None)

Controls the value of PyConfig.legacy_windows_stdio.

malloc_stats

(bool or None)

Controls the value of PyConfig.malloc_stats.

module_search_paths

(list[string] or None)

Controls the value of PyConfig.module_search_paths.

This value effectively controls the initial value of sys.path.

The special string $ORIGIN in values will be expanded to the absolute path of the directory of the executable at run-time. For example, if the executable is /opt/my-application/pyapp, $ORIGIN will expand to /opt/my-application and the value $ORIGIN/lib will expand to /opt/my-application/lib.

Setting this to a non-empty value also has the side-effect of setting filesystem_importer = True

optimization_level

(int or None)

Controls the value of PyConfig.optimization_level.

Allowed values are:

  • None
  • 0
  • 1
  • 2

This setting is only relevant if write_bytecode is True and Python modules are being imported from the filesystem using Python’s standard filesystem importer.

parser_debug

(bool or None)

Controls the value of PyConfig.parser_debug.

pathconfig_warnings

(bool or None)

Controls the value of PyConfig.pathconfig_warnings.

prefix

(string or None)

Controls the value of PyConfig.prefix.

program_name

(string or None)

Controls the value of PyConfig.program_name.

pycache_prefix

(string or None)

Controls the value of PyConfig.pycache_prefix.

python_path_env

(string or None)

Controls the value of PyConfig.pythonpath_env.

quiet

(bool or None)

Controls the value of PyConfig.quiet.

run_command

(string or None)

Controls the value of PyConfig.run_command.

run_filename

(string or None)

Controls the value of PyConfig.run_filename.

run_module

(string or None)

Controls the value of PyConfig.run_module.

show_alloc_count

(bool or None)

Controls the value of PyConfig.show_alloc_count.

show_ref_count

(bool or None)

Controls the value of PyConfig.show_ref_count.

site_import

(bool or None)

Controls the value of PyConfig.site_import.

The site module is typically not needed for standalone/isolated Python applications.

skip_first_source_line

(bool or None)

Controls the value of PyConfig.skip_first_source_line.

stdio_encoding

(string or None)

Controls the value of PyConfig.stdio_encoding.

stdio_errors

(string or None)

Controls the value of PyConfig.stdio_errors.

tracemalloc

(bool or None)

Controls the value of PyConfig.tracemalloc.

user_site_directory

(bool or None)

Controls the value of PyConfig.user_site_directory.

verbose

(bool or None)

Controls the value of PyConfig.verbose.

warn_options

(list[string] or None)

Controls the value of PyConfig.warn_options.

write_bytecode

(bool or None)

Controls the value of PyConfig.write_bytecode.

This only influences the behavior of Python standard path-based importer (controlled via filesystem_importer).

x_options

(list[string] or None)

Controls the value of PyConfig.xoptions.

Starlark Caveats

The PythonInterpreterConfig Starlark type is backed by a Rust data structure. And when attributes are retrieved, a copy of the underlying Rust struct field is returned.

This means that if you attempt to mutate a Starlark value (as opposed to assigning an attribute), the mutation won’t be reflected on the underlying Rust data structure.

For example:

config = dist.make_python_interpreter_config()

# assigns vec!["foo", "bar"].
config.module_search_paths = ["foo", "bar"]

# Creates a copy of the underlying list and appends to that copy.
# The stored value of `module_search_paths` is still `["foo", "bar"]`.
config.module_search_paths.append("baz")

To append to a list, do something like the following:

value = config.module_search_paths
value.append("baz")
config.module_search_paths = value