Mercurial > public > mercurial-scm > hg
annotate rust/hg-cpython/src/utils.rs @ 52046:de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
We will make use of the path auditor when running our update fast-path,
and we want to output of it to be close enough.
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Wed, 02 Oct 2024 20:29:48 +0200 |
parents | 28a0eb21ff04 |
children | e698e3e75420 |
rev | line source |
---|---|
44505
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
1 use cpython::exc::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::{ |
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
3 ObjectProtocol, PyBytes, PyDict, PyErr, PyObject, PyResult, PyTuple, |
de317a87ea6a
rust-pathauditor: match more of Python's behavior and display messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
4 Python, ToPyObject, |
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 } |
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
|
53 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
|
54 }) |
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
|
55 } |
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 |
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 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
|
58 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
|
59 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
|
60 ) -> 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
|
61 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
|
62 } |
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 |
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 /// 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
|
65 /// 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
|
66 pub fn repo_from_path(py: Python, repo_path: PyObject) -> Result<Repo, 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
|
67 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
|
68 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
|
69 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
|
70 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
|
71 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
|
72 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
|
73 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
|
74 )?; |
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 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
|
76 } |
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 |
44505
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
78 // 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
|
79 // 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
|
80 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
|
81 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
|
82 |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
83 /// 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
|
84 /// 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
|
85 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
|
86 py: Python, |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
87 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
|
88 ) -> PyResult<Node> { |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
89 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
|
90 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
|
91 } |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
92 |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
93 /// 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
|
94 /// doing the necessary checks. |
44973
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44505
diff
changeset
|
95 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
|
96 <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
|
97 .map_err(|_| { |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
98 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
|
99 py, |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
100 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
|
101 ) |
d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Georges Racinet <georges.racinet@octobus.net>
parents:
43251
diff
changeset
|
102 }) |
44973
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44505
diff
changeset
|
103 .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
|
104 } |