diff --git a/crates/capi/src/pylifecycle.rs b/crates/capi/src/pylifecycle.rs index de673b33f0a..534c97956fe 100644 --- a/crates/capi/src/pylifecycle.rs +++ b/crates/capi/src/pylifecycle.rs @@ -4,7 +4,8 @@ use crate::pystate::ensure_thread_has_vm_attached; use alloc::ffi::CString; use core::ffi::{c_char, c_int, c_ulong}; use rustpython_vm::common::rc::PyRc; -use rustpython_vm::version::{MAJOR, MICRO, MINOR, VERSION_HEX}; +use rustpython_vm::stdlib::sys; +use rustpython_vm::version::{MAJOR, MICRO, MINOR, RUSTPYTHON_BUILD_INFO, VERSION_HEX}; use rustpython_vm::vm::thread::ThreadedVirtualMachine; use rustpython_vm::{Context, Interpreter}; use std::sync::{LazyLock, Mutex}; @@ -80,6 +81,29 @@ pub extern "C" fn Py_GetVersion() -> *const c_char { VERSION.as_ptr() } +#[unsafe(no_mangle)] +pub extern "C" fn Py_GetBuildInfo() -> *const c_char { + static BUILD_INFO: LazyLock = LazyLock::new(|| { + CString::new(RUSTPYTHON_BUILD_INFO).expect("build info must not contain interior NULs") + }); + BUILD_INFO.as_ptr() +} + +#[unsafe(no_mangle)] +pub extern "C" fn Py_GetCompiler() -> *const c_char { + c"[RUST]".as_ptr() +} + +#[unsafe(no_mangle)] +pub extern "C" fn Py_GetCopyright() -> *const c_char { + sys::COPYRIGHT.as_ptr() +} + +#[unsafe(no_mangle)] +pub extern "C" fn Py_GetPlatform() -> *const c_char { + sys::PLATFORM.as_ptr() +} + #[cfg(test)] mod tests { use pyo3::prelude::*; diff --git a/crates/vm/src/builtins/str.rs b/crates/vm/src/builtins/str.rs index a72a272679b..52307d2624b 100644 --- a/crates/vm/src/builtins/str.rs +++ b/crates/vm/src/builtins/str.rs @@ -35,6 +35,7 @@ use crate::{ use alloc::{borrow::Cow, fmt}; use ascii::{AsciiChar, AsciiStr, AsciiString}; use bstr::ByteSlice; +use core::ffi::CStr; use core::{char, mem, ops::Range}; use itertools::Itertools; use num_traits::ToPrimitive; @@ -1868,6 +1869,13 @@ impl ToPyObject for &String { } } +impl ToPyObject for &CStr { + fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { + let s = self.to_str().expect("ToPyObject expects utf-8 CStr"); + vm.ctx.new_str(s).into() + } +} + impl ToPyObject for &Wtf8 { fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { vm.ctx.new_str(self).into() diff --git a/crates/vm/src/stdlib/sys.rs b/crates/vm/src/stdlib/sys.rs index b8fe578f238..8f19b99560e 100644 --- a/crates/vm/src/stdlib/sys.rs +++ b/crates/vm/src/stdlib/sys.rs @@ -4,6 +4,7 @@ use crate::{Py, PyPayload, PyResult, VirtualMachine, builtins::PyModule, convert #[cfg(all(not(feature = "host_env"), feature = "stdio"))] pub(crate) use sys::SandboxStdio; +pub use sys::{COPYRIGHT, PLATFORM, VERSION}; pub(crate) use sys::{DOC, MAXSIZE, RUST_MULTIARCH, UnraisableHookArgsData, module_def, multiarch}; #[pymodule(name = "_jit")] @@ -50,6 +51,7 @@ pub mod sys { version, vm::{Settings, VirtualMachine}, }; + use core::ffi::CStr; use core::sync::atomic::Ordering; use num_traits::ToPrimitive; use std::{ @@ -222,7 +224,7 @@ pub mod sys { #[pyattr(name = "api_version")] const API_VERSION: u32 = 0x0; // what C api? #[pyattr(name = "copyright")] - const COPYRIGHT: &str = "Copyright (c) 2019 RustPython Team"; + pub const COPYRIGHT: &CStr = c"Copyright (c) 2019 RustPython Team"; #[pyattr(name = "float_repr_style")] const FLOAT_REPR_STYLE: &str = "short"; #[pyattr(name = "_framework")] @@ -235,14 +237,14 @@ pub mod sys { const MAXUNICODE: u32 = core::char::MAX as u32; #[pyattr(name = "platform")] - pub const PLATFORM: &str = cfg_select! { - target_os = "linux" => "linux", - target_os = "android" => "android", - target_os = "macos" => "darwin", - target_os = "ios" => "ios", - windows => "win32", - target_os = "wasi" => "wasi", - _ => "unknown" + pub const PLATFORM: &CStr = cfg_select! { + target_os = "linux" => c"linux", + target_os = "android" => c"android", + target_os = "macos" => c"darwin", + target_os = "ios" => c"ios", + windows => c"win32", + target_os = "wasi" => c"wasi", + _ => c"unknown" }; #[pyattr(name = "ps1")] @@ -708,7 +710,7 @@ pub mod sys { } #[pyattr(name = "version")] - const VERSION: &str = version::RUSTPYTHON_VERSION; + pub const VERSION: &str = version::RUSTPYTHON_VERSION; // Note: This is Python DLL version in CPython, but we arbitrary fill it for compatibility #[cfg(windows)] @@ -1911,7 +1913,7 @@ pub(crate) fn sysconfigdata_name() -> String { format!( "_sysconfigdata_{}_{}_{}", sys::ABIFLAGS, - sys::PLATFORM, + sys::PLATFORM.to_string_lossy(), sys::multiarch() ) }