rust/hg-pyo3/src/lib.rs
author Georges Racinet <georges.racinet@cloudcrane.io>
Sat, 30 Nov 2024 20:57:02 +0100
changeset 52411 c2480ac4c5e2
parent 52409 a642c0a3860f
child 52531 4c9e31984b3a
permissions -rw-r--r--
rust-pyo3: retrieving the InnerRevlog of hg-cpython This allows PyO3-based code to use the InnerRevlog, access its shared data (core InnerRevlog), which will then allow, e.g., to retrieve references on the core Index. On the `hg-cpython` (`rusthg` crate, `rustext` Python extension module), we had to also build as a Rust library, and open up some accesses (see notably the public accessor for `inner`, the core `InnerRevlog`). Retrieving the Rust struct underlying a Python object defined by another extension module written in Rust is tricky because the Python type objects are duplicated in the extension modules, leading to failure of the normal type checking. See the doc-comment of `convert_cpython::extract_inner_revlog` for a complete explanation. To solve this, we import the Python type object of `rustext` (defined by `hg-cpython`) and perform a manual check. Checking the Python type is necessary, as PyO3 documentation clearly state that downcasting an object that has not the proper type is Undefined Behaviour. At this point, we do not have conversion facilities for exceptions (`PyErr` on both sides), hence the remaining unwraps).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52402
6673cec8605c rust: add PyO3 based Rust extension module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     1
use pyo3::prelude::*;
6673cec8605c rust: add PyO3 based Rust extension module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     2
52411
c2480ac4c5e2 rust-pyo3: retrieving the InnerRevlog of hg-cpython
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52409
diff changeset
     3
mod convert_cpython;
52407
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
     4
mod dagops;
52408
20c0472b2ab7 rust-pyo3: defining GraphError
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
     5
mod exceptions;
52409
a642c0a3860f rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52408
diff changeset
     6
mod revision;
52407
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
     7
mod util;
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
     8
52402
6673cec8605c rust: add PyO3 based Rust extension module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     9
#[pymodule]
52407
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
    10
fn pyo3_rustext(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
    11
    m.add(
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
    12
        "__doc__",
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
    13
        "Mercurial core concepts - Rust implementation exposed via PyO3",
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
    14
    )?;
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
    15
    // the module's __name__ is pyo3_rustext, not mercurial.pyo3_rustext
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
    16
    // (at least at this point).
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
    17
    let name: String = m.getattr("__name__")?.extract()?;
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
    18
    let dotted_name = format!("mercurial.{}", name);
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
    19
c5128c541021 rust-pyo3: facility for submodule registration, using it for dagop
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52403
diff changeset
    20
    m.add_submodule(&dagops::init_module(py, &dotted_name)?)?;
52408
20c0472b2ab7 rust-pyo3: defining GraphError
Georges Racinet <georges.racinet@cloudcrane.io>
parents: 52407
diff changeset
    21
    m.add("GraphError", py.get_type::<exceptions::GraphError>())?;
52402
6673cec8605c rust: add PyO3 based Rust extension module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    22
    Ok(())
6673cec8605c rust: add PyO3 based Rust extension module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    23
}