Rust 기반의 PyO3를 사용하여 파이썬 프로젝트 빌드 자동화

Rust는 시스템 수준의 프로그래밍 언어로, 고성능 및 안정성이 요구되는 프로젝트에 적합합니다. 파이썬은 편리한 프로그래밍 언어지만 성능이 중요한 경우 Rust를 사용하여 모듈을 작성할 수 있습니다. 이 글에서는 Rust와 PyO3를 사용하여 파이썬 프로젝트의 빌드 자동화를 어떻게 할 수 있는지 알아보겠습니다.

PyO3란?

PyO3는 Rust와 파이썬 C API를 이용하여 파이썬과 Rust 코드를 연동할 수 있도록 해주는 Rust 라이브러리입니다. PyO3를 사용하면 Rust로 작성한 모듈을 파이썬에서 사용할 수 있게 됩니다.

Rust 환경 설정하기

먼저, Rust를 설치하고 환경을 설정해야 합니다. Rust를 설치하기 위해서는 공식 Rust 웹사이트를 방문하여 설치 방법을 확인할 수 있습니다. 설치가 완료되면, Rust 환경이 제대로 설정되었는지 확인하기 위해 다음 명령어를 실행합니다:

rustc --version

출력되는 결과에서 설치된 Rust의 버전을 확인할 수 있어야 합니다.

PyO3 프로젝트 생성하기

PyO3로 파이썬 프로젝트를 빌드하려면 먼저 PyO3 프로젝트를 생성해야 합니다. 프로젝트를 생성하기 위해 프로젝트 디렉토리로 이동한 후 다음 명령어를 실행합니다:

cargo init --lib my_project

이 명령어는 my_project라는 이름을 가진 Rust 프로젝트를 생성합니다. --lib 플래그는 라이브러리 프로젝트를 생성한다는 것을 나타냅니다.

PyO3 종속성 추가하기

프로젝트를 생성한 후, Cargo.toml 파일을 열어 PyO3 종속성을 추가해야 합니다. 다음과 같이 Cargo.toml 파일을 수정합니다:

[dependencies]
pyo3 = "0.15"

pyo3는 PyO3 라이브러리의 버전을 지정하는 부분입니다. 이 예제에서는 0.15 버전을 사용하고 있습니다. 필요에 따라 최신 버전을 사용할 수 있습니다.

Rust 모듈 작성하기

이제 Rust 모듈을 작성해보겠습니다. src/lib.rs 파일을 열어 다음 코드를 추가합니다:

use pyo3::prelude::*;
use pyo3::types::IntoPyDict;

#[pymodule]
fn my_module(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(greet, m)?)?;
    Ok(())
}

#[pyfunction]
fn greet() -> PyResult<String> {
    Ok("Hello from Rust!".to_string())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_greet() {
        assert_eq!(greet().unwrap(), "Hello from Rust!");
    }
}

#[pymodule]
fn my_project(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_module_with_methods::<my_module>()?;
    Ok(())
}

#[pymodule]
fn rust_module(py: Python, m: &PyModule) -> PyResult<()> {
    my_project(py, m)?;
    Ok(())
}

#[pymodule]
fn my_project_rust_module(py: Python, m: &PyModule) -> PyResult<()> {
    rust_module(py, m)?;
    Ok(())
}

#[pymodule]
fn _my_project_rust(py: Python, m: &PyModule) -> PyResult<()> {
    my_project_rust_module(py, m)?;
    Ok(())
}

/// Python 모듈의 진입점
#[pymodule]
fn my_project_rust(py: Python, m: &PyModule) -> PyResult<()> {
    let locals = [("my_module", "my_project_rust.my_module")].into_py_dict(py);
    m.add("__name__", "my_project_rust")?;
    m.add("__doc__", "My rust project.")?;
    m.add("__package__", "my_project_rust")?;
    m.add_locals(locals)?;
    Ok(())
}

이 코드는 greet라는 함수를 가진 Rust 모듈을 정의하고, PyO3로 모듈을 만들기 위한 필요한 함수들을 정의합니다.

PyO3 모듈 빌드 및 사용하기

이제 PyO3 모듈을 빌드하고 사용해보겠습니다. 프로젝트 디렉토리에서 다음 명령어를 실행합니다:

cargo build --release

빌드가 완료되면, target/release 디렉토리에 libmy_project_rust.so (또는 libmy_project_rust.dylib 또는 my_project_rust.dll) 파일이 생성됩니다.

이제 이 파일을 파이썬에서 사용해보겠습니다. 다음과 같이 파이썬 스크립트를 작성합니다:

import my_project_rust

print(my_project_rust.my_module.greet())

위 스크립트를 실행하면 “Hello from Rust!”가 출력됩니다.

결론

이렇게 PyO3와 Rust를 사용하여 파이썬 프로젝트의 빌드 자동화를 할 수 있습니다. Rust의 고성능과 안정성을 활용하여 파이썬 프로젝트의 성능을 향상시킬 수 있습니다. Rust와 PyO3를 함께 사용하면 다양한 가능성이 열립니다.

#Rust #PyO3