You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

rust-numpy依赖的ndarray版本与项目指定版本冲突导致编译失败,寻求兼容ndarray 0.14的解决方案

解决rust-numpy与ndarray 0.14版本冲突的问题

问题复现场景

我按照rust-numpy README中的示例编写Python扩展代码,但由于项目需要配合ndarray-linalg必须使用ndarray 0.14版本,而rust-numpy 0.13默认依赖ndarray 0.15.3,导致编译时出现版本冲突错误。

复现代码

src/lib.rs

use ndarray::{ArrayD, ArrayViewD, ArrayViewMutD};
use numpy::{IntoPyArray, PyArrayDyn, PyReadonlyArrayDyn};
use pyo3::prelude::{pymodule, PyModule, PyResult, Python};

#[pymodule]
fn rust_ext(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
    // immutable example
    fn axpy(a: f64, x: ArrayViewD<'_, f64>, y: ArrayViewD<'_, f64>) -> ArrayD<f64> {
        a * &x + &y
    }

    // mutable example (no return)
    fn mult(a: f64, mut x: ArrayViewMutD<'_, f64>) {
        x *= a;
    }

    // wrapper of `axpy`
    #[pyfn(m, "axpy")]
    fn axpy_py<'py>(
        py: Python<'py>,
        a: f64,
        x: PyReadonlyArrayDyn<f64>,
        y: PyReadonlyArrayDyn<f64>,
    ) -> &'py PyArrayDyn<f64> {
        let x = x.as_array();
        let y = y.as_array();
        axpy(a, x, y).into_pyarray(py)
    }

    // wrapper of `mult`
    #[pyfn(m, "mult")]
    fn mult_py(_py: Python<'_>, a: f64, x: &PyArrayDyn<f64>) -> PyResult<()> {
        let x = unsafe { x.as_array_mut() };
        mult(a, x);
        Ok(())
    }

    Ok(())
}

Cargo.toml

[package]
name = "pyotest"
version = "0.1.0"
edition = "2018"

[dependencies]
pyo3 = { version = "0.13",features=["extension-module"] }
numpy = "0.13"
ndarray = "0.14"

[lib]
name="preprocess"
crate-type = ["cdylib"]

编译错误信息

Compiling pyotest v0.1.0 (/home/bokutotu/pyotesterror)
[E0308]: mismatched types
--> src/lib.rs:50:17
|
50 | axpy(a, x, y).into_pyarray(py)
| ^ expected struct ArrayBase, found struct ndarray::ArrayBase
| = note: expected struct ArrayBase<ViewRepr<&f64>, Dim<IxDynImpl>>
found struct ndarray::ArrayBase<ndarray::ViewRepr<&f64>, ndarray::dimension::dim::Dim<ndarray::dimension::dynindeximpl::IxDynImpl>>
= note: perhaps two different versions of crate ndarray are being used?

error[E0308]: mismatched types
--> src/lib.rs:50:20
|
50 | axpy(a, x, y).into_pyarray(py)
| ^ expected struct ArrayBase, found struct ndarray::ArrayBase
| = note: expected struct ArrayBase<ViewRepr<&f64>, Dim<IxDynImpl>>
found struct ndarray::ArrayBase<ndarray::ViewRepr<&f64>, ndarray::dimension::dim::Dim<ndarray::dimension::dynindeximpl::IxDynImpl>>
= note: perhaps two different versions of crate ndarray are being used?

error[E0599]: no method named into_pyarray found for struct ArrayBase<OwnedRepr<f64>, Dim<IxDynImpl>> in the current scope
--> src/lib.rs:50:23
|
50 | axpy(a, x, y).into_pyarray(py)
| ^^^^^^^^^^^^ method not found in ArrayBase<OwnedRepr<f64>, Dim<IxDynImpl>>

error[E0308]: mismatched types
--> src/lib.rs:57:17
|
57 | mult(a, x);
| ^ expected struct ArrayBase, found struct ndarray::ArrayBase
| = note: expected struct ArrayBase<ViewRepr<&mut f64>, Dim<IxDynImpl>>
found struct ndarray::ArrayBase<ndarray::ViewRepr<&mut f64>, ndarray::dimension::dim::Dim<ndarray::dimension::dynindeximpl::IxDynImpl>>
= note: perhaps two different versions of crate ndarray are being used?

warning: unused import: IntoPyArray
--> src/lib.rs:25:13
|
25 | use numpy::{IntoPyArray, PyArrayDyn, PyReadonlyArrayDyn};
| ^^^^^^^^^^^
| = note: #[warn(unused_imports)] on by default

error: aborting due to 4 previous errors; 1 warning emitted

Some errors have detailed explanations: E0308, E0599.
For more information about an error, try rustc --explain E0308.

error: could not compile pyotest

To learn more, run the command again with --verbose.

Cargo.lock确认版本冲突

从Cargo.lock可以看到,numpy 0.13.2依赖ndarray 0.15.3,而我们的项目显式依赖ndarray 0.14.0,导致两个版本并存:

[[package]]
name = "ndarray"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c0d5c9540a691d153064dc47a4db2504587a75eae07bf1d73f7a596ebc73c04"
dependencies = [
 "matrixmultiply 0.2.4",
 "num-complex 0.3.1",
 "num-integer",
 "num-traits",
 "rawpointer",
]

[[package]]
name = "ndarray"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08e854964160a323e65baa19a0b1a027f76d590faba01f05c0cbc3187221a8c9"
dependencies = [
 "matrixmultiply 0.3.1",
 "num-complex 0.4.0",
 "num-integer",
 "num-traits",
 "rawpointer",
]

[[package]]
name = "numpy"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a996bcd58fb29bef9debf717330cd8876c3b4adbeea4939020a5326a3afad4d9"
dependencies = [
 "cfg-if 0.1.10",
 "libc",
 "ndarray 0.15.3",
 "num-complex 0.4.0",
 "num-traits",
 "pyo3",
]

解决方案

要解决这个版本冲突,我们需要让numpy crate使用我们指定的ndarray 0.14版本,而不是它默认的0.15.3。可以通过Cargo的强制依赖版本功能来实现:

修改Cargo.toml的[dependencies]部分,给numpy添加ndarray的版本强制指定:

[dependencies]
pyo3 = { version = "0.13", features = ["extension-module"] }
numpy = { version = "0.13", dependencies = [
    "ndarray = { version = \"0.14\" }"
] }
ndarray = "0.14"

说明

  • 这里我们显式指定numpy依赖的ndarray版本为0.14,Cargo会优先使用这个版本来满足所有依赖,避免重复编译不同版本的ndarray。
  • 从rust-numpy的版本历史来看,0.13.x版本原本就兼容ndarray 0.14,后来才升级到0.15,所以这个强制指定是安全的。

验证修改

修改完成后,运行cargo update更新依赖,然后查看Cargo.lock,你会发现现在只有ndarray 0.14.0一个版本存在,此时重新编译项目就能正常通过了。

如果遇到num-complex的版本冲突,也可以用同样的方式强制指定版本,比如给numpy的依赖里加上num-complex = "0.3.1"来匹配ndarray 0.14的依赖。


内容的提问来源于stack exchange,提问作者musako

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 20:17:47