[artiq] Fix intermittent class resolution failures

In the past, modules (and therefore its members) are not added or
analyzed in order of appearance, as it is stored in a HashMap with the
PythonId as its key.

While this never posed an issue in the past, the refactoring performed
in #535 assumed that the classes *are* ordered by appearance, causing
the bug to manifest. Furthermore, this bug will only manifest
iff a base class has a PythonId greater than the derived class,
explaining why the bug only occurs on occasion.

Fix this by using an IndexMap, which preserves the order of insertion
while also performing deduplication.
This commit is contained in:
David Mak 2025-02-11 17:02:57 +08:00
parent 36d502dc31
commit 6265d53ad5
3 changed files with 5 additions and 2 deletions

1
Cargo.lock generated
View File

@ -646,6 +646,7 @@ dependencies = [
name = "nac3artiq"
version = "0.1.0"
dependencies = [
"indexmap 2.7.1",
"itertools",
"nac3core",
"nac3ld",

View File

@ -9,6 +9,7 @@ name = "nac3artiq"
crate-type = ["cdylib"]
[dependencies]
indexmap = "2.7"
itertools = "0.14"
pyo3 = { version = "0.21", features = ["extension-module", "gil-refs"] }
parking_lot = "0.12"

View File

@ -19,6 +19,7 @@ use std::{
sync::Arc,
};
use indexmap::IndexMap;
use itertools::Itertools;
use parking_lot::{Mutex, RwLock};
use pyo3::{
@ -1218,8 +1219,8 @@ impl Nac3 {
content_modules: &PySet,
) -> PyResult<()> {
let (modules, class_ids) =
Python::with_gil(|py| -> PyResult<(HashMap<u64, PyObject>, HashSet<u64>)> {
let mut modules: HashMap<u64, PyObject> = HashMap::new();
Python::with_gil(|py| -> PyResult<(IndexMap<u64, PyObject>, HashSet<u64>)> {
let mut modules: IndexMap<u64, PyObject> = IndexMap::new();
let mut class_ids: HashSet<u64> = HashSet::new();
let id_fn = PyModule::import(py, "builtins")?.getattr("id")?;