view rust/hg-cpython/src/utils.rs @ 47202:0de5eefbe4b2

contrib: install PyOxidizer 0.16.0 PyOxidizer now provides MSI installers and pre-built Linux binaries. So we install that way. This significantly reduces the time to bootstrap a new machine in automation, as building PyOxidizer from source on a low core count machine takes several minutes. This change temporarily breaks the ability of the automated environment to use the in-repo pyoxidizer.bzl configuration file, as there are backwards-incompatible changes with the upgrade that need to be reflected. We'll handle those in subsequent commits. Differential Revision: https://phab.mercurial-scm.org/D10680
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 06 May 2021 15:56:04 -0700
parents 26114bd6ec60
children c7fb9b74e753
line wrap: on
line source

use cpython::exc::ValueError;
use cpython::{PyBytes, PyDict, PyErr, PyObject, PyResult, PyTuple, Python};
use hg::revlog::Node;
use std::convert::TryFrom;

#[allow(unused)]
pub fn print_python_trace(py: Python) -> PyResult<PyObject> {
    eprintln!("===============================");
    eprintln!("Printing Python stack from Rust");
    eprintln!("===============================");
    let traceback = py.import("traceback")?;
    let sys = py.import("sys")?;
    let kwargs = PyDict::new(py);
    kwargs.set_item(py, "file", sys.get(py, "stderr")?)?;
    traceback.call(py, "print_stack", PyTuple::new(py, &[]), Some(&kwargs))
}

// Necessary evil for the time being, could maybe be moved to
// a TryFrom in Node itself
const NODE_BYTES_LENGTH: usize = 20;
type NodeData = [u8; NODE_BYTES_LENGTH];

/// Copy incoming Python bytes given as `PyObject` into `Node`,
/// doing the necessary checks
pub fn node_from_py_object<'a>(
    py: Python,
    bytes: &'a PyObject,
) -> PyResult<Node> {
    let as_py_bytes: &'a PyBytes = bytes.extract(py)?;
    node_from_py_bytes(py, as_py_bytes)
}

/// Clone incoming Python bytes given as `PyBytes` as a `Node`,
/// doing the necessary checks.
pub fn node_from_py_bytes(py: Python, bytes: &PyBytes) -> PyResult<Node> {
    <NodeData>::try_from(bytes.data(py))
        .map_err(|_| {
            PyErr::new::<ValueError, _>(
                py,
                format!("{}-byte hash required", NODE_BYTES_LENGTH),
            )
        })
        .map(Into::into)
}