Skip to content

Commit c8e353a

Browse files
Peter554claude
andcommitted
Implement FromPyObject for ImportsByModule
Replace the imports_by_module_to_rust helper function with a more idiomatic Rust approach by implementing FromPyObject trait for an ImportsByModule newtype wrapper. This allows using .extract() directly, making the code more ergonomic and following Rust best practices similar to DirectImport. The new ImportsByModule wrapper encapsulates HashMap<Module, HashSet<DirectImport>> and provides automatic conversion from Python dict objects. Addresses PR comment: #259 (comment) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent a25e6df commit c8e353a

1 file changed

Lines changed: 21 additions & 21 deletions

File tree

‎rust/src/caching.rs‎

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::module_finding::Module;
55
use pyo3::types::PyAnyMethods;
66
use pyo3::types::{PyDict, PySet};
77
use pyo3::types::{PyDictMethods, PySetMethods};
8-
use pyo3::{Bound, PyAny, PyResult, Python, pyfunction};
8+
use pyo3::{Bound, FromPyObject, PyAny, PyResult, Python, pyfunction};
99
use std::collections::{HashMap, HashSet};
1010

1111
/// Writes the cache file containing all the imports for a given package.
@@ -21,7 +21,7 @@ pub fn write_cache_data_map_file<'py>(
2121
) -> PyResult<()> {
2222
let mut file_system_boxed = get_file_system_boxed(&file_system)?;
2323

24-
let imports_by_module_rust = imports_by_module_to_rust(imports_by_module);
24+
let ImportsByModule(imports_by_module_rust) = imports_by_module.extract()?;
2525

2626
let file_contents = serialize_imports_by_module(&imports_by_module_rust);
2727

@@ -50,27 +50,27 @@ pub fn read_cache_data_map_file<'py>(
5050
Ok(imports_by_module_to_py(py, imports_by_module))
5151
}
5252

53-
fn imports_by_module_to_rust(
54-
imports_by_module_py: Bound<PyDict>,
55-
) -> HashMap<Module, HashSet<DirectImport>> {
56-
let mut imports_by_module_rust = HashMap::new();
57-
58-
for (py_key, py_value) in imports_by_module_py.iter() {
59-
let module: Module = py_key.extract().unwrap();
60-
let py_set = py_value
61-
.downcast::<PySet>()
62-
.expect("Expected value to be a Python set.");
63-
let mut hashset: HashSet<DirectImport> = HashSet::new();
64-
for element in py_set.iter() {
65-
let direct_import: DirectImport = element
66-
.extract()
67-
.expect("Expected value to be DirectImport.");
68-
hashset.insert(direct_import);
53+
/// A newtype wrapper for HashMap<Module, HashSet<DirectImport>> that implements FromPyObject.
54+
pub struct ImportsByModule(pub HashMap<Module, HashSet<DirectImport>>);
55+
56+
impl<'py> FromPyObject<'py> for ImportsByModule {
57+
fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<Self> {
58+
let py_dict = ob.downcast::<PyDict>()?;
59+
let mut imports_by_module_rust = HashMap::new();
60+
61+
for (py_key, py_value) in py_dict.iter() {
62+
let module: Module = py_key.extract()?;
63+
let py_set = py_value.downcast::<PySet>()?;
64+
let mut hashset: HashSet<DirectImport> = HashSet::new();
65+
for element in py_set.iter() {
66+
let direct_import: DirectImport = element.extract()?;
67+
hashset.insert(direct_import);
68+
}
69+
imports_by_module_rust.insert(module, hashset);
6970
}
70-
imports_by_module_rust.insert(module, hashset);
71-
}
7271

73-
imports_by_module_rust
72+
Ok(ImportsByModule(imports_by_module_rust))
73+
}
7474
}
7575

7676
fn serialize_imports_by_module(

0 commit comments

Comments
 (0)