1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#[cfg(feature = "rustpython-ast")]
pub(crate) mod ast;
pub mod atexit;
pub mod builtins;
mod codecs;
mod collections;
pub mod errno;
mod functools;
mod imp;
pub mod io;
mod itertools;
mod marshal;
mod operator;
// TODO: maybe make this an extension module, if we ever get those
// mod re;
mod sre;
mod string;
#[cfg(feature = "rustpython-compiler")]
mod symtable;
mod sysconfigdata;
#[cfg(feature = "threading")]
pub mod thread;
pub mod time;
pub mod warnings;
mod weakref;

#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
#[macro_use]
pub mod os;
#[cfg(windows)]
pub mod nt;
#[cfg(unix)]
pub mod posix;
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
#[cfg(not(any(unix, windows)))]
#[path = "posix_compat.rs"]
pub mod posix;

#[cfg(windows)]
pub(crate) mod msvcrt;
#[cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))]
mod pwd;
#[cfg(not(target_arch = "wasm32"))]
pub(crate) mod signal;
pub mod sys;
#[cfg(windows)]
mod winapi;
#[cfg(windows)]
mod winreg;

use crate::{builtins::PyModule, PyRef, VirtualMachine};
use std::{borrow::Cow, collections::HashMap};

pub type StdlibInitFunc = Box<py_dyn_fn!(dyn Fn(&VirtualMachine) -> PyRef<PyModule>)>;
pub type StdlibMap = HashMap<Cow<'static, str>, StdlibInitFunc, ahash::RandomState>;

pub fn get_module_inits() -> StdlibMap {
    macro_rules! modules {
        {
            $(
                #[cfg($cfg:meta)]
                { $( $key:expr => $val:expr),* $(,)? }
            )*
        } => {{
            let modules = [
                $(
                    $(#[cfg($cfg)] (Cow::<'static, str>::from($key), Box::new($val) as StdlibInitFunc),)*
                )*
            ];
            modules.into_iter().collect()
        }};
    }
    modules! {
        #[cfg(all())]
        {
            "atexit" => atexit::make_module,
            "_codecs" => codecs::make_module,
            "_collections" => collections::make_module,
            "errno" => errno::make_module,
            "_functools" => functools::make_module,
            "itertools" => itertools::make_module,
            "_io" => io::make_module,
            "marshal" => marshal::make_module,
            "_operator" => operator::make_module,
            "_sre" => sre::make_module,
            "_string" => string::make_module,
            "time" => time::make_module,
            "_weakref" => weakref::make_module,
            "_imp" => imp::make_module,
            "_warnings" => warnings::make_module,
            sys::sysconfigdata_name() => sysconfigdata::make_module,
        }
        // parser related modules:
        #[cfg(feature = "rustpython-ast")]
        {
            "_ast" => ast::make_module,
        }
        // compiler related modules:
        #[cfg(feature = "rustpython-compiler")]
        {
            "symtable" => symtable::make_module,
        }
        #[cfg(any(unix, target_os = "wasi"))]
        {
            "posix" => posix::make_module,
            // "fcntl" => fcntl::make_module,
        }
        // disable some modules on WASM
        #[cfg(not(target_arch = "wasm32"))]
        {
            "_signal" => signal::make_module,
        }
        #[cfg(feature = "threading")]
        {
            "_thread" => thread::make_module,
        }
        // Unix-only
        #[cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))]
        {
            "pwd" => pwd::make_module,
        }
        // Windows-only
        #[cfg(windows)]
        {
            "nt" => nt::make_module,
            "msvcrt" => msvcrt::make_module,
            "_winapi" => winapi::make_module,
            "winreg" => winreg::make_module,
        }
    }
}