author | Pierre-Yves David <pierre-yves.david@octobus.net> |
Tue, 11 Mar 2025 02:29:42 +0100 | |
branch | stable |
changeset 53042 | cdd7bf612c7b |
parent 52213 | 96b113d22b34 |
permissions | -rw-r--r-- |
52213
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
1 |
use cpython::exc::{KeyboardInterrupt, ValueError}; |
52046
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
2 |
use cpython::{ |
52213
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
3 |
ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyObject, PyResult, |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
4 |
PyTuple, Python, ToPyObject, |
52046
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
5 |
}; |
52042
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
6 |
use hg::config::Config; |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
7 |
use hg::errors::HgError; |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
8 |
use hg::repo::{Repo, RepoError}; |
44505
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
9 |
use hg::revlog::Node; |
52042
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
10 |
use hg::utils::files::get_path_from_bytes; |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
11 |
|
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
12 |
use crate::exceptions::FallbackError; |
43251
970978975574
rust-utils: introduce a debug util to print the python stack trace
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
13 |
|
970978975574
rust-utils: introduce a debug util to print the python stack trace
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
14 |
#[allow(unused)] |
970978975574
rust-utils: introduce a debug util to print the python stack trace
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
15 |
pub fn print_python_trace(py: Python) -> PyResult<PyObject> { |
970978975574
rust-utils: introduce a debug util to print the python stack trace
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
16 |
eprintln!("==============================="); |
970978975574
rust-utils: introduce a debug util to print the python stack trace
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
17 |
eprintln!("Printing Python stack from Rust"); |
970978975574
rust-utils: introduce a debug util to print the python stack trace
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
18 |
eprintln!("==============================="); |
970978975574
rust-utils: introduce a debug util to print the python stack trace
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
19 |
let traceback = py.import("traceback")?; |
970978975574
rust-utils: introduce a debug util to print the python stack trace
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
20 |
let sys = py.import("sys")?; |
970978975574
rust-utils: introduce a debug util to print the python stack trace
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
21 |
let kwargs = PyDict::new(py); |
970978975574
rust-utils: introduce a debug util to print the python stack trace
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
22 |
kwargs.set_item(py, "file", sys.get(py, "stderr")?)?; |
970978975574
rust-utils: introduce a debug util to print the python stack trace
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
23 |
traceback.call(py, "print_stack", PyTuple::new(py, &[]), Some(&kwargs)) |
970978975574
rust-utils: introduce a debug util to print the python stack trace
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
24 |
} |
44505
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
25 |
|
52042
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
26 |
pub fn hgerror_to_pyerr<T>( |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
27 |
py: Python, |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
28 |
error: Result<T, HgError>, |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
29 |
) -> PyResult<T> { |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
30 |
error.map_err(|e| match e { |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
31 |
HgError::IoError { .. } => { |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
32 |
PyErr::new::<cpython::exc::IOError, _>(py, e.to_string()) |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
33 |
} |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
34 |
HgError::UnsupportedFeature(e) => { |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
35 |
let as_string = e.to_string(); |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
36 |
log::trace!("Update from null fallback: {}", as_string); |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
37 |
PyErr::new::<FallbackError, _>(py, &as_string) |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
38 |
} |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
39 |
HgError::RaceDetected(_) => { |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
40 |
unreachable!("must not surface to the user") |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
41 |
} |
52046
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
42 |
HgError::Path(path_error) => { |
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
43 |
let msg = PyBytes::new(py, path_error.to_string().as_bytes()); |
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
44 |
let cls = py |
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
45 |
.import("mercurial.error") |
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
46 |
.and_then(|m| m.get(py, "InputError")) |
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
47 |
.unwrap(); |
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
48 |
PyErr::from_instance( |
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
49 |
py, |
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
50 |
cls.call(py, (msg,), None).ok().into_py_object(py), |
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
51 |
) |
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
52 |
} |
52213
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
53 |
HgError::InterruptReceived => { |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
54 |
PyErr::new::<KeyboardInterrupt, _>(py, "") |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
55 |
} |
52042
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
56 |
e => PyErr::new::<cpython::exc::RuntimeError, _>(py, e.to_string()), |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
57 |
}) |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
58 |
} |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
59 |
|
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
60 |
pub fn repo_error_to_pyerr<T>( |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
61 |
py: Python, |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
62 |
error: Result<T, RepoError>, |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
63 |
) -> PyResult<T> { |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
64 |
hgerror_to_pyerr(py, error.map_err(HgError::from)) |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
65 |
} |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
66 |
|
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
67 |
/// Get a repository from a given [`PyObject`] path, and bubble up any error |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
68 |
/// that comes up. |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
69 |
pub fn repo_from_path(py: Python, repo_path: PyObject) -> Result<Repo, PyErr> { |
52185
e698e3e75420
rust-cpython: add a TODO about repo reuse
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52046
diff
changeset
|
70 |
// TODO make the Config a Python class and downcast it here, otherwise we |
e698e3e75420
rust-cpython: add a TODO about repo reuse
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52046
diff
changeset
|
71 |
// lose CLI args and runtime overrides done in Python. |
52042
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
72 |
let config = |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
73 |
hgerror_to_pyerr(py, Config::load_non_repo().map_err(HgError::from))?; |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
74 |
let py_bytes = &repo_path.extract::<PyBytes>(py)?; |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
75 |
let repo_path = py_bytes.data(py); |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
76 |
let repo = repo_error_to_pyerr( |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
77 |
py, |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
78 |
Repo::find(&config, Some(get_path_from_bytes(repo_path).to_owned())), |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
79 |
)?; |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
80 |
Ok(repo) |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
81 |
} |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
82 |
|
44505
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
83 |
// Necessary evil for the time being, could maybe be moved to |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
84 |
// a TryFrom in Node itself |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
85 |
const NODE_BYTES_LENGTH: usize = 20; |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
86 |
type NodeData = [u8; NODE_BYTES_LENGTH]; |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
87 |
|
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
88 |
/// Copy incoming Python bytes given as `PyObject` into `Node`, |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
89 |
/// doing the necessary checks |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
90 |
pub fn node_from_py_object<'a>( |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
91 |
py: Python, |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
92 |
bytes: &'a PyObject, |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
93 |
) -> PyResult<Node> { |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
94 |
let as_py_bytes: &'a PyBytes = bytes.extract(py)?; |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
95 |
node_from_py_bytes(py, as_py_bytes) |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
96 |
} |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
97 |
|
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
98 |
/// Clone incoming Python bytes given as `PyBytes` as a `Node`, |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
99 |
/// doing the necessary checks. |
44973
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44505
diff
changeset
|
100 |
pub fn node_from_py_bytes(py: Python, bytes: &PyBytes) -> PyResult<Node> { |
44505
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
101 |
<NodeData>::try_from(bytes.data(py)) |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
102 |
.map_err(|_| { |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
103 |
PyErr::new::<ValueError, _>( |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
104 |
py, |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
105 |
format!("{}-byte hash required", NODE_BYTES_LENGTH), |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
106 |
) |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
107 |
}) |
44973
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44505
diff
changeset
|
108 |
.map(Into::into) |
44505
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
109 |
} |
52213
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
110 |
|
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
111 |
/// Wrap a call to `func` so that Python's `SIGINT` handler is first stored, |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
112 |
/// then restored after the call to `func` and finally raised if |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
113 |
/// `func` returns a [`HgError::InterruptReceived`] |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
114 |
pub fn with_sigint_wrapper<R>( |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
115 |
py: Python, |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
116 |
func: impl Fn() -> Result<R, HgError>, |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
117 |
) -> PyResult<Result<R, HgError>> { |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
118 |
let signal_py_mod = py.import("signal")?; |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
119 |
let sigint_py_const = signal_py_mod.get(py, "SIGINT")?; |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
120 |
let old_handler = signal_py_mod.call( |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
121 |
py, |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
122 |
"getsignal", |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
123 |
PyTuple::new(py, &[sigint_py_const.clone_ref(py)]), |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
124 |
None, |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
125 |
)?; |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
126 |
let res = func(); |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
127 |
// Reset the old signal handler in Python because we've may have changed it |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
128 |
signal_py_mod.call( |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
129 |
py, |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
130 |
"signal", |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
131 |
PyTuple::new(py, &[sigint_py_const.clone_ref(py), old_handler]), |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
132 |
None, |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
133 |
)?; |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
134 |
if let Err(HgError::InterruptReceived) = res { |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
135 |
// Trigger the signal in Python |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
136 |
signal_py_mod.call( |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
137 |
py, |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
138 |
"raise_signal", |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
139 |
PyTuple::new(py, &[sigint_py_const]), |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
140 |
None, |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
141 |
)?; |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
142 |
} |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
143 |
Ok(res) |
96b113d22b34
rust-update: handle SIGINT from long-running update threads
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52185
diff
changeset
|
144 |
} |