Skip to main content

sim_lib_lang_python/
profile.rs

1use sim_kernel::{Cx, Result, Symbol};
2use sim_lib_standard_core::{
3    LanguageProfile, OrganUse, ProfileBackingLib, ProfileRegistry, install_language_profile,
4};
5
6/// Stable symbol for the thin Python core profile.
7pub fn python_profile_symbol() -> Symbol {
8    Symbol::qualified("lang", "python-core/v1")
9}
10fn reader() -> Symbol {
11    Symbol::qualified("codec", "python")
12}
13fn lowering() -> Symbol {
14    Symbol::qualified("python", "token-lowering/v1")
15}
16fn eval_policy() -> Symbol {
17    Symbol::qualified("python", "direct-eval/v1")
18}
19
20/// Build the Python core profile, including capabilities and inspectable gaps.
21pub fn python_core_profile() -> LanguageProfile {
22    LanguageProfile::new(python_profile_symbol())
23        .with_reader(reader())
24        .with_lowering(lowering())
25        .with_eval_policy(eval_policy())
26        .with_organ(OrganUse::new(sim_lib_binding::binding_organ_symbol()))
27        .with_organ(OrganUse::new(sim_lib_control::control_organ_symbol()))
28        .with_organ(OrganUse::new(sim_lib_mutation::mutation_organ_symbol()))
29        .with_organ(OrganUse::new(sim_lib_sequence::sequence_organ_symbol()))
30        .with_organ(OrganUse::new(sim_lib_dispatch::dispatch_organ_symbol()))
31        .requiring(sim_lib_mutation::standard_mutate_capability())
32        .with_unsupported_form(Symbol::qualified("python", "bytecode"))
33        .with_unsupported_form(Symbol::qualified("python", "foreign-runtime"))
34        .with_unsupported_form(Symbol::qualified("python", "annotation-check-pass"))
35        .with_unsupported_form(Symbol::qualified("python", "retain-policy-leaks-cycles"))
36}
37
38/// Install the profile. Collection is a runtime policy option, never a load prerequisite.
39pub fn install_python_core_profile(
40    cx: &mut Cx,
41    registry: &mut ProfileRegistry,
42) -> Result<LanguageProfile> {
43    install_language_profile(
44        cx,
45        registry,
46        python_core_profile(),
47        &[
48            ProfileBackingLib::loadable(
49                sim_lib_binding::binding_organ_symbol(),
50                sim_lib_binding::manifest_name(),
51                sim_lib_binding::install_binding_lib,
52                Some(sim_lib_binding::publish_binding_organ_claims_for_lib),
53            ),
54            ProfileBackingLib::loadable(
55                sim_lib_control::control_organ_symbol(),
56                sim_lib_control::manifest_name(),
57                sim_lib_control::install_control_lib,
58                None,
59            ),
60            ProfileBackingLib::unresolved(
61                sim_lib_mutation::mutation_organ_symbol(),
62                Symbol::qualified("sim", "mutation"),
63            ),
64            ProfileBackingLib::loadable(
65                sim_lib_sequence::sequence_organ_symbol(),
66                sim_lib_sequence::manifest_name(),
67                sim_lib_sequence::install_sequence_lib,
68                Some(sim_lib_sequence::publish_sequence_organ_claims_for_lib),
69            ),
70            ProfileBackingLib::unresolved(
71                sim_lib_dispatch::dispatch_organ_symbol(),
72                Symbol::qualified("sim", "dispatch"),
73            ),
74        ],
75        &[],
76    )
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82    #[test]
83    fn profile_declares_complete_runtime_evidence() {
84        let evidence = python_core_profile().checked_guest_evidence().unwrap();
85        assert_eq!(evidence.reader, reader());
86        assert_eq!(evidence.organs.len(), 5);
87        assert_eq!(evidence.capabilities.len(), 1);
88        assert_eq!(evidence.gaps.len(), 4);
89    }
90}