python_packaging/interpreter.rs
1// Copyright 2022 Gregory Szorc.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9/*! Functionality related to running Python interpreters. */
10
11use {
12 crate::resource::BytecodeOptimizationLevel,
13 std::{ffi::OsString, os::raw::c_ulong, path::PathBuf, str::FromStr},
14};
15
16#[cfg(feature = "serialization")]
17use serde::{Deserialize, Serialize};
18
19/// Defines the profile to use to configure a Python interpreter.
20///
21/// This effectively provides a template for seeding the initial values of
22/// `PyPreConfig` and `PyConfig` C structs.
23///
24/// Serialization type: `string`.
25#[derive(Clone, Copy, Debug, PartialEq, Eq)]
26#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
27#[cfg_attr(feature = "serialization", serde(try_from = "String", into = "String"))]
28pub enum PythonInterpreterProfile {
29 /// Python is isolated from the system.
30 ///
31 /// See <https://docs.python.org/3/c-api/init_config.html#isolated-configuration>.
32 ///
33 /// Serialized value: `isolated`
34 Isolated,
35
36 /// Python interpreter behaves like `python`.
37 ///
38 /// See <https://docs.python.org/3/c-api/init_config.html#python-configuration>.
39 ///
40 /// Serialized value: `python`
41 Python,
42}
43
44impl Default for PythonInterpreterProfile {
45 fn default() -> Self {
46 PythonInterpreterProfile::Isolated
47 }
48}
49
50impl ToString for PythonInterpreterProfile {
51 fn to_string(&self) -> String {
52 match self {
53 Self::Isolated => "isolated",
54 Self::Python => "python",
55 }
56 .to_string()
57 }
58}
59
60impl From<PythonInterpreterProfile> for String {
61 fn from(v: PythonInterpreterProfile) -> Self {
62 v.to_string()
63 }
64}
65
66impl TryFrom<&str> for PythonInterpreterProfile {
67 type Error = String;
68
69 fn try_from(value: &str) -> Result<Self, Self::Error> {
70 match value {
71 "isolated" => Ok(Self::Isolated),
72 "python" => Ok(Self::Python),
73 _ => Err(format!(
74 "{} is not a valid profile; use 'isolated' or 'python'",
75 value
76 )),
77 }
78 }
79}
80
81impl TryFrom<String> for PythonInterpreterProfile {
82 type Error = String;
83
84 fn try_from(value: String) -> Result<Self, Self::Error> {
85 Self::try_from(value.as_str())
86 }
87}
88
89/// Defines `terminfo` database resolution semantics.
90///
91/// Python links against libraries like `readline`, `libedit`, and `ncurses`
92/// which need to utilize a `terminfo` database (a set of files defining
93/// terminals and their capabilities) in order to work properly.
94///
95/// The absolute path to the terminfo database is typically compiled into these
96/// libraries at build time. If the compiled path on the building machine doesn't
97/// match the path on the runtime machine, these libraries cannot find the terminfo
98/// database and terminal interactions won't work correctly because these libraries
99/// don't know how to resolve terminal features. This can result in quirks like
100/// the backspace key not working in prompts.
101///
102/// The `pyembed` Rust crate is able to point libraries at a terminfo database
103/// at runtime, overriding the compiled-in default path. This enum is used
104/// to control that behavior.
105///
106/// Serialization type: `string`.
107#[derive(Clone, Debug, PartialEq, Eq)]
108#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
109#[cfg_attr(feature = "serialization", serde(try_from = "String", into = "String"))]
110pub enum TerminfoResolution {
111 /// Resolve `terminfo` database using appropriate behavior for current OS.
112 ///
113 /// We will look for the terminfo database in paths that are common for the
114 /// current OS / distribution. The terminfo database is present in most systems
115 /// (except the most barebones containers or sandboxes) and this method is
116 /// usually successfully in locating the terminfo database.
117 ///
118 /// Serialized value: `dynamic`
119 Dynamic,
120
121 /// Do not attempt to resolve the `terminfo` database. Basically a no-op.
122 ///
123 /// This is what should be used for applications that don't interact with the
124 /// terminal. Using this option will prevent some I/O syscalls that would
125 /// be incurred by `dynamic`.
126 ///
127 /// Serialized value: `none`
128 None,
129
130 /// Use a specified string as the `TERMINFO_DIRS` value.
131 ///
132 /// Serialized value: `static:<path>`
133 ///
134 /// e.g. `static:/usr/share/terminfo`.
135 Static(String),
136}
137
138impl ToString for TerminfoResolution {
139 fn to_string(&self) -> String {
140 match self {
141 Self::Dynamic => "dynamic".to_string(),
142 Self::None => "none".to_string(),
143 Self::Static(value) => format!("static:{}", value),
144 }
145 }
146}
147
148impl From<TerminfoResolution> for String {
149 fn from(t: TerminfoResolution) -> Self {
150 t.to_string()
151 }
152}
153
154impl TryFrom<&str> for TerminfoResolution {
155 type Error = String;
156
157 fn try_from(value: &str) -> Result<Self, Self::Error> {
158 if value == "dynamic" {
159 Ok(Self::Dynamic)
160 } else if value == "none" {
161 Ok(Self::None)
162 } else if let Some(suffix) = value.strip_prefix("static:") {
163 Ok(Self::Static(suffix.to_string()))
164 } else {
165 Err(format!(
166 "{} is not a valid terminfo resolution value",
167 value
168 ))
169 }
170 }
171}
172
173impl TryFrom<String> for TerminfoResolution {
174 type Error = String;
175
176 fn try_from(value: String) -> Result<Self, Self::Error> {
177 Self::try_from(value.as_str())
178 }
179}
180
181/// Defines a backend for a memory allocator.
182///
183/// This says which memory allocator API / library to configure the Python
184/// interpreter to use.
185///
186/// Not all allocators are available in all program builds.
187///
188/// Serialization type: `string`
189#[derive(Clone, Copy, Debug, PartialEq, Eq)]
190#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
191#[cfg_attr(feature = "serialization", serde(try_from = "String", into = "String"))]
192pub enum MemoryAllocatorBackend {
193 /// The default allocator as configured by Python.
194 ///
195 /// This likely utilizes the system default allocator, normally the
196 /// `malloc()`, `free()`, etc functions from the libc implementation being
197 /// linked against.
198 ///
199 /// Serialized value: `default`
200 Default,
201
202 /// Use the jemalloc allocator.
203 ///
204 /// Requires the binary to be built with jemalloc support.
205 ///
206 /// Never available on Windows.
207 ///
208 /// Serialized value: `jemalloc`
209 Jemalloc,
210
211 /// Use the mimalloc allocator (<https://github.com/microsoft/mimalloc>).
212 ///
213 /// Requires the binary to be built with mimalloc support.
214 ///
215 /// Serialized value: `mimalloc`
216 Mimalloc,
217
218 /// Use the snmalloc allocator (<https://github.com/microsoft/snmalloc>).
219 ///
220 /// Not always available.
221 ///
222 /// Serialized value: `snmalloc`
223 Snmalloc,
224
225 /// Use Rust's global allocator.
226 ///
227 /// The Rust allocator is less efficient than other allocators because of
228 /// overhead tracking allocations. For optimal performance, use the default
229 /// allocator. Or if Rust is using a custom global allocator, use the enum
230 /// variant corresponding to that allocator.
231 ///
232 /// Serialized value: `rust`
233 Rust,
234}
235
236impl Default for MemoryAllocatorBackend {
237 fn default() -> Self {
238 if cfg!(windows) {
239 Self::Default
240 } else {
241 Self::Jemalloc
242 }
243 }
244}
245
246impl ToString for MemoryAllocatorBackend {
247 fn to_string(&self) -> String {
248 match self {
249 Self::Default => "default",
250 Self::Jemalloc => "jemalloc",
251 Self::Mimalloc => "mimalloc",
252 Self::Snmalloc => "snmalloc",
253 Self::Rust => "rust",
254 }
255 .to_string()
256 }
257}
258
259impl From<MemoryAllocatorBackend> for String {
260 fn from(v: MemoryAllocatorBackend) -> Self {
261 v.to_string()
262 }
263}
264
265impl TryFrom<&str> for MemoryAllocatorBackend {
266 type Error = String;
267
268 fn try_from(value: &str) -> Result<Self, Self::Error> {
269 match value {
270 "default" => Ok(Self::Default),
271 "jemalloc" => Ok(Self::Jemalloc),
272 "mimalloc" => Ok(Self::Mimalloc),
273 "snmalloc" => Ok(Self::Snmalloc),
274 "rust" => Ok(Self::Rust),
275 _ => Err(format!("{} is not a valid memory allocator backend", value)),
276 }
277 }
278}
279
280impl TryFrom<String> for MemoryAllocatorBackend {
281 type Error = String;
282
283 fn try_from(value: String) -> Result<Self, Self::Error> {
284 Self::try_from(value.as_str())
285 }
286}
287
288/// Holds values for `coerce_c_locale`.
289///
290/// See <https://docs.python.org/3/c-api/init_config.html#c.PyPreConfig.coerce_c_locale>.
291///
292/// Serialization type: `string`
293#[derive(Clone, Copy, Debug, PartialEq, Eq)]
294#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
295#[cfg_attr(feature = "serialization", serde(try_from = "String", into = "String"))]
296pub enum CoerceCLocale {
297 /// Read the LC_CTYPE locale to decide if it should be coerced.
298 ///
299 /// Serialized value: `LC_CTYPE`
300 #[allow(clippy::upper_case_acronyms)]
301 LCCtype = 1,
302
303 /// Coerce the C locale.
304 ///
305 /// Serialized value: `C`
306 C = 2,
307}
308
309impl ToString for CoerceCLocale {
310 fn to_string(&self) -> String {
311 match self {
312 Self::LCCtype => "LC_CTYPE",
313 Self::C => "C",
314 }
315 .to_string()
316 }
317}
318
319impl From<CoerceCLocale> for String {
320 fn from(v: CoerceCLocale) -> Self {
321 v.to_string()
322 }
323}
324
325impl TryFrom<&str> for CoerceCLocale {
326 type Error = String;
327
328 fn try_from(value: &str) -> Result<Self, Self::Error> {
329 match value {
330 "LC_CTYPE" => Ok(Self::LCCtype),
331 "C" => Ok(Self::C),
332 _ => Err(format!("{} is not a valid C locale coercion value", value)),
333 }
334 }
335}
336
337impl TryFrom<String> for CoerceCLocale {
338 type Error = String;
339
340 fn try_from(value: String) -> Result<Self, Self::Error> {
341 Self::try_from(value.as_str())
342 }
343}
344
345/// Defines what to do when comparing `bytes` or `bytesarray` with `str` or comparing `bytes` with `int`.
346///
347/// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.bytes_warning>.
348///
349/// Serialization type: `string`
350#[derive(Clone, Copy, Debug, PartialEq, Eq)]
351#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
352#[cfg_attr(feature = "serialization", serde(try_from = "String", into = "String"))]
353pub enum BytesWarning {
354 /// Do nothing.
355 ///
356 /// Serialization value: `none`
357 None = 0,
358
359 /// Issue a warning.
360 ///
361 /// Serialization value: `warn`
362 Warn = 1,
363
364 /// Raise a `BytesWarning`.
365 ///
366 /// Serialization value: `raise`
367 Raise = 2,
368}
369
370impl ToString for BytesWarning {
371 fn to_string(&self) -> String {
372 match self {
373 Self::None => "none",
374 Self::Warn => "warn",
375 Self::Raise => "raise",
376 }
377 .to_string()
378 }
379}
380
381impl From<BytesWarning> for String {
382 fn from(v: BytesWarning) -> Self {
383 v.to_string()
384 }
385}
386
387impl TryFrom<&str> for BytesWarning {
388 type Error = String;
389
390 fn try_from(value: &str) -> Result<Self, Self::Error> {
391 match value {
392 "none" => Ok(Self::None),
393 "warn" => Ok(Self::Warn),
394 "raise" => Ok(Self::Raise),
395 _ => Err(format!("{} is not a valid bytes warning value", value)),
396 }
397 }
398}
399
400impl TryFrom<String> for BytesWarning {
401 type Error = String;
402
403 fn try_from(value: String) -> Result<Self, Self::Error> {
404 Self::try_from(value.as_str())
405 }
406}
407
408impl From<i32> for BytesWarning {
409 fn from(value: i32) -> BytesWarning {
410 match value {
411 0 => Self::None,
412 1 => Self::Warn,
413 _ => Self::Raise,
414 }
415 }
416}
417
418/// Control the validation behavior of hash-based .pyc files.
419///
420/// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.check_hash_pycs_mode>.
421///
422/// Serialization type: `string`
423#[derive(Clone, Copy, Debug, PartialEq, Eq)]
424#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
425#[cfg_attr(feature = "serialization", serde(try_from = "String", into = "String"))]
426pub enum CheckHashPycsMode {
427 /// Hash the source file for invalidation regardless of value of the `check_source` flag.
428 ///
429 /// Serialized value: `always`
430 Always,
431
432 /// Assume that hash-based pycs always are valid.
433 ///
434 /// Serialized value: `never`
435 Never,
436
437 /// The `check_source` flag in hash-based pycs determines invalidation.
438 ///
439 /// Serialized value: `default`
440 Default,
441}
442
443impl ToString for CheckHashPycsMode {
444 fn to_string(&self) -> String {
445 match self {
446 Self::Always => "always",
447 Self::Never => "never",
448 Self::Default => "default",
449 }
450 .to_string()
451 }
452}
453
454impl From<CheckHashPycsMode> for String {
455 fn from(v: CheckHashPycsMode) -> Self {
456 v.to_string()
457 }
458}
459
460impl TryFrom<&str> for CheckHashPycsMode {
461 type Error = String;
462
463 fn try_from(value: &str) -> Result<Self, Self::Error> {
464 match value {
465 "always" => Ok(Self::Always),
466 "never" => Ok(Self::Never),
467 "default" => Ok(Self::Default),
468 _ => Err(format!(
469 "{} is not a valid check hash pycs mode value",
470 value
471 )),
472 }
473 }
474}
475
476impl TryFrom<String> for CheckHashPycsMode {
477 type Error = String;
478
479 fn try_from(value: String) -> Result<Self, Self::Error> {
480 Self::try_from(value.as_str())
481 }
482}
483
484/// Name of the Python memory allocators.
485///
486/// See <https://docs.python.org/3/c-api/init_config.html#c.PyPreConfig.allocator>.
487///
488/// Serialization type: `string`
489#[derive(Clone, Copy, Debug, PartialEq, Eq)]
490#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
491#[cfg_attr(feature = "serialization", serde(try_from = "String", into = "String"))]
492pub enum Allocator {
493 /// Don’t change memory allocators (use defaults).
494 ///
495 /// Serialized value: `not-set`
496 NotSet = 0,
497
498 /// Default memory allocators.
499 ///
500 /// Serialized value: `default`
501 Default = 1,
502
503 /// Default memory allocators with debug hooks.
504 ///
505 /// Serialized value: `debug`
506 Debug = 2,
507
508 /// Use `malloc()` from the C library.
509 ///
510 /// Serialized value: `malloc`
511 Malloc = 3,
512
513 /// Force usage of `malloc()` with debug hooks.
514 ///
515 /// Serialized value: `malloc-debug`
516 MallocDebug = 4,
517
518 /// Python `pymalloc` allocator.
519 ///
520 /// Serialized value: `py-malloc`
521 PyMalloc = 5,
522
523 /// Python `pymalloc` allocator with debug hooks.
524 ///
525 /// Serialized value: `py-malloc-debug`
526 PyMallocDebug = 6,
527}
528
529impl ToString for Allocator {
530 fn to_string(&self) -> String {
531 match self {
532 Self::NotSet => "not-set",
533 Self::Default => "default",
534 Self::Debug => "debug",
535 Self::Malloc => "malloc",
536 Self::MallocDebug => "malloc-debug",
537 Self::PyMalloc => "py-malloc",
538 Self::PyMallocDebug => "py-malloc-debug",
539 }
540 .to_string()
541 }
542}
543
544impl From<Allocator> for String {
545 fn from(v: Allocator) -> Self {
546 v.to_string()
547 }
548}
549
550impl TryFrom<&str> for Allocator {
551 type Error = String;
552
553 fn try_from(value: &str) -> Result<Self, Self::Error> {
554 match value {
555 "not-set" => Ok(Self::NotSet),
556 "default" => Ok(Self::Default),
557 "debug" => Ok(Self::Debug),
558 "malloc" => Ok(Self::Malloc),
559 "malloc-debug" => Ok(Self::MallocDebug),
560 "py-malloc" => Ok(Self::PyMalloc),
561 "py-malloc-debug" => Ok(Self::PyMallocDebug),
562 _ => Err(format!("{} is not a valid allocator value", value)),
563 }
564 }
565}
566
567impl TryFrom<String> for Allocator {
568 type Error = String;
569
570 fn try_from(value: String) -> Result<Self, Self::Error> {
571 Self::try_from(value.as_str())
572 }
573}
574
575/// Defines how to call `multiprocessing.set_start_method()` when `multiprocessing` is imported.
576///
577/// When set to a value that is not `none`, when `oxidized_importer.OxidizedFinder` services
578/// an import of the `multiprocessing` module, it will automatically call
579/// `multiprocessing.set_start_method()` to configure how worker processes are created.
580///
581/// If the `multiprocessing` module is not imported by `oxidized_importer.OxidizedFinder`,
582/// this setting has no effect.
583///
584/// Serialization type: `string`
585#[derive(Clone, Debug, PartialEq, Eq)]
586#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
587#[cfg_attr(feature = "serialization", serde(try_from = "String", into = "String"))]
588pub enum MultiprocessingStartMethod {
589 /// Do not call `multiprocessing.set_start_method()`.
590 ///
591 /// This mode is what Python programs do by default.
592 ///
593 /// Serialized value: `none`
594 None,
595
596 /// Call with value `fork`.
597 ///
598 /// Serialized value: `fork`
599 Fork,
600
601 /// Call with value `forkserver`
602 ///
603 /// Serialized value: `forkserver`
604 ForkServer,
605
606 /// Call with value `spawn`
607 ///
608 /// Serialized value: `spawn`
609 Spawn,
610
611 /// Call with a valid appropriate for the given environment.
612 ///
613 /// This likely maps to `spawn` on Windows and `fork` on non-Windows.
614 ///
615 /// Serialized value: `auto`
616 Auto,
617}
618
619impl ToString for MultiprocessingStartMethod {
620 fn to_string(&self) -> String {
621 match self {
622 Self::None => "none",
623 Self::Fork => "fork",
624 Self::ForkServer => "forkserver",
625 Self::Spawn => "spawn",
626 Self::Auto => "auto",
627 }
628 .to_string()
629 }
630}
631
632impl From<MultiprocessingStartMethod> for String {
633 fn from(v: MultiprocessingStartMethod) -> Self {
634 v.to_string()
635 }
636}
637
638impl FromStr for MultiprocessingStartMethod {
639 type Err = String;
640
641 fn from_str(s: &str) -> Result<Self, Self::Err> {
642 match s {
643 "none" => Ok(Self::None),
644 "fork" => Ok(Self::Fork),
645 "forkserver" => Ok(Self::ForkServer),
646 "spawn" => Ok(Self::Spawn),
647 "auto" => Ok(Self::Auto),
648 _ => Err(format!("{} is not a valid multiprocessing start method", s)),
649 }
650 }
651}
652
653impl TryFrom<&str> for MultiprocessingStartMethod {
654 type Error = String;
655
656 fn try_from(v: &str) -> Result<Self, Self::Error> {
657 Self::from_str(v)
658 }
659}
660
661impl TryFrom<String> for MultiprocessingStartMethod {
662 type Error = String;
663
664 fn try_from(value: String) -> Result<Self, Self::Error> {
665 Self::try_from(value.as_str())
666 }
667}
668
669/// Holds configuration of a Python interpreter.
670///
671/// This struct holds fields that are exposed by `PyPreConfig` and
672/// `PyConfig` in the CPython API.
673///
674/// Other than the profile (which is used to initialize instances of
675/// `PyPreConfig` and `PyConfig`), all fields are optional. Only fields
676/// with `Some(T)` will be updated from the defaults.
677#[derive(Clone, Debug, Default, PartialEq, Eq)]
678#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
679#[cfg_attr(feature = "serialization", serde(default))]
680pub struct PythonInterpreterConfig {
681 /// Profile to use to initialize pre-config and config state of interpreter.
682 pub profile: PythonInterpreterProfile,
683
684 // The following fields are from PyPreConfig or are shared with PyConfig.
685 /// Name of the memory allocator.
686 ///
687 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyPreConfig.allocator>.
688 pub allocator: Option<Allocator>,
689
690 /// Whether to set the LC_CTYPE locale to the user preferred locale.
691 ///
692 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyPreConfig.configure_locale>.
693 pub configure_locale: Option<bool>,
694
695 /// How to coerce the locale settings.
696 ///
697 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyPreConfig.coerce_c_locale>.
698 pub coerce_c_locale: Option<CoerceCLocale>,
699
700 /// Whether to emit a warning if the C locale is coerced.
701 ///
702 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyPreConfig.coerce_c_locale_warn>.
703 pub coerce_c_locale_warn: Option<bool>,
704
705 /// Whether to enable Python development mode.
706 ///
707 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.dev_mode>.
708 pub development_mode: Option<bool>,
709
710 /// Isolated mode.
711 ///
712 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyPreConfig.isolated>.
713 pub isolated: Option<bool>,
714
715 /// Whether to use legacy filesystem encodings on Windows.
716 ///
717 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyPreConfig.legacy_windows_fs_encoding>.
718 pub legacy_windows_fs_encoding: Option<bool>,
719
720 /// Whether argv should be parsed the way `python` parses them.
721 ///
722 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyPreConfig.parse_argv>.
723 pub parse_argv: Option<bool>,
724
725 /// Whether environment variables are read to control the interpreter configuration.
726 ///
727 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.use_environment>.
728 pub use_environment: Option<bool>,
729
730 /// Controls Python UTF-8 mode.
731 ///
732 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyPreConfig.utf8_mode>.
733 pub utf8_mode: Option<bool>,
734 // The following fields are from PyConfig.
735 /// Command line arguments.
736 ///
737 /// These will become `sys.argv`.
738 ///
739 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.argv>.
740 pub argv: Option<Vec<OsString>>,
741
742 /// Controls `sys.base_exec_prefix`.
743 ///
744 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.base_exec_prefix>.
745 pub base_exec_prefix: Option<PathBuf>,
746
747 /// Controls `sys._base_executable`.
748 ///
749 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.base_executable>.
750 pub base_executable: Option<PathBuf>,
751
752 /// Controls `sys.base_prefix`.
753 ///
754 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.base_prefix>.
755 pub base_prefix: Option<PathBuf>,
756
757 /// Controls buffering on `stdout` and `stderr`.
758 ///
759 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.buffered_stdio>.
760 pub buffered_stdio: Option<bool>,
761
762 /// Controls warnings/errors for some bytes type coercions.
763 ///
764 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.bytes_warning>.
765 pub bytes_warning: Option<BytesWarning>,
766
767 /// Validation mode for `.pyc` files.
768 ///
769 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.check_hash_pycs_mode>.
770 pub check_hash_pycs_mode: Option<CheckHashPycsMode>,
771
772 /// Controls binary mode and buffering on C standard streams.
773 ///
774 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.configure_c_stdio>.
775 pub configure_c_stdio: Option<bool>,
776
777 /// Dump Python references.
778 ///
779 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.dump_refs>.
780 pub dump_refs: Option<bool>,
781
782 /// Controls `sys.exec_prefix`.
783 ///
784 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.exec_prefix>.
785 pub exec_prefix: Option<PathBuf>,
786
787 /// Controls `sys.executable`.
788 ///
789 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.executable>.
790 pub executable: Option<PathBuf>,
791
792 /// Enable `faulthandler`.
793 ///
794 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.faulthandler>.
795 pub fault_handler: Option<bool>,
796
797 /// Controls the encoding to use for filesystems/paths.
798 ///
799 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.filesystem_encoding>.
800 pub filesystem_encoding: Option<String>,
801
802 /// Filesystem encoding error handler.
803 ///
804 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.filesystem_errors>.
805 pub filesystem_errors: Option<String>,
806
807 /// Randomized hash function seed.
808 ///
809 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.hash_seed>.
810 pub hash_seed: Option<c_ulong>,
811
812 /// Python home directory.
813 ///
814 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.home>.
815 pub home: Option<PathBuf>,
816
817 /// Whether to profile `import` time.
818 ///
819 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.import_time>.
820 pub import_time: Option<bool>,
821
822 /// Enter interactive mode after executing a script or a command.
823 ///
824 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.inspect>.
825 pub inspect: Option<bool>,
826
827 /// Whether to install Python signal handlers.
828 ///
829 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.install_signal_handlers>.
830 pub install_signal_handlers: Option<bool>,
831
832 /// Whether to enable the interactive REPL mode.
833 ///
834 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.interactive>.
835 pub interactive: Option<bool>,
836
837 /// Controls legacy stdio behavior on Windows.
838 ///
839 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.legacy_windows_stdio>.
840 pub legacy_windows_stdio: Option<bool>,
841
842 /// Whether to dump statistics from the `pymalloc` allocator on exit.
843 ///
844 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.malloc_stats>.
845 pub malloc_stats: Option<bool>,
846
847 /// Defines `sys.path`.
848 ///
849 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.module_search_paths>.
850 ///
851 /// This value effectively controls the initial value of `sys.path`.
852 ///
853 /// The special string `$ORIGIN` in values will be expanded to the absolute path of the
854 /// directory of the executable at run-time. For example, if the executable is
855 /// `/opt/my-application/pyapp`, `$ORIGIN` will expand to `/opt/my-application` and the
856 /// value `$ORIGIN/lib` will expand to `/opt/my-application/lib`.
857 pub module_search_paths: Option<Vec<PathBuf>>,
858
859 /// Bytecode optimization level.
860 ///
861 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.optimization_level>.
862 ///
863 /// This setting is only relevant if `write_bytecode` is true and Python modules are
864 /// being imported from the filesystem using Python’s standard filesystem importer.
865 pub optimization_level: Option<BytecodeOptimizationLevel>,
866
867 /// Parser debug mode.
868 ///
869 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.parser_debug>.
870 pub parser_debug: Option<bool>,
871
872 /// Whether calculating the Python path configuration can emit warnings.
873 ///
874 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.pathconfig_warnings>.
875 pub pathconfig_warnings: Option<bool>,
876
877 /// Defines `sys.prefix`.
878 ///
879 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.prefix>.
880 pub prefix: Option<PathBuf>,
881
882 /// Program named used to initialize state during path configuration.
883 ///
884 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.program_name>.
885 pub program_name: Option<PathBuf>,
886
887 /// Directory where `.pyc` files are written.
888 ///
889 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.pycache_prefix>.
890 pub pycache_prefix: Option<PathBuf>,
891
892 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.pythonpath_env>.
893 pub python_path_env: Option<String>,
894
895 /// Quiet mode.
896 ///
897 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.quiet>.
898 pub quiet: Option<bool>,
899
900 /// Value of the `-c` command line option.
901 ///
902 /// Effectively defines Python code to evaluate in `Py_RunMain()`.
903 ///
904 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.run_command>.
905 pub run_command: Option<String>,
906
907 /// Filename passed on the command line.
908 ///
909 /// Effectively defines the Python file to run in `Py_RunMain()`.
910 ///
911 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.run_filename>.
912 pub run_filename: Option<PathBuf>,
913
914 /// Value of the `-m` command line option.
915 ///
916 /// Effectively defines the Python module to run as `__main__` in `Py_RunMain()`.
917 ///
918 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.run_module>.
919 pub run_module: Option<String>,
920
921 /// Whether to show the total reference count at exit.
922 ///
923 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.show_ref_count>.
924 pub show_ref_count: Option<bool>,
925
926 /// Whether to import the `site` module at startup.
927 ///
928 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.site_import>.
929 ///
930 /// The `site` module is typically not needed for standalone applications and disabling
931 /// it can reduce application startup time.
932 pub site_import: Option<bool>,
933
934 /// Whether to skip the first line of [Self::run_filename].
935 ///
936 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.skip_source_first_line>.
937 pub skip_first_source_line: Option<bool>,
938
939 /// Encoding of `sys.stdout`, `sys.stderr`, and `sys.stdin`.
940 ///
941 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.stdio_encoding>.
942 pub stdio_encoding: Option<String>,
943
944 /// Encoding error handler for `sys.stdout` and `sys.stdin`.
945 ///
946 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.stdio_errors>.
947 pub stdio_errors: Option<String>,
948
949 /// Whether to enable `tracemalloc`.
950 ///
951 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.tracemalloc>.
952 pub tracemalloc: Option<bool>,
953
954 /// Whether to add the user site directory to `sys.path`.
955 ///
956 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.user_site_directory>.
957 pub user_site_directory: Option<bool>,
958
959 /// Verbose mode.
960 ///
961 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.verbose>.
962 pub verbose: Option<bool>,
963
964 /// Options of the `warning` module to control behavior.
965 ///
966 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.warnoptions>.
967 pub warn_options: Option<Vec<String>>,
968
969 /// Controls `sys.dont_write_bytecode`.
970 ///
971 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.write_bytecode>.
972 pub write_bytecode: Option<bool>,
973
974 /// Values of the `-X` command line options / `sys._xoptions`.
975 ///
976 /// See <https://docs.python.org/3/c-api/init_config.html#c.PyConfig.xoptions>.
977 pub x_options: Option<Vec<String>>,
978}