Skip to content

Commit ceaefd5

Browse files
authored
Fix __init__ exports when using multiple UniFFI bindings (#2305)
1 parent 11d0dd7 commit ceaefd5

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

src/module_writer.rs

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use fs_err::OpenOptions;
1818
use ignore::overrides::Override;
1919
use ignore::WalkBuilder;
2020
use indexmap::IndexMap;
21+
use itertools::Itertools;
2122
use normpath::PathExt as _;
2223
use same_file::is_same_file;
2324
use sha2::{Digest, Sha256};
@@ -971,7 +972,7 @@ struct UniFfiBindingsConfig {
971972

972973
#[derive(Debug, Clone)]
973974
struct UniFfiBindings {
974-
name: String,
975+
names: Vec<String>,
975976
cdylib: String,
976977
path: PathBuf,
977978
}
@@ -1111,8 +1112,25 @@ fn generate_uniffi_bindings(
11111112
_ => format!("lib{cdylib_name}.so"),
11121113
};
11131114

1115+
let py_bindings = fs::read_dir(&binding_dir)?
1116+
.flatten()
1117+
.filter(|file| {
1118+
file.path()
1119+
.extension()
1120+
.and_then(std::ffi::OsStr::to_str)
1121+
.map_or(false, |ext| ext == "py")
1122+
})
1123+
.map(|file| {
1124+
file.path()
1125+
.file_stem()
1126+
.unwrap()
1127+
.to_string_lossy()
1128+
.to_string()
1129+
})
1130+
.collect_vec();
1131+
11141132
Ok(UniFfiBindings {
1115-
name: py_binding_name,
1133+
names: py_bindings,
11161134
cdylib,
11171135
path: binding_dir,
11181136
})
@@ -1132,11 +1150,16 @@ pub fn write_uniffi_module(
11321150
pyproject_toml: Option<&PyProjectToml>,
11331151
) -> Result<()> {
11341152
let UniFfiBindings {
1135-
name: binding_name,
1153+
names: binding_names,
11361154
cdylib,
11371155
path: binding_dir,
11381156
} = generate_uniffi_bindings(crate_dir, target_dir, target_os, artifact)?;
1139-
let py_init = format!("from .{binding_name} import * # NOQA\n");
1157+
1158+
let py_init = binding_names
1159+
.iter()
1160+
.map(|name| format!("from .{name} import * # NOQA\n"))
1161+
.collect::<Vec<String>>()
1162+
.join("");
11401163

11411164
if !editable {
11421165
write_python_part(writer, project_layout, pyproject_toml)
@@ -1156,13 +1179,13 @@ pub fn write_uniffi_module(
11561179
))?;
11571180

11581181
File::create(base_path.join("__init__.py"))?.write_all(py_init.as_bytes())?;
1159-
if let Ok(read_dir) = fs::read_dir(&binding_dir) {
1160-
for binding_file in read_dir.flatten() {
1161-
let target: PathBuf = base_path.join(binding_file.file_name());
1162-
fs::copy(binding_file.path(), &target).with_context(|| {
1163-
format!("Failed to copy {:?} to {:?}", binding_file.path(), target)
1182+
1183+
for binding_name in binding_names.iter() {
1184+
let target: PathBuf = base_path.join(binding_name).with_extension("py");
1185+
fs::copy(binding_dir.join(binding_name).with_extension("py"), &target)
1186+
.with_context(|| {
1187+
format!("Failed to copy {:?} to {:?}", binding_dir.display(), target)
11641188
})?;
1165-
}
11661189
}
11671190
}
11681191

@@ -1189,10 +1212,11 @@ pub fn write_uniffi_module(
11891212

11901213
if !editable || project_layout.python_module.is_none() {
11911214
writer.add_bytes(module.join("__init__.py"), None, py_init.as_bytes())?;
1192-
if let Ok(read_dir) = fs::read_dir(binding_dir) {
1193-
for binding_file in read_dir.flatten() {
1194-
writer.add_file(module.join(binding_file.file_name()), binding_file.path())?;
1195-
}
1215+
for binding in binding_names.iter() {
1216+
writer.add_file(
1217+
module.join(binding).with_extension("py"),
1218+
binding_dir.join(binding).with_extension("py"),
1219+
)?;
11961220
}
11971221
writer.add_file_with_permissions(module.join(cdylib), artifact, 0o755)?;
11981222
}

0 commit comments

Comments
 (0)