diff --git a/eden/scm/edenscmnative/bindings/Cargo.toml b/eden/scm/edenscmnative/bindings/Cargo.toml index 2f58ee033a..a528039a44 100644 --- a/eden/scm/edenscmnative/bindings/Cargo.toml +++ b/eden/scm/edenscmnative/bindings/Cargo.toml @@ -32,6 +32,7 @@ pydirs = { path = "modules/pydirs" } pyeagerepo = { path = "modules/pyeagerepo" } pyedenapi = { path = "modules/pyedenapi" } pyerror = { path = "modules/pyerror" } +pyfail = { path = "modules/pyfail" } pyfs = { path = "modules/pyfs" } pyhgmetrics = { path = "modules/pyhgmetrics" } pyhgtime = { path = "modules/pyhgtime" } diff --git a/eden/scm/edenscmnative/bindings/modules/pyfail/Cargo.toml b/eden/scm/edenscmnative/bindings/modules/pyfail/Cargo.toml new file mode 100644 index 0000000000..5d690a1732 --- /dev/null +++ b/eden/scm/edenscmnative/bindings/modules/pyfail/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "pyfail" +version = "0.1.0" +edition = "2018" + +[dependencies] +cpython_ext = { path = "../../../../lib/cpython-ext", default-features = false } +cpython = { version = "0.5", default-features = false } +fail = "0.4" + +[features] +default = [] +python2 = ["cpython/python27-sys", "cpython_ext/python2"] +python3 = ["cpython/python3-sys", "cpython_ext/python3"] diff --git a/eden/scm/edenscmnative/bindings/modules/pyfail/src/lib.rs b/eden/scm/edenscmnative/bindings/modules/pyfail/src/lib.rs new file mode 100644 index 0000000000..c2fea7e544 --- /dev/null +++ b/eden/scm/edenscmnative/bindings/modules/pyfail/src/lib.rs @@ -0,0 +1,32 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This software may be used and distributed according to the terms of the + * GNU General Public License version 2. + */ + +use cpython::*; +use cpython_ext::PyNone; +use std::io; + +pub fn init_module(py: Python, package: &str) -> PyResult { + let name = [package, "fail"].join("."); + let m = PyModule::new(py, &name)?; + m.add(py, "failpoint", py_fn!(py, failpoint(name: &str)))?; + Ok(m) +} + +fn failpoint(py: Python, name: &str) -> PyResult { + if let Some(e) = fail::eval(name, |_| fail_error(name)) { + Err(cpython_ext::error::translate_io_error(py, &e).into()) + } else { + Ok(PyNone) + } +} + +fn fail_error(name: &str) -> io::Error { + io::Error::new( + io::ErrorKind::Other, + format!("failpoint '{}' set by FAILPOINTS", name), + ) +} diff --git a/eden/scm/edenscmnative/bindings/src/modules.rs b/eden/scm/edenscmnative/bindings/src/modules.rs index 95e40d3cb7..29c681a234 100644 --- a/eden/scm/edenscmnative/bindings/src/modules.rs +++ b/eden/scm/edenscmnative/bindings/src/modules.rs @@ -30,6 +30,7 @@ pub(crate) fn populate_module(py: Python<'_>, module: &PyModule) -> PyResult