Skip to main content

rustpython_vm/vm/
setting.rs

1use core::num::NonZeroI32;
2#[cfg(feature = "flame-it")]
3use std::ffi::OsString;
4
5/// Path configuration computed at runtime (like PyConfig path outputs)
6#[derive(Debug, Clone, Default)]
7pub struct Paths {
8    /// sys.executable
9    pub executable: String,
10    /// sys._base_executable (original interpreter in venv)
11    pub base_executable: String,
12    /// sys.prefix
13    pub prefix: String,
14    /// sys.base_prefix
15    pub base_prefix: String,
16    /// sys.exec_prefix
17    pub exec_prefix: String,
18    /// sys.base_exec_prefix
19    pub base_exec_prefix: String,
20    /// sys._stdlib_dir
21    pub stdlib_dir: Option<String>,
22    /// Computed module_search_paths (complete sys.path)
23    pub module_search_paths: Vec<String>,
24}
25
26/// Combined configuration: user settings + computed paths
27/// CPython directly exposes every fields under both of them.
28/// We separate them to maintain better ownership discipline.
29#[derive(Clone)]
30pub struct PyConfig {
31    pub settings: Settings,
32    pub paths: Paths,
33}
34
35impl PyConfig {
36    #[must_use]
37    pub fn new(settings: Settings, paths: Paths) -> Self {
38        Self { settings, paths }
39    }
40}
41
42/// User-configurable settings for the python vm.
43#[non_exhaustive]
44#[derive(Clone)]
45pub struct Settings {
46    /// -I
47    pub isolated: bool,
48
49    // int use_environment
50    /// -Xdev
51    pub dev_mode: bool,
52
53    /// Not set SIGINT handler(i.e. for embedded mode)
54    pub install_signal_handlers: bool,
55
56    /// PYTHONHASHSEED=x
57    /// None means use_hash_seed = 0 in CPython
58    pub hash_seed: Option<u32>,
59
60    /// -X faulthandler, PYTHONFAULTHANDLER
61    pub faulthandler: bool,
62
63    // int tracemalloc;
64    // int perf_profiling;
65    // int import_time;
66    /// -X no_debug_ranges: disable column info in bytecode
67    pub code_debug_ranges: bool,
68    // int show_ref_count;
69    // int dump_refs;
70    // wchar_t *dump_refs_file;
71    // int malloc_stats;
72    // wchar_t *filesystem_encoding;
73    // wchar_t *filesystem_errors;
74    // wchar_t *pycache_prefix;
75    // int parse_argv;
76    // PyWideStringList orig_argv;
77    /// sys.argv
78    pub argv: Vec<String>,
79
80    // spell-checker:ignore Xfoo
81    /// -Xfoo[=bar]
82    pub xoptions: Vec<(String, Option<String>)>,
83
84    // spell-checker:ignore Wfoo
85    /// -Wfoo
86    pub warnoptions: Vec<String>,
87
88    /// -S
89    pub import_site: bool,
90
91    /// -b
92    pub bytes_warning: u64,
93
94    /// -X warn_default_encoding, PYTHONWARNDEFAULTENCODING
95    pub warn_default_encoding: bool,
96
97    /// -X thread_inherit_context, whether new threads inherit context from parent
98    pub thread_inherit_context: bool,
99
100    /// -X context_aware_warnings, whether warnings are context aware
101    pub context_aware_warnings: bool,
102
103    /// -i
104    pub inspect: bool,
105
106    /// -i, with no script
107    pub interactive: bool,
108
109    // int optimization_level;
110    // int parser_debug;
111    /// -B
112    pub write_bytecode: bool,
113
114    /// verbosity level (-v switch)
115    pub verbose: u8,
116
117    /// -q
118    pub quiet: bool,
119
120    /// -s
121    pub user_site_directory: bool,
122
123    // int configure_c_stdio;
124    /// -u, PYTHONUNBUFFERED=x
125    pub buffered_stdio: bool,
126
127    /// PYTHONIOENCODING - stdio encoding
128    pub stdio_encoding: Option<String>,
129    /// PYTHONIOENCODING - stdio error handler
130    pub stdio_errors: Option<String>,
131    pub utf8_mode: i8,
132    /// --check-hash-based-pycs
133    pub check_hash_pycs_mode: CheckHashPycsMode,
134
135    // int use_frozen_modules;
136    /// -P
137    pub safe_path: bool,
138
139    /// -X int_max_str_digits
140    pub int_max_str_digits: i64,
141
142    /// `-X cpu_count` / `PYTHON_CPU_COUNT` override; `None` leaves the count to the host
143    pub cpu_count: Option<NonZeroI32>,
144
145    // /* --- Path configuration inputs ------------ */
146    // int pathconfig_warnings;
147    // wchar_t *program_name;
148    /// Environment PYTHONPATH (and RUSTPYTHONPATH)
149    pub path_list: Vec<String>,
150
151    // wchar_t *home;
152    // wchar_t *platlibdir;
153    /// -d command line switch
154    pub debug: u8,
155
156    /// -O optimization switch counter
157    pub optimize: u8,
158
159    /// -E
160    pub ignore_environment: bool,
161
162    /// false for wasm. Not a command-line option
163    pub allow_external_library: bool,
164
165    #[cfg(feature = "flame-it")]
166    pub profile_output: Option<OsString>,
167    #[cfg(feature = "flame-it")]
168    pub profile_format: Option<String>,
169}
170
171#[derive(Debug, Default, Copy, Clone, strum_macros::Display, strum_macros::EnumString)]
172#[strum(serialize_all = "lowercase")]
173pub enum CheckHashPycsMode {
174    #[default]
175    Default,
176    Always,
177    Never,
178}
179
180impl Settings {
181    #[must_use]
182    pub fn with_path(mut self, path: String) -> Self {
183        self.path_list.push(path);
184        self
185    }
186}
187
188/// Sensible default settings.
189impl Default for Settings {
190    fn default() -> Self {
191        Self {
192            debug: 0,
193            inspect: false,
194            interactive: false,
195            optimize: 0,
196            install_signal_handlers: true,
197            user_site_directory: true,
198            import_site: true,
199            ignore_environment: false,
200            verbose: 0,
201            quiet: false,
202            write_bytecode: true,
203            safe_path: false,
204            bytes_warning: 0,
205            xoptions: vec![],
206            isolated: false,
207            dev_mode: false,
208            warn_default_encoding: false,
209            thread_inherit_context: false,
210            context_aware_warnings: false,
211            warnoptions: vec![],
212            path_list: vec![],
213            argv: vec![],
214            hash_seed: None,
215            faulthandler: false,
216            code_debug_ranges: true,
217            buffered_stdio: true,
218            check_hash_pycs_mode: CheckHashPycsMode::Default,
219            allow_external_library: cfg!(feature = "importlib"),
220            stdio_encoding: None,
221            stdio_errors: None,
222            utf8_mode: -1,
223            int_max_str_digits: 4300,
224            cpu_count: None,
225            #[cfg(feature = "flame-it")]
226            profile_output: None,
227            #[cfg(feature = "flame-it")]
228            profile_format: None,
229        }
230    }
231}