Mercurial > public > mercurial-scm > hg
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 |
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 } |