1use {
6 super::util::ToValue,
7 crate::py_packaging::config::PyembedPythonInterpreterConfig,
8 python_packaging::{
9 interpreter::{
10 Allocator, BytesWarning, CheckHashPycsMode, CoerceCLocale, MemoryAllocatorBackend,
11 MultiprocessingStartMethod, PythonInterpreterProfile, TerminfoResolution,
12 },
13 resource::BytecodeOptimizationLevel,
14 },
15 starlark::values::{
16 error::{
17 RuntimeError, UnsupportedOperation, ValueError, INCORRECT_PARAMETER_TYPE_ERROR_CODE,
18 },
19 none::NoneType,
20 {Mutable, TypedValue, Value, ValueResult},
21 },
22 starlark_dialect_build_targets::{ToOptional, TryToOptional},
23 std::{
24 str::FromStr,
25 sync::{Arc, Mutex, MutexGuard},
26 },
27};
28
29impl ToValue for PythonInterpreterProfile {
30 fn to_value(&self) -> Value {
31 Value::from(self.to_string())
32 }
33}
34
35impl ToValue for TerminfoResolution {
36 fn to_value(&self) -> Value {
37 Value::from(self.to_string())
38 }
39}
40
41impl ToValue for Option<CoerceCLocale> {
42 fn to_value(&self) -> Value {
43 match self {
44 Some(value) => Value::from(value.to_string()),
45 None => Value::from(NoneType::None),
46 }
47 }
48}
49
50impl ToValue for Option<BytesWarning> {
51 fn to_value(&self) -> Value {
52 match self {
53 Some(value) => Value::from(value.to_string()),
54 None => Value::from(NoneType::None),
55 }
56 }
57}
58
59impl ToValue for Option<CheckHashPycsMode> {
60 fn to_value(&self) -> Value {
61 match self {
62 Some(value) => Value::from(value.to_string()),
63 None => Value::from(NoneType::None),
64 }
65 }
66}
67
68impl ToValue for Option<Allocator> {
69 fn to_value(&self) -> Value {
70 match self {
71 Some(value) => Value::from(value.to_string()),
72 None => Value::from(NoneType::None),
73 }
74 }
75}
76
77impl ToValue for Option<BytecodeOptimizationLevel> {
78 fn to_value(&self) -> Value {
79 match self {
80 Some(value) => Value::from(*value as i32),
81 None => Value::from(NoneType::None),
82 }
83 }
84}
85
86impl ToValue for MemoryAllocatorBackend {
87 fn to_value(&self) -> Value {
88 Value::from(self.to_string())
89 }
90}
91
92fn bytecode_optimization_level_try_to_optional(
93 v: Value,
94) -> Result<Option<BytecodeOptimizationLevel>, ValueError> {
95 if v.get_type() == "NoneType" {
96 Ok(None)
97 } else {
98 match v.to_int()? {
99 0 => Ok(Some(BytecodeOptimizationLevel::Zero)),
100 1 => Ok(Some(BytecodeOptimizationLevel::One)),
101 2 => Ok(Some(BytecodeOptimizationLevel::Two)),
102 _ => Err(ValueError::from(RuntimeError {
103 code: INCORRECT_PARAMETER_TYPE_ERROR_CODE,
104 message: "invalid Python bytecode integer value".to_string(),
105 label: "PythonInterpreterConfig.optimization_level".to_string(),
106 })),
107 }
108 }
109}
110
111#[derive(Debug, Clone)]
112pub struct PythonInterpreterConfigValue {
113 pub inner: Arc<Mutex<PyembedPythonInterpreterConfig>>,
114}
115
116impl PythonInterpreterConfigValue {
117 pub fn new(inner: PyembedPythonInterpreterConfig) -> Self {
118 Self {
119 inner: Arc::new(Mutex::new(inner)),
120 }
121 }
122
123 pub fn inner(
124 &self,
125 label: &str,
126 ) -> Result<MutexGuard<PyembedPythonInterpreterConfig>, ValueError> {
127 self.inner.try_lock().map_err(|e| {
128 ValueError::Runtime(RuntimeError {
129 code: "PYTHON_INTERPRETER_CONFIG",
130 message: format!("error obtaining lock: {}", e),
131 label: label.to_string(),
132 })
133 })
134 }
135}
136
137impl TypedValue for PythonInterpreterConfigValue {
138 type Holder = Mutable<PythonInterpreterConfigValue>;
139 const TYPE: &'static str = "PythonInterpreterConfig";
140
141 fn values_for_descendant_check_and_freeze(&self) -> Box<dyn Iterator<Item = Value>> {
142 Box::new(std::iter::empty())
143 }
144
145 fn to_str(&self) -> String {
146 format!("PythonInterpreterConfig<{:#?}>", self.inner)
147 }
148
149 fn to_repr(&self) -> String {
150 self.to_str()
151 }
152
153 fn get_attr(&self, attribute: &str) -> ValueResult {
154 let inner = self.inner(&format!("PythonInterpreterConfig.{}", attribute))?;
155
156 let v = match attribute {
157 "config_profile" => inner.config.profile.to_value(),
158 "allocator" => inner.config.allocator.to_value(),
159 "configure_locale" => inner.config.configure_locale.to_value(),
160 "coerce_c_locale" => inner.config.coerce_c_locale.to_value(),
161 "coerce_c_locale_warn" => inner.config.coerce_c_locale_warn.to_value(),
162 "development_mode" => inner.config.development_mode.to_value(),
163 "isolated" => inner.config.isolated.to_value(),
164 "legacy_windows_fs_encoding" => inner.config.legacy_windows_fs_encoding.to_value(),
165 "parse_argv" => inner.config.parse_argv.to_value(),
166 "use_environment" => inner.config.use_environment.to_value(),
167 "utf8_mode" => inner.config.utf8_mode.to_value(),
168 "base_exec_prefix" => inner.config.base_exec_prefix.to_value(),
169 "base_executable" => inner.config.base_executable.to_value(),
170 "base_prefix" => inner.config.base_prefix.to_value(),
171 "buffered_stdio" => inner.config.buffered_stdio.to_value(),
172 "bytes_warning" => inner.config.bytes_warning.to_value(),
173 "check_hash_pycs_mode" => inner.config.check_hash_pycs_mode.to_value(),
174 "configure_c_stdio" => inner.config.configure_c_stdio.to_value(),
175 "dump_refs" => inner.config.dump_refs.to_value(),
176 "exec_prefix" => inner.config.exec_prefix.to_value(),
177 "executable" => inner.config.executable.to_value(),
178 "fault_handler" => inner.config.fault_handler.to_value(),
179 "filesystem_encoding" => inner.config.filesystem_encoding.to_value(),
180 "filesystem_errors" => inner.config.filesystem_errors.to_value(),
181 "hash_seed" => inner.config.hash_seed.to_value(),
182 "home" => inner.config.home.to_value(),
183 "import_time" => inner.config.import_time.to_value(),
184 "inspect" => inner.config.inspect.to_value(),
185 "install_signal_handlers" => inner.config.install_signal_handlers.to_value(),
186 "interactive" => inner.config.interactive.to_value(),
187 "legacy_windows_stdio" => inner.config.legacy_windows_stdio.to_value(),
188 "malloc_stats" => inner.config.malloc_stats.to_value(),
189 "module_search_paths" => inner.config.module_search_paths.to_value(),
190 "optimization_level" => inner.config.optimization_level.to_value(),
191 "parser_debug" => inner.config.parser_debug.to_value(),
192 "pathconfig_warnings" => inner.config.pathconfig_warnings.to_value(),
193 "prefix" => inner.config.prefix.to_value(),
194 "program_name" => inner.config.program_name.to_value(),
195 "pycache_prefix" => inner.config.pycache_prefix.to_value(),
196 "python_path_env" => inner.config.python_path_env.to_value(),
197 "quiet" => inner.config.quiet.to_value(),
198 "run_command" => inner.config.run_command.to_value(),
199 "run_filename" => inner.config.run_filename.to_value(),
200 "run_module" => inner.config.run_module.to_value(),
201 "show_ref_count" => inner.config.show_ref_count.to_value(),
202 "site_import" => inner.config.site_import.to_value(),
203 "skip_first_source_line" => inner.config.skip_first_source_line.to_value(),
204 "stdio_encoding" => inner.config.stdio_encoding.to_value(),
205 "stdio_errors" => inner.config.stdio_errors.to_value(),
206 "tracemalloc" => inner.config.tracemalloc.to_value(),
207 "user_site_directory" => inner.config.user_site_directory.to_value(),
208 "verbose" => inner.config.verbose.to_value(),
209 "warn_options" => inner.config.warn_options.to_value(),
210 "write_bytecode" => inner.config.write_bytecode.to_value(),
211 "x_options" => inner.config.x_options.to_value(),
212 "allocator_backend" => inner.allocator_backend.to_value(),
213 "allocator_raw" => Value::from(inner.allocator_raw),
214 "allocator_mem" => Value::from(inner.allocator_mem),
215 "allocator_obj" => Value::from(inner.allocator_obj),
216 "allocator_pymalloc_arena" => Value::from(inner.allocator_pymalloc_arena),
217 "allocator_debug" => Value::from(inner.allocator_debug),
218 "oxidized_importer" => Value::from(inner.oxidized_importer),
219 "filesystem_importer" => Value::from(inner.filesystem_importer),
220 "argvb" => Value::from(inner.argvb),
221 "multiprocessing_auto_dispatch" => Value::from(inner.multiprocessing_auto_dispatch),
222 "multiprocessing_start_method" => {
223 Value::from(inner.multiprocessing_start_method.to_string())
224 }
225 "sys_frozen" => Value::from(inner.sys_frozen),
226 "sys_meipass" => Value::from(inner.sys_meipass),
227 "terminfo_resolution" => inner.terminfo_resolution.to_value(),
228 "write_modules_directory_env" => inner.write_modules_directory_env.to_value(),
229 attr => {
230 return Err(ValueError::OperationNotSupported {
231 op: UnsupportedOperation::GetAttr(attr.to_string()),
232 left: Self::TYPE.to_owned(),
233 right: None,
234 })
235 }
236 };
237
238 Ok(v)
239 }
240
241 fn has_attr(&self, attribute: &str) -> Result<bool, ValueError> {
242 Ok(matches!(
243 attribute,
244 "config_profile"
245 | "allocator"
246 | "configure_locale"
247 | "coerce_c_locale"
248 | "coerce_c_locale_warn"
249 | "development_mode"
250 | "isolated"
251 | "legacy_windows_fs_encoding"
252 | "parse_argv"
253 | "use_environment"
254 | "utf8_mode"
255 | "base_exec_prefix"
256 | "base_executable"
257 | "base_prefix"
258 | "buffered_stdio"
259 | "bytes_warning"
260 | "check_hash_pycs_mode"
261 | "configure_c_stdio"
262 | "dump_refs"
263 | "exec_prefix"
264 | "executable"
265 | "fault_handler"
266 | "filesystem_encoding"
267 | "filesystem_errors"
268 | "hash_seed"
269 | "home"
270 | "import_time"
271 | "inspect"
272 | "install_signal_handlers"
273 | "interactive"
274 | "legacy_windows_stdio"
275 | "malloc_stats"
276 | "module_search_paths"
277 | "optimization_level"
278 | "parser_debug"
279 | "pathconfig_warnings"
280 | "prefix"
281 | "program_name"
282 | "pycache_prefix"
283 | "python_path_env"
284 | "quiet"
285 | "run_command"
286 | "run_filename"
287 | "run_module"
288 | "show_ref_count"
289 | "site_import"
290 | "skip_first_source_line"
291 | "stdio_encoding"
292 | "stdio_errors"
293 | "tracemalloc"
294 | "user_site_directory"
295 | "verbose"
296 | "warn_options"
297 | "write_bytecode"
298 | "x_options"
299 | "allocator_backend"
300 | "allocator_raw"
301 | "allocator_mem"
302 | "allocator_obj"
303 | "allocator_pymalloc_arena"
304 | "allocator_debug"
305 | "oxidized_importer"
306 | "filesystem_importer"
307 | "argvb"
308 | "multiprocessing_auto_dispatch"
309 | "multiprocessing_start_method"
310 | "sys_frozen"
311 | "sys_meipass"
312 | "terminfo_resolution"
313 | "write_modules_directory_env"
314 ))
315 }
316
317 fn set_attr(&mut self, attribute: &str, value: Value) -> Result<(), ValueError> {
318 let mut inner = self.inner(&format!("PythonInterpreterConfig.{}", attribute))?;
319
320 match attribute {
321 "config_profile" => {
322 inner.config.profile = PythonInterpreterProfile::try_from(
323 value.to_string().as_str(),
324 )
325 .map_err(|e| {
326 ValueError::from(RuntimeError {
327 code: INCORRECT_PARAMETER_TYPE_ERROR_CODE,
328 message: e,
329 label: format!("{}.{}", Self::TYPE, attribute),
330 })
331 })?;
332 }
333 "allocator" => {
334 inner.config.allocator = if value.get_type() == "NoneType" {
335 None
336 } else {
337 Some(
338 Allocator::try_from(value.to_string().as_str()).map_err(|e| {
339 ValueError::from(RuntimeError {
340 code: INCORRECT_PARAMETER_TYPE_ERROR_CODE,
341 message: e,
342 label: format!("{}.{}", Self::TYPE, attribute),
343 })
344 })?,
345 )
346 };
347 }
348 "configure_locale" => {
349 inner.config.configure_locale = value.to_optional();
350 }
351 "coerce_c_locale" => {
352 inner.config.coerce_c_locale = if value.get_type() == "NoneType" {
353 None
354 } else {
355 Some(
356 CoerceCLocale::try_from(value.to_string().as_str()).map_err(|e| {
357 ValueError::from(RuntimeError {
358 code: INCORRECT_PARAMETER_TYPE_ERROR_CODE,
359 message: e,
360 label: format!("{}.{}", Self::TYPE, attribute),
361 })
362 })?,
363 )
364 };
365 }
366 "coerce_c_locale_warn" => {
367 inner.config.coerce_c_locale_warn = value.to_optional();
368 }
369 "development_mode" => {
370 inner.config.development_mode = value.to_optional();
371 }
372 "isolated" => {
373 inner.config.isolated = value.to_optional();
374 }
375 "legacy_windows_fs_encoding" => {
376 inner.config.legacy_windows_fs_encoding = value.to_optional();
377 }
378 "parse_argv" => {
379 inner.config.parse_argv = value.to_optional();
380 }
381 "use_environment" => {
382 inner.config.use_environment = value.to_optional();
383 }
384 "utf8_mode" => {
385 inner.config.utf8_mode = value.to_optional();
386 }
387 "base_exec_prefix" => {
388 inner.config.base_exec_prefix = value.to_optional();
389 }
390 "base_executable" => {
391 inner.config.base_executable = value.to_optional();
392 }
393 "base_prefix" => {
394 inner.config.base_prefix = value.to_optional();
395 }
396 "buffered_stdio" => {
397 inner.config.buffered_stdio = value.to_optional();
398 }
399 "bytes_warning" => {
400 inner.config.bytes_warning = if value.get_type() == "NoneType" {
401 None
402 } else {
403 Some(
404 BytesWarning::try_from(value.to_string().as_str()).map_err(|e| {
405 ValueError::from(RuntimeError {
406 code: INCORRECT_PARAMETER_TYPE_ERROR_CODE,
407 message: e,
408 label: format!("{}.{}", Self::TYPE, attribute),
409 })
410 })?,
411 )
412 };
413 }
414 "check_hash_pycs_mode" => {
415 inner.config.check_hash_pycs_mode = if value.get_type() == "NoneType" {
416 None
417 } else {
418 Some(
419 CheckHashPycsMode::try_from(value.to_string().as_str()).map_err(|e| {
420 ValueError::from(RuntimeError {
421 code: INCORRECT_PARAMETER_TYPE_ERROR_CODE,
422 message: e,
423 label: format!("{}.{}", Self::TYPE, attribute),
424 })
425 })?,
426 )
427 };
428 }
429 "configure_c_stdio" => {
430 inner.config.configure_c_stdio = value.to_optional();
431 }
432 "dump_refs" => {
433 inner.config.dump_refs = value.to_optional();
434 }
435 "exec_prefix" => {
436 inner.config.exec_prefix = value.to_optional();
437 }
438 "executable" => {
439 inner.config.executable = value.to_optional();
440 }
441 "fault_handler" => {
442 inner.config.fault_handler = value.to_optional();
443 }
444 "filesystem_encoding" => {
445 inner.config.filesystem_encoding = value.to_optional();
446 }
447 "filesystem_errors" => {
448 inner.config.filesystem_errors = value.to_optional();
449 }
450 "hash_seed" => {
451 inner.config.hash_seed = value.try_to_optional()?;
452 }
453 "home" => {
454 inner.config.home = value.to_optional();
455 }
456 "import_time" => {
457 inner.config.import_time = value.to_optional();
458 }
459 "inspect" => {
460 inner.config.inspect = value.to_optional();
461 }
462 "install_signal_handlers" => {
463 inner.config.install_signal_handlers = value.to_optional();
464 }
465 "interactive" => {
466 inner.config.interactive = value.to_optional();
467 }
468 "legacy_windows_stdio" => {
469 inner.config.legacy_windows_stdio = value.to_optional();
470 }
471 "malloc_stats" => {
472 inner.config.malloc_stats = value.to_optional();
473 }
474 "module_search_paths" => {
475 inner.config.module_search_paths = value.try_to_optional()?;
476
477 if let Some(paths) = &inner.config.module_search_paths {
480 if !paths.is_empty() {
481 inner.filesystem_importer = true;
482 }
483 }
484 }
485 "optimization_level" => {
486 inner.config.optimization_level =
487 bytecode_optimization_level_try_to_optional(value)?;
488 }
489 "parser_debug" => {
490 inner.config.parser_debug = value.to_optional();
491 }
492 "pathconfig_warnings" => {
493 inner.config.pathconfig_warnings = value.to_optional();
494 }
495 "prefix" => {
496 inner.config.prefix = value.to_optional();
497 }
498 "program_name" => {
499 inner.config.program_name = value.to_optional();
500 }
501 "pycache_prefix" => {
502 inner.config.pycache_prefix = value.to_optional();
503 }
504 "python_path_env" => {
505 inner.config.python_path_env = value.to_optional();
506 }
507 "quiet" => {
508 inner.config.quiet = value.to_optional();
509 }
510 "run_command" => {
511 inner.config.run_command = value.to_optional();
512 }
513 "run_filename" => {
514 inner.config.run_filename = value.to_optional();
515 }
516 "run_module" => {
517 inner.config.run_module = value.to_optional();
518 }
519 "show_ref_count" => {
520 inner.config.show_ref_count = value.to_optional();
521 }
522 "site_import" => {
523 inner.config.site_import = value.to_optional();
524 }
525 "skip_first_source_line" => {
526 inner.config.skip_first_source_line = value.to_optional();
527 }
528 "stdio_encoding" => {
529 inner.config.stdio_encoding = value.to_optional();
530 }
531 "stdio_errors" => {
532 inner.config.stdio_errors = value.to_optional();
533 }
534 "tracemalloc" => {
535 inner.config.tracemalloc = value.to_optional();
536 }
537 "user_site_directory" => {
538 inner.config.user_site_directory = value.to_optional();
539 }
540 "verbose" => {
541 inner.config.configure_locale = value.to_optional();
542 }
543 "warn_options" => {
544 inner.config.warn_options = value.try_to_optional()?;
545 }
546 "write_bytecode" => {
547 inner.config.write_bytecode = value.to_optional();
548 }
549 "x_options" => {
550 inner.config.x_options = value.try_to_optional()?;
551 }
552 "allocator_backend" => {
553 inner.allocator_backend =
554 MemoryAllocatorBackend::try_from(value.to_string().as_str()).map_err(|e| {
555 ValueError::from(RuntimeError {
556 code: INCORRECT_PARAMETER_TYPE_ERROR_CODE,
557 message: e,
558 label: format!("{}.{}", Self::TYPE, attribute),
559 })
560 })?;
561 }
562 "allocator_raw" => {
563 inner.allocator_raw = value.to_bool();
564 }
565 "allocator_mem" => {
566 inner.allocator_mem = value.to_bool();
567 }
568 "allocator_obj" => {
569 inner.allocator_obj = value.to_bool();
570 }
571 "allocator_pymalloc_arena" => {
572 inner.allocator_pymalloc_arena = value.to_bool();
573 }
574 "allocator_debug" => {
575 inner.allocator_debug = value.to_bool();
576 }
577 "oxidized_importer" => {
578 inner.oxidized_importer = value.to_bool();
579 }
580 "filesystem_importer" => {
581 inner.filesystem_importer = value.to_bool();
582 }
583 "argvb" => {
584 inner.argvb = value.to_bool();
585 }
586 "multiprocessing_auto_dispatch" => {
587 inner.multiprocessing_auto_dispatch = value.to_bool();
588 }
589 "multiprocessing_start_method" => {
590 inner.multiprocessing_start_method = MultiprocessingStartMethod::from_str(
591 value.to_string().as_str(),
592 )
593 .map_err(|e| {
594 ValueError::from(RuntimeError {
595 code: INCORRECT_PARAMETER_TYPE_ERROR_CODE,
596 message: e,
597 label: format!("{}.{}", Self::TYPE, attribute),
598 })
599 })?;
600 }
601 "sys_frozen" => {
602 inner.sys_frozen = value.to_bool();
603 }
604 "sys_meipass" => {
605 inner.sys_meipass = value.to_bool();
606 }
607 "terminfo_resolution" => {
608 inner.terminfo_resolution =
609 TerminfoResolution::try_from(value.to_string().as_str()).map_err(|e| {
610 ValueError::from(RuntimeError {
611 code: INCORRECT_PARAMETER_TYPE_ERROR_CODE,
612 message: e,
613 label: format!("{}.{}", Self::TYPE, attribute),
614 })
615 })?;
616 }
617 "write_modules_directory_env" => {
618 inner.write_modules_directory_env = value.to_optional();
619 }
620 attr => {
621 return Err(ValueError::OperationNotSupported {
622 op: UnsupportedOperation::SetAttr(attr.to_string()),
623 left: Self::TYPE.to_owned(),
624 right: None,
625 })
626 }
627 }
628
629 Ok(())
630 }
631}
632
633#[cfg(test)]
634mod tests {
635 use crate::starlark::eval::EvaluationContext;
636 use {super::super::testutil::*, anyhow::Result};
637
638 fn get_env() -> Result<EvaluationContext> {
640 let mut eval = test_evaluation_context_builder()?.into_context()?;
641 eval.eval("dist = default_python_distribution()")?;
642 eval.eval("config = dist.make_python_interpreter_config()")?;
643
644 Ok(eval)
645 }
646
647 #[test]
648 fn test_profile() -> Result<()> {
649 let mut env = get_env()?;
650
651 eval_assert(&mut env, "config.config_profile == 'isolated'")?;
652
653 env.eval("config.config_profile = 'python'")?;
654 eval_assert(&mut env, "config.config_profile == 'python'")?;
655
656 env.eval("config.config_profile = 'isolated'")?;
657 eval_assert(&mut env, "config.config_profile == 'isolated'")?;
658
659 Ok(())
660 }
661
662 #[test]
663 fn test_allocator() -> Result<()> {
664 let mut env = get_env()?;
665
666 eval_assert(&mut env, "config.allocator == None")?;
667
668 env.eval("config.allocator = 'not-set'")?;
669 eval_assert(&mut env, "config.allocator == 'not-set'")?;
670
671 env.eval("config.allocator = 'default'")?;
672 eval_assert(&mut env, "config.allocator == 'default'")?;
673
674 env.eval("config.allocator = 'debug'")?;
675 eval_assert(&mut env, "config.allocator == 'debug'")?;
676
677 env.eval("config.allocator = 'malloc'")?;
678 eval_assert(&mut env, "config.allocator == 'malloc'")?;
679
680 env.eval("config.allocator = 'malloc-debug'")?;
681 eval_assert(&mut env, "config.allocator == 'malloc-debug'")?;
682
683 env.eval("config.allocator = 'py-malloc'")?;
684 eval_assert(&mut env, "config.allocator == 'py-malloc'")?;
685
686 env.eval("config.allocator = 'py-malloc-debug'")?;
687 eval_assert(&mut env, "config.allocator == 'py-malloc-debug'")?;
688
689 env.eval("config.allocator = None")?;
690 eval_assert(&mut env, "config.allocator == None")?;
691
692 Ok(())
693 }
694
695 #[test]
696 fn test_configure_locale() -> Result<()> {
697 let mut env = get_env()?;
698
699 eval_assert(&mut env, "config.configure_locale == True")?;
700
701 Ok(())
702 }
703
704 #[test]
705 fn test_coerce_c_locale() -> Result<()> {
706 let mut env = get_env()?;
707
708 eval_assert(&mut env, "config.coerce_c_locale == None")?;
709
710 Ok(())
711 }
712
713 #[test]
714 fn test_development_mode() -> Result<()> {
715 let mut env = get_env()?;
716
717 eval_assert(&mut env, "config.development_mode == None")?;
718
719 Ok(())
720 }
721
722 #[test]
723 fn test_isolated() -> Result<()> {
724 let mut env = get_env()?;
725
726 eval_assert(&mut env, "config.isolated == None")?;
727
728 Ok(())
729 }
730
731 #[test]
732 fn test_legacy_windows_fs_encoding() -> Result<()> {
733 let mut env = get_env()?;
734
735 eval_assert(&mut env, "config.legacy_windows_fs_encoding == None")?;
736
737 Ok(())
738 }
739
740 #[test]
741 fn test_parse_argv() -> Result<()> {
742 let mut env = get_env()?;
743
744 eval_assert(&mut env, "config.parse_argv == None")?;
745
746 Ok(())
747 }
748
749 #[test]
750 fn test_use_environment() -> Result<()> {
751 let mut env = get_env()?;
752
753 eval_assert(&mut env, "config.use_environment == None")?;
754
755 Ok(())
756 }
757
758 #[test]
759 fn test_utf8_mode() -> Result<()> {
760 let mut env = get_env()?;
761
762 eval_assert(&mut env, "config.utf8_mode == None")?;
763
764 Ok(())
765 }
766
767 #[test]
768 fn test_base_exec_prefix() -> Result<()> {
769 let mut env = get_env()?;
770
771 eval_assert(&mut env, "config.base_exec_prefix == None")?;
772
773 Ok(())
774 }
775
776 #[test]
777 fn test_base_executable() -> Result<()> {
778 let mut env = get_env()?;
779
780 eval_assert(&mut env, "config.base_executable == None")?;
781
782 Ok(())
783 }
784
785 #[test]
786 fn test_base_prefix() -> Result<()> {
787 let mut env = get_env()?;
788
789 eval_assert(&mut env, "config.base_prefix == None")?;
790
791 Ok(())
792 }
793
794 #[test]
795 fn test_buffered_stdio() -> Result<()> {
796 let mut env = get_env()?;
797
798 eval_assert(&mut env, "config.buffered_stdio == None")?;
799
800 Ok(())
801 }
802
803 #[test]
804 fn test_bytes_warning() -> Result<()> {
805 let mut env = get_env()?;
806
807 eval_assert(&mut env, "config.bytes_warning == None")?;
808
809 env.eval("config.bytes_warning = 'warn'")?;
810 eval_assert(&mut env, "config.bytes_warning == 'warn'")?;
811
812 env.eval("config.bytes_warning = 'raise'")?;
813 eval_assert(&mut env, "config.bytes_warning == 'raise'")?;
814
815 env.eval("config.bytes_warning = None")?;
816 eval_assert(&mut env, "config.bytes_warning == None")?;
817
818 Ok(())
819 }
820
821 #[test]
822 fn test_check_hash_pycs_mode() -> Result<()> {
823 let mut env = get_env()?;
824
825 eval_assert(&mut env, "config.check_hash_pycs_mode == None")?;
826
827 Ok(())
828 }
829
830 #[test]
831 fn test_configure_c_stdio() -> Result<()> {
832 let mut env = get_env()?;
833
834 eval_assert(&mut env, "config.configure_c_stdio == None")?;
835
836 Ok(())
837 }
838
839 #[test]
840 fn test_dump_refs() -> Result<()> {
841 let mut env = get_env()?;
842
843 eval_assert(&mut env, "config.dump_refs == None")?;
844
845 Ok(())
846 }
847
848 #[test]
849 fn test_exec_prefix() -> Result<()> {
850 let mut env = get_env()?;
851
852 eval_assert(&mut env, "config.exec_prefix == None")?;
853
854 Ok(())
855 }
856
857 #[test]
858 fn test_executable() -> Result<()> {
859 let mut env = get_env()?;
860
861 eval_assert(&mut env, "config.executable == None")?;
862
863 Ok(())
864 }
865
866 #[test]
867 fn test_fault_handler() -> Result<()> {
868 let mut env = get_env()?;
869
870 eval_assert(&mut env, "config.fault_handler == None")?;
871
872 Ok(())
873 }
874
875 #[test]
876 fn test_filesystem_encoding() -> Result<()> {
877 let mut env = get_env()?;
878
879 eval_assert(&mut env, "config.filesystem_encoding == None")?;
880
881 Ok(())
882 }
883
884 #[test]
885 fn test_filesystem_errors() -> Result<()> {
886 let mut env = get_env()?;
887
888 eval_assert(&mut env, "config.filesystem_errors == None")?;
889
890 Ok(())
891 }
892
893 #[test]
894 fn test_hash_seed() -> Result<()> {
895 let mut env = get_env()?;
896
897 eval_assert(&mut env, "config.hash_seed == None")?;
898
899 Ok(())
900 }
901
902 #[test]
903 fn test_home() -> Result<()> {
904 let mut env = get_env()?;
905
906 eval_assert(&mut env, "config.home == None")?;
907
908 Ok(())
909 }
910
911 #[test]
912 fn test_import_time() -> Result<()> {
913 let mut env = get_env()?;
914
915 eval_assert(&mut env, "config.import_time == None")?;
916
917 Ok(())
918 }
919
920 #[test]
921 fn test_inspect() -> Result<()> {
922 let mut env = get_env()?;
923
924 eval_assert(&mut env, "config.inspect == None")?;
925
926 Ok(())
927 }
928
929 #[test]
930 fn test_install_signal_handlers() -> Result<()> {
931 let mut env = get_env()?;
932
933 eval_assert(&mut env, "config.install_signal_handlers == None")?;
934
935 Ok(())
936 }
937
938 #[test]
939 fn test_interactive() -> Result<()> {
940 let mut env = get_env()?;
941
942 eval_assert(&mut env, "config.interactive == None")?;
943
944 Ok(())
945 }
946
947 #[test]
948 fn test_legacy_windows_stdio() -> Result<()> {
949 let mut env = get_env()?;
950
951 eval_assert(&mut env, "config.legacy_windows_stdio == None")?;
952
953 Ok(())
954 }
955
956 #[test]
957 fn test_malloc_stats() -> Result<()> {
958 let mut env = get_env()?;
959
960 eval_assert(&mut env, "config.malloc_stats == None")?;
961
962 Ok(())
963 }
964
965 #[test]
966 fn test_module_search_paths() -> Result<()> {
967 let mut env = get_env()?;
968
969 eval_assert(&mut env, "config.module_search_paths == None")?;
970 eval_assert(&mut env, "config.filesystem_importer == False")?;
971
972 env.eval("config.module_search_paths = []")?;
973 eval_assert(&mut env, "config.module_search_paths == []")?;
974 eval_assert(&mut env, "config.filesystem_importer == False")?;
975
976 env.eval("config.module_search_paths = ['foo']")?;
977 eval_assert(&mut env, "config.module_search_paths == ['foo']")?;
978 eval_assert(&mut env, "config.filesystem_importer == True")?;
980
981 Ok(())
982 }
983
984 #[test]
985 fn test_optimization_level() -> Result<()> {
986 let mut env = get_env()?;
987
988 eval_assert(&mut env, "config.optimization_level == None")?;
989
990 env.eval("config.optimization_level = 0")?;
991 eval_assert(&mut env, "config.optimization_level == 0")?;
992
993 env.eval("config.optimization_level = 1")?;
994 eval_assert(&mut env, "config.optimization_level == 1")?;
995
996 env.eval("config.optimization_level = 2")?;
997 eval_assert(&mut env, "config.optimization_level == 2")?;
998
999 Ok(())
1000 }
1001
1002 #[test]
1003 fn test_parser_debug() -> Result<()> {
1004 let mut env = get_env()?;
1005
1006 eval_assert(&mut env, "config.parser_debug == None")?;
1007
1008 Ok(())
1009 }
1010
1011 #[test]
1012 fn test_pathconfig_warnings() -> Result<()> {
1013 let mut env = get_env()?;
1014
1015 eval_assert(&mut env, "config.pathconfig_warnings == None")?;
1016
1017 Ok(())
1018 }
1019
1020 #[test]
1021 fn test_prefix() -> Result<()> {
1022 let mut env = get_env()?;
1023
1024 eval_assert(&mut env, "config.prefix == None")?;
1025
1026 Ok(())
1027 }
1028
1029 #[test]
1030 fn test_program_name() -> Result<()> {
1031 let mut env = get_env()?;
1032
1033 eval_assert(&mut env, "config.program_name == None")?;
1034
1035 Ok(())
1036 }
1037
1038 #[test]
1039 fn test_pycache_prefix() -> Result<()> {
1040 let mut env = get_env()?;
1041
1042 eval_assert(&mut env, "config.pycache_prefix == None")?;
1043
1044 Ok(())
1045 }
1046
1047 #[test]
1048 fn test_python_path_env() -> Result<()> {
1049 let mut env = get_env()?;
1050
1051 eval_assert(&mut env, "config.python_path_env == None")?;
1052
1053 Ok(())
1054 }
1055
1056 #[test]
1057 fn test_quiet() -> Result<()> {
1058 let mut env = get_env()?;
1059
1060 eval_assert(&mut env, "config.quiet == None")?;
1061
1062 Ok(())
1063 }
1064
1065 #[test]
1066 fn test_run_command() -> Result<()> {
1067 let mut env = get_env()?;
1068
1069 eval_assert(&mut env, "config.run_command == None")?;
1070
1071 Ok(())
1072 }
1073
1074 #[test]
1075 fn test_run_filename() -> Result<()> {
1076 let mut env = get_env()?;
1077
1078 eval_assert(&mut env, "config.run_filename == None")?;
1079
1080 Ok(())
1081 }
1082
1083 #[test]
1084 fn test_run_module() -> Result<()> {
1085 let mut env = get_env()?;
1086
1087 eval_assert(&mut env, "config.run_module == None")?;
1088
1089 Ok(())
1090 }
1091
1092 #[test]
1093 fn test_show_ref_count() -> Result<()> {
1094 let mut env = get_env()?;
1095
1096 eval_assert(&mut env, "config.show_ref_count == None")?;
1097
1098 Ok(())
1099 }
1100
1101 #[test]
1102 fn test_site_import() -> Result<()> {
1103 let mut env = get_env()?;
1104
1105 eval_assert(&mut env, "config.site_import == None")?;
1106
1107 Ok(())
1108 }
1109
1110 #[test]
1111 fn test_skip_first_source_line() -> Result<()> {
1112 let mut env = get_env()?;
1113
1114 eval_assert(&mut env, "config.skip_first_source_line == None")?;
1115
1116 Ok(())
1117 }
1118
1119 #[test]
1120 fn test_stdio_encoding() -> Result<()> {
1121 let mut env = get_env()?;
1122
1123 eval_assert(&mut env, "config.stdio_encoding == None")?;
1124
1125 Ok(())
1126 }
1127
1128 #[test]
1129 fn test_stdio_errors() -> Result<()> {
1130 let mut env = get_env()?;
1131
1132 eval_assert(&mut env, "config.stdio_errors == None")?;
1133
1134 Ok(())
1135 }
1136
1137 #[test]
1138 fn test_tracemalloc() -> Result<()> {
1139 let mut env = get_env()?;
1140
1141 eval_assert(&mut env, "config.tracemalloc == None")?;
1142
1143 Ok(())
1144 }
1145
1146 #[test]
1147 fn test_user_site_directory() -> Result<()> {
1148 let mut env = get_env()?;
1149
1150 eval_assert(&mut env, "config.user_site_directory == None")?;
1151 env.eval("config.user_site_directory = True")?;
1152 let v = env.eval("config.user_site_directory")?;
1153 assert!(v.to_bool());
1154 env.eval("config.user_site_directory = False")?;
1155 let v = env.eval("config.user_site_directory")?;
1156 assert!(!v.to_bool());
1157
1158 Ok(())
1159 }
1160
1161 #[test]
1162 fn test_verbose() -> Result<()> {
1163 let mut env = get_env()?;
1164
1165 eval_assert(&mut env, "config.verbose == None")?;
1166
1167 Ok(())
1168 }
1169
1170 #[test]
1171 fn test_warn_options() -> Result<()> {
1172 let mut env = get_env()?;
1173
1174 eval_assert(&mut env, "config.warn_options == None")?;
1175
1176 Ok(())
1177 }
1178
1179 #[test]
1180 fn test_write_bytecode() -> Result<()> {
1181 let mut env = get_env()?;
1182
1183 eval_assert(&mut env, "config.write_bytecode == None")?;
1184
1185 Ok(())
1186 }
1187
1188 #[test]
1189 fn test_x_options() -> Result<()> {
1190 let mut env = get_env()?;
1191
1192 eval_assert(&mut env, "config.x_options == None")?;
1193
1194 Ok(())
1195 }
1196
1197 #[test]
1198 fn test_allocator_backend() -> Result<()> {
1199 let mut env = get_env()?;
1200
1201 eval_assert(&mut env, "config.allocator_backend == 'default'")?;
1202
1203 env.eval("config.allocator_backend = 'jemalloc'")?;
1204 eval_assert(&mut env, "config.allocator_backend == 'jemalloc'")?;
1205
1206 env.eval("config.allocator_backend = 'mimalloc'")?;
1207 eval_assert(&mut env, "config.allocator_backend == 'mimalloc'")?;
1208
1209 env.eval("config.allocator_backend = 'rust'")?;
1210 eval_assert(&mut env, "config.allocator_backend == 'rust'")?;
1211
1212 env.eval("config.allocator_backend = 'snmalloc'")?;
1213 eval_assert(&mut env, "config.allocator_backend == 'snmalloc'")?;
1214
1215 env.eval("config.allocator_backend = 'default'")?;
1216 eval_assert(&mut env, "config.allocator_backend == 'default'")?;
1217
1218 Ok(())
1219 }
1220
1221 #[test]
1222 fn test_allocator_raw() -> Result<()> {
1223 let mut env = get_env()?;
1224
1225 eval_assert(&mut env, "config.allocator_raw == True")?;
1226
1227 env.eval("config.allocator_raw = False")?;
1228 eval_assert(&mut env, "config.allocator_raw == False")?;
1229
1230 Ok(())
1231 }
1232
1233 #[test]
1234 fn test_allocator_mem() -> Result<()> {
1235 let mut env = get_env()?;
1236
1237 eval_assert(&mut env, "config.allocator_mem == False")?;
1238
1239 env.eval("config.allocator_mem = True")?;
1240 eval_assert(&mut env, "config.allocator_mem == True")?;
1241
1242 Ok(())
1243 }
1244
1245 #[test]
1246 fn test_allocator_obj() -> Result<()> {
1247 let mut env = get_env()?;
1248
1249 eval_assert(&mut env, "config.allocator_obj == False")?;
1250
1251 env.eval("config.allocator_obj = True")?;
1252 eval_assert(&mut env, "config.allocator_obj == True")?;
1253
1254 Ok(())
1255 }
1256
1257 #[test]
1258 fn test_allocator_pymalloc_arena() -> Result<()> {
1259 let mut env = get_env()?;
1260
1261 eval_assert(&mut env, "config.allocator_pymalloc_arena == False")?;
1262
1263 env.eval("config.allocator_pymalloc_arena = True")?;
1264 eval_assert(&mut env, "config.allocator_pymalloc_arena == True")?;
1265
1266 Ok(())
1267 }
1268
1269 #[test]
1270 fn test_allocator_debug() -> Result<()> {
1271 let mut env = get_env()?;
1272
1273 eval_assert(&mut env, "config.allocator_debug == False")?;
1274
1275 env.eval("config.allocator_debug = True")?;
1276 eval_assert(&mut env, "config.allocator_debug == True")?;
1277
1278 Ok(())
1279 }
1280
1281 #[test]
1282 fn test_oxidized_importer() -> Result<()> {
1283 let mut env = get_env()?;
1284
1285 eval_assert(&mut env, "config.oxidized_importer == True")?;
1286
1287 Ok(())
1288 }
1289
1290 #[test]
1291 fn test_filesystem_importer() -> Result<()> {
1292 let mut env = get_env()?;
1293
1294 eval_assert(&mut env, "config.filesystem_importer == False")?;
1295
1296 Ok(())
1297 }
1298
1299 #[test]
1300 fn test_argvb() -> Result<()> {
1301 let mut env = get_env()?;
1302
1303 eval_assert(&mut env, "config.argvb == False")?;
1304
1305 Ok(())
1306 }
1307
1308 #[test]
1309 fn test_multiprocessing_auto_dispatch() -> Result<()> {
1310 let mut env = get_env()?;
1311
1312 eval_assert(&mut env, "config.multiprocessing_auto_dispatch == True")?;
1313
1314 env.eval("config.multiprocessing_auto_dispatch = False")?;
1315 eval_assert(&mut env, "config.multiprocessing_auto_dispatch == False")?;
1316
1317 Ok(())
1318 }
1319
1320 #[test]
1321 fn test_multiprocessing_start_method() -> Result<()> {
1322 let mut env = get_env()?;
1323
1324 eval_assert(&mut env, "config.multiprocessing_start_method == 'auto'")?;
1325
1326 env.eval("config.multiprocessing_start_method = 'none'")?;
1327 eval_assert(&mut env, "config.multiprocessing_start_method == 'none'")?;
1328
1329 env.eval("config.multiprocessing_start_method = 'fork'")?;
1330 eval_assert(&mut env, "config.multiprocessing_start_method == 'fork'")?;
1331
1332 env.eval("config.multiprocessing_start_method = 'forkserver'")?;
1333 eval_assert(
1334 &mut env,
1335 "config.multiprocessing_start_method == 'forkserver'",
1336 )?;
1337
1338 env.eval("config.multiprocessing_start_method = 'spawn'")?;
1339 eval_assert(&mut env, "config.multiprocessing_start_method == 'spawn'")?;
1340
1341 env.eval("config.multiprocessing_start_method = 'auto'")?;
1342 eval_assert(&mut env, "config.multiprocessing_start_method == 'auto'")?;
1343
1344 Ok(())
1345 }
1346
1347 #[test]
1348 fn test_sys_frozen() -> Result<()> {
1349 let mut env = get_env()?;
1350
1351 eval_assert(&mut env, "config.sys_frozen == True")?;
1352
1353 Ok(())
1354 }
1355
1356 #[test]
1357 fn test_sys_meipass() -> Result<()> {
1358 let mut env = get_env()?;
1359
1360 eval_assert(&mut env, "config.sys_meipass == False")?;
1361
1362 Ok(())
1363 }
1364
1365 #[test]
1366 fn test_terminfo_resolution() -> Result<()> {
1367 let mut env = get_env()?;
1368
1369 eval_assert(&mut env, "config.terminfo_resolution == 'dynamic'")?;
1370
1371 env.eval("config.terminfo_resolution = 'none'")?;
1372 eval_assert(&mut env, "config.terminfo_resolution == 'none'")?;
1373
1374 env.eval("config.terminfo_resolution = 'static:foo'")?;
1375 eval_assert(&mut env, "config.terminfo_resolution == 'static:foo'")?;
1376
1377 Ok(())
1378 }
1379
1380 #[test]
1381 fn test_write_modules_directory_env() -> Result<()> {
1382 let mut env = get_env()?;
1383
1384 eval_assert(&mut env, "config.write_modules_directory_env == None")?;
1385
1386 Ok(())
1387 }
1388}