From 6265d53ad552b818e9df41298f0cafbee9b89397 Mon Sep 17 00:00:00 2001 From: David Mak Date: Tue, 11 Feb 2025 17:02:57 +0800 Subject: [PATCH] [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. --- Cargo.lock | 1 + nac3artiq/Cargo.toml | 1 + nac3artiq/src/lib.rs | 5 +++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9435fed..4bb9a6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -646,6 +646,7 @@ dependencies = [ name = "nac3artiq" version = "0.1.0" dependencies = [ + "indexmap 2.7.1", "itertools", "nac3core", "nac3ld", diff --git a/nac3artiq/Cargo.toml b/nac3artiq/Cargo.toml index fa80465..2bceb4d 100644 --- a/nac3artiq/Cargo.toml +++ b/nac3artiq/Cargo.toml @@ -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" diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index 2383046..1dee8dd 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -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, HashSet)> { - let mut modules: HashMap = HashMap::new(); + Python::with_gil(|py| -> PyResult<(IndexMap, HashSet)> { + let mut modules: IndexMap = IndexMap::new(); let mut class_ids: HashSet = HashSet::new(); let id_fn = PyModule::import(py, "builtins")?.getattr("id")?;