use {
crate::resource::BytecodeOptimizationLevel,
std::{convert::TryFrom, ffi::OsString, os::raw::c_ulong, path::PathBuf},
};
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum PythonInterpreterProfile {
Isolated,
Python,
}
impl Default for PythonInterpreterProfile {
fn default() -> Self {
PythonInterpreterProfile::Isolated
}
}
impl ToString for PythonInterpreterProfile {
fn to_string(&self) -> String {
match self {
Self::Isolated => "isolated",
Self::Python => "python",
}
.to_string()
}
}
impl TryFrom<&str> for PythonInterpreterProfile {
type Error = String;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"isolated" => Ok(Self::Isolated),
"python" => Ok(Self::Python),
_ => Err(format!(
"{} is not a valid profile; use 'isolated' or 'python'",
value
)),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum PythonRunMode {
None,
Repl,
Module { module: String },
Eval { code: String },
File { path: PathBuf },
}
impl ToString for PythonRunMode {
fn to_string(&self) -> String {
match self {
Self::None => "none".to_string(),
Self::Repl => "repl".to_string(),
Self::Module { module } => format!("module:{}", module),
Self::Eval { code } => format!("eval:{}", code),
Self::File { path } => format!("file:{}", path.display()),
}
}
}
impl TryFrom<&str> for PythonRunMode {
type Error = String;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"none" => Ok(Self::None),
"repl" => Ok(Self::Repl),
value => {
let parts = value.splitn(2, ":").collect::<Vec<_>>();
if parts.len() != 2 {
return Err(format!("{} is not a valid Python run mode", value));
}
let prefix = parts[0];
let suffix = parts[1];
match prefix {
"module" => Ok(Self::Module {
module: suffix.to_string(),
}),
"eval" => Ok(Self::Eval {
code: suffix.to_string(),
}),
"file" => Ok(Self::File {
path: PathBuf::from(suffix),
}),
_ => Err(format!("{} is not a valid Python run mode", value)),
}
}
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum TerminfoResolution {
Dynamic,
None,
Static(String),
}
impl ToString for TerminfoResolution {
fn to_string(&self) -> String {
match self {
Self::Dynamic => "dynamic".to_string(),
Self::None => "none".to_string(),
Self::Static(value) => format!("static:{}", value),
}
}
}
impl TryFrom<&str> for TerminfoResolution {
type Error = String;
fn try_from(value: &str) -> Result<Self, Self::Error> {
if value == "dynamic" {
Ok(Self::Dynamic)
} else if value == "none" {
Ok(Self::None)
} else if value.starts_with("static:") {
let suffix = &value[7..];
Ok(Self::Static(suffix.to_string()))
} else {
Err(format!(
"{} is not a valid terminfo resolution value",
value
))
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum MemoryAllocatorBackend {
System,
Jemalloc,
Rust,
}
impl ToString for MemoryAllocatorBackend {
fn to_string(&self) -> String {
match self {
Self::System => "system",
Self::Jemalloc => "jemalloc",
Self::Rust => "rust",
}
.to_string()
}
}
impl TryFrom<&str> for MemoryAllocatorBackend {
type Error = String;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"system" => Ok(Self::System),
"jemalloc" => Ok(Self::Jemalloc),
"rust" => Ok(Self::Rust),
_ => Err(format!("{} is not a valid memory allocator backend", value)),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct PythonRawAllocator {
pub backend: MemoryAllocatorBackend,
pub debug: bool,
}
impl PythonRawAllocator {
pub fn system() -> Self {
Self {
backend: MemoryAllocatorBackend::System,
..PythonRawAllocator::default()
}
}
pub fn jemalloc() -> Self {
Self {
backend: MemoryAllocatorBackend::Jemalloc,
..PythonRawAllocator::default()
}
}
pub fn rust() -> Self {
Self {
backend: MemoryAllocatorBackend::Rust,
..PythonRawAllocator::default()
}
}
}
impl Default for PythonRawAllocator {
fn default() -> Self {
Self {
backend: if cfg!(windows) {
MemoryAllocatorBackend::System
} else {
MemoryAllocatorBackend::Jemalloc
},
debug: false,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum CoerceCLocale {
LCCtype = 1,
C = 2,
}
impl ToString for CoerceCLocale {
fn to_string(&self) -> String {
match self {
Self::LCCtype => "LC_CTYPE",
Self::C => "C",
}
.to_string()
}
}
impl TryFrom<&str> for CoerceCLocale {
type Error = String;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"LC_CTYPE" => Ok(Self::LCCtype),
"C" => Ok(Self::C),
_ => Err(format!("{} is not a valid C locale coercion value", value)),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum BytesWarning {
None = 0,
Warn = 1,
Raise = 2,
}
impl ToString for BytesWarning {
fn to_string(&self) -> String {
match self {
Self::None => "none",
Self::Warn => "warn",
Self::Raise => "raise",
}
.to_string()
}
}
impl TryFrom<&str> for BytesWarning {
type Error = String;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"none" => Ok(Self::None),
"warn" => Ok(Self::Warn),
"raise" => Ok(Self::Raise),
_ => Err(format!("{} is not a valid bytes warning value", value)),
}
}
}
impl From<i32> for BytesWarning {
fn from(value: i32) -> BytesWarning {
match value {
0 => Self::None,
1 => Self::Warn,
_ => Self::Raise,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum CheckHashPYCsMode {
Always,
Never,
Default,
}
impl ToString for CheckHashPYCsMode {
fn to_string(&self) -> String {
match self {
Self::Always => "always",
Self::Never => "never",
Self::Default => "default",
}
.to_string()
}
}
impl TryFrom<&str> for CheckHashPYCsMode {
type Error = String;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"always" => Ok(Self::Always),
"never" => Ok(Self::Never),
"default" => Ok(Self::Default),
_ => Err(format!(
"{} is not a valid check hash pycs mode value",
value
)),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Allocator {
NotSet = 0,
Default = 1,
Debug = 2,
Malloc = 3,
MallocDebug = 4,
PyMalloc = 5,
PyMallocDebug = 6,
}
impl ToString for Allocator {
fn to_string(&self) -> String {
match self {
Self::NotSet => "not-set",
Self::Default => "default",
Self::Debug => "debug",
Self::Malloc => "malloc",
Self::MallocDebug => "malloc-debug",
Self::PyMalloc => "py-malloc",
Self::PyMallocDebug => "py-malloc-debug",
}
.to_string()
}
}
impl TryFrom<&str> for Allocator {
type Error = String;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"not-set" => Ok(Self::NotSet),
"default" => Ok(Self::Default),
"debug" => Ok(Self::Debug),
"malloc" => Ok(Self::Malloc),
"malloc-debug" => Ok(Self::MallocDebug),
"py-malloc" => Ok(Self::PyMalloc),
"py-malloc-debug" => Ok(Self::PyMallocDebug),
_ => Err(format!("{} is not a valid allocator value", value)),
}
}
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct PythonInterpreterConfig {
pub profile: PythonInterpreterProfile,
pub allocator: Option<Allocator>,
pub configure_locale: Option<bool>,
pub coerce_c_locale: Option<CoerceCLocale>,
pub coerce_c_locale_warn: Option<bool>,
pub development_mode: Option<bool>,
pub isolated: Option<bool>,
pub legacy_windows_fs_encoding: Option<bool>,
pub parse_argv: Option<bool>,
pub use_environment: Option<bool>,
pub utf8_mode: Option<bool>,
pub argv: Option<Vec<OsString>>,
pub base_exec_prefix: Option<PathBuf>,
pub base_executable: Option<PathBuf>,
pub base_prefix: Option<PathBuf>,
pub buffered_stdio: Option<bool>,
pub bytes_warning: Option<BytesWarning>,
pub check_hash_pycs_mode: Option<CheckHashPYCsMode>,
pub configure_c_stdio: Option<bool>,
pub dump_refs: Option<bool>,
pub exec_prefix: Option<PathBuf>,
pub executable: Option<PathBuf>,
pub fault_handler: Option<bool>,
pub filesystem_encoding: Option<String>,
pub filesystem_errors: Option<String>,
pub hash_seed: Option<c_ulong>,
pub home: Option<PathBuf>,
pub import_time: Option<bool>,
pub inspect: Option<bool>,
pub install_signal_handlers: Option<bool>,
pub interactive: Option<bool>,
pub legacy_windows_stdio: Option<bool>,
pub malloc_stats: Option<bool>,
pub module_search_paths: Option<Vec<PathBuf>>,
pub optimization_level: Option<BytecodeOptimizationLevel>,
pub parser_debug: Option<bool>,
pub pathconfig_warnings: Option<bool>,
pub prefix: Option<PathBuf>,
pub program_name: Option<PathBuf>,
pub pycache_prefix: Option<PathBuf>,
pub python_path_env: Option<String>,
pub quiet: Option<bool>,
pub run_command: Option<String>,
pub run_filename: Option<PathBuf>,
pub run_module: Option<String>,
pub show_alloc_count: Option<bool>,
pub show_ref_count: Option<bool>,
pub site_import: Option<bool>,
pub skip_first_source_line: Option<bool>,
pub stdio_encoding: Option<String>,
pub stdio_errors: Option<String>,
pub tracemalloc: Option<bool>,
pub user_site_directory: Option<bool>,
pub verbose: Option<bool>,
pub warn_options: Option<Vec<String>>,
pub write_bytecode: Option<bool>,
pub x_options: Option<Vec<String>>,
}