Skip to content

Commit b48fe63

Browse files
Fix sys.implementation
`sys.version_info` and `sys.implementation` are two different versioning schemes. `version_info` refers to the target Python version while `implementation` refers to the implementation version. For RustPython, `version_info` should be 3.14 because it currently targets Python 3.14. This was correct and remains unchanged. `implementation`, however, should be set to RustPython's version. I updated the code to correctly get RustPython's version from the environment. I also ensured values are hard coded at build time which reduces the overall code that needs to be run at runtime as well as removes some unneeded allocations. Closes: #7770
1 parent e10a27b commit b48fe63

2 files changed

Lines changed: 41 additions & 38 deletions

File tree

‎crates/vm/src/stdlib/sys.rs‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -660,22 +660,22 @@ pub mod sys {
660660
vm.new_tuple((
661661
ascii!("RustPython"),
662662
version::get_git_identifier(),
663-
version::get_git_revision(),
663+
version::GIT_REVISION,
664664
))
665665
}
666666

667667
#[pyattr]
668668
fn implementation(vm: &VirtualMachine) -> PyRef<PyNamespace> {
669669
const NAME: &str = "rustpython";
670670

671-
let cache_tag = format!("{NAME}-{}{}", version::MAJOR, version::MINOR);
671+
let cache_tag = format!("{NAME}-{}{}", version::MAJOR_IMPL, version::MINOR_IMPL);
672672
let ctx = &vm.ctx;
673673
py_namespace!(vm, {
674674
"name" => ctx.new_str(NAME),
675675
"cache_tag" => ctx.new_str(cache_tag),
676676
"_multiarch" => ctx.new_str(multiarch()),
677-
"version" => version_info(vm),
678-
"hexversion" => ctx.new_int(version::VERSION_HEX),
677+
"version" => PyVersionInfo::from_data(VersionInfoData::IMPLEMENTATION, vm),
678+
"hexversion" => ctx.new_int(version::VERSION_HEX_IMPL),
679679
"supports_isolated_interpreters" => ctx.new_bool(false),
680680
})
681681
}
@@ -1758,6 +1758,14 @@ pub mod sys {
17581758
releaselevel: version::RELEASELEVEL,
17591759
serial: version::SERIAL,
17601760
};
1761+
1762+
pub const IMPLEMENTATION: Self = Self {
1763+
major: version::MAJOR_IMPL,
1764+
minor: version::MINOR_IMPL,
1765+
micro: version::MICRO_IMPL,
1766+
releaselevel: version::RELEASELEVEL,
1767+
serial: version::SERIAL,
1768+
};
17611769
}
17621770

17631771
#[pystruct_sequence(name = "version_info", data = "VersionInfoData", no_attr)]

‎crates/vm/src/version.rs‎

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,29 @@ pub const MICRO: usize = 0;
1111
pub const RELEASELEVEL: &str = "alpha";
1212
pub const RELEASELEVEL_N: usize = 0xA;
1313
pub const SERIAL: usize = 0;
14-
1514
pub const VERSION_HEX: usize =
1615
(MAJOR << 24) | (MINOR << 16) | (MICRO << 8) | (RELEASELEVEL_N << 4) | SERIAL;
1716

17+
pub const GIT_REVISION: &str = env!("RUSTPYTHON_GIT_HASH");
18+
const GIT_TAG: &str = env!("RUSTPYTHON_GIT_TAG");
19+
const GIT_BRANCH: &str = env!("RUSTPYTHON_GIT_BRANCH");
20+
21+
// RustPython version
22+
pub const MAJOR_IMPL: usize = match usize::from_str_radix(env!("CARGO_PKG_VERSION_MAJOR"), 10) {
23+
Ok(v) => v,
24+
Err(_) => panic!("Compile with Cargo to get 'CARGO_PKG_VERSION_MAJOR'"),
25+
};
26+
pub const MINOR_IMPL: usize = match usize::from_str_radix(env!("CARGO_PKG_VERSION_MINOR"), 10) {
27+
Ok(v) => v,
28+
Err(_) => panic!("Compile with Cargo to get 'CARGO_PKG_VERSION_MINOR'"),
29+
};
30+
pub const MICRO_IMPL: usize = match usize::from_str_radix(env!("CARGO_PKG_VERSION_PATCH"), 10) {
31+
Ok(v) => v,
32+
Err(_) => panic!("Compile with Cargo to get 'CARGO_PKG_VERSION_PATCH'"),
33+
};
34+
pub const VERSION_HEX_IMPL: usize =
35+
(MAJOR_IMPL << 24) | (MINOR_IMPL << 16) | (MICRO_IMPL << 8) | (RELEASELEVEL_N << 4) | SERIAL;
36+
1837
#[must_use]
1938
pub fn get_version() -> String {
2039
// Windows: include MSC v. for compatibility with ctypes.util.find_library
@@ -57,59 +76,35 @@ const COMPILER: &str = env!("RUSTC_VERSION");
5776
#[must_use]
5877
pub fn get_build_info() -> String {
5978
// See: https://reproducible-builds.org/docs/timestamps/
60-
let git_revision = get_git_revision();
61-
let separator = if git_revision.is_empty() { "" } else { ":" };
62-
79+
let separator = if GIT_REVISION.is_empty() { "" } else { ":" };
6380
let git_identifier = get_git_identifier();
6481

6582
format!(
6683
"{id}{sep}{revision}, {date:.20}, {time:.9}",
6784
id = if git_identifier.is_empty() {
68-
"default".to_owned()
85+
"default"
6986
} else {
7087
git_identifier
7188
},
7289
sep = separator,
73-
revision = git_revision,
90+
revision = GIT_REVISION,
7491
date = get_git_date(),
7592
time = get_git_time(),
7693
)
7794
}
7895

7996
#[must_use]
80-
pub fn get_git_revision() -> String {
81-
option_env!("RUSTPYTHON_GIT_HASH").unwrap_or("").to_owned()
82-
}
83-
84-
#[must_use]
85-
pub fn get_git_tag() -> String {
86-
option_env!("RUSTPYTHON_GIT_TAG").unwrap_or("").to_owned()
87-
}
88-
89-
#[must_use]
90-
pub fn get_git_branch() -> String {
91-
option_env!("RUSTPYTHON_GIT_BRANCH")
92-
.unwrap_or("")
93-
.to_owned()
94-
}
95-
96-
#[must_use]
97-
pub fn get_git_identifier() -> String {
98-
let git_tag = get_git_tag();
99-
let git_branch = get_git_branch();
100-
101-
if git_tag.is_empty() || git_tag == "undefined" {
102-
git_branch
97+
pub const fn get_git_identifier() -> &'static str {
98+
if GIT_TAG.is_empty() || GIT_TAG.eq_ignore_ascii_case("undefined") {
99+
GIT_BRANCH
103100
} else {
104-
git_tag
101+
GIT_TAG
105102
}
106103
}
107104

108105
fn get_git_timestamp_datetime() -> DateTime<Local> {
109-
let timestamp = option_env!("RUSTPYTHON_GIT_TIMESTAMP")
110-
.unwrap_or("")
111-
.to_owned();
112-
let timestamp = timestamp.parse::<u64>().unwrap_or(0);
106+
let timestamp = option_env!("RUSTPYTHON_GIT_TIMESTAMP").unwrap_or_default();
107+
let timestamp = timestamp.parse::<u64>().unwrap_or_default();
113108

114109
let datetime = UNIX_EPOCH + Duration::from_secs(timestamp);
115110

0 commit comments

Comments
 (0)