annotate rust/hg-cpython/src/utils.rs @ 52696:10e7adbffa8c

streamclone: unbyteify string args to builtin Error classes This avoids printing the error with a `b''` prefix in the case of `ValueError`. The custom `ProgrammingError` class is special in that it won't do that, and can take either bytes or str. But there's no point in passing bytes when it is just going to decode to str at runtime anyway.
author Matt Harbison <matt_harbison@yahoo.com>
date Mon, 13 Jan 2025 00:40:48 -0500
parents 96b113d22b34
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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 }