55 // |
56 // |
56 // No errors are expected from the Python side, and they will should only |
57 // No errors are expected from the Python side, and they will should only |
57 // happens in case of programing error or severe data corruption. Such |
58 // happens in case of programing error or severe data corruption. Such |
58 // errors will raise panic and the rust-cpython harness will turn them into |
59 // errors will raise panic and the rust-cpython harness will turn them into |
59 // Python exception. |
60 // Python exception. |
60 let rev_info_maker = |rev: Revision| -> RevInfo { |
61 let rev_info_maker: RevInfoMaker<PyBytes> = |
61 let res: PyTuple = rev_info |
62 Box::new(|rev: Revision, d: &mut DataHolder<PyBytes>| -> RevInfo { |
62 .call(py, (rev,), None) |
63 let res: PyTuple = rev_info |
63 .expect("rust-copy-tracing: python call to `rev_info` failed") |
64 .call(py, (rev,), None) |
64 .cast_into(py) |
65 .expect("rust-copy-tracing: python call to `rev_info` failed") |
65 .expect( |
|
66 "rust-copy_tracing: python call to `rev_info` returned \ |
|
67 unexpected non-Tuple value", |
|
68 ); |
|
69 let p1 = res.get_item(py, 0).extract(py).expect( |
|
70 "rust-copy-tracing: \ |
|
71 rev_info return is invalid, first item is a not a revision", |
|
72 ); |
|
73 let p2 = res.get_item(py, 1).extract(py).expect( |
|
74 "rust-copy-tracing: \ |
|
75 rev_info return is invalid, second item is a not a revision", |
|
76 ); |
|
77 |
|
78 let changes = res.get_item(py, 2); |
|
79 |
|
80 let files; |
|
81 if !changes |
|
82 .hasattr(py, "copied_from_p1") |
|
83 .expect("rust-copy-tracing: python call to `hasattr` failed") |
|
84 { |
|
85 files = ChangedFiles::new_empty(); |
|
86 } else { |
|
87 let p1_copies: PyDict = changes |
|
88 .getattr(py, "copied_from_p1") |
|
89 .expect( |
|
90 "rust-copy-tracing: retrieval of python attribute \ |
|
91 `copied_from_p1` failed", |
|
92 ) |
|
93 .cast_into(py) |
66 .cast_into(py) |
94 .expect( |
67 .expect( |
95 "rust-copy-tracing: failed to convert `copied_from_p1` \ |
68 "rust-copy_tracing: python call to `rev_info` returned \ |
96 to PyDict", |
69 unexpected non-Tuple value", |
97 ); |
70 ); |
98 let p1_copies: PyResult<_> = p1_copies |
71 let p1 = res.get_item(py, 0).extract(py).expect( |
99 .items(py) |
72 "rust-copy-tracing: rev_info return is invalid, first item \ |
100 .iter() |
73 is a not a revision", |
101 .map(|(key, value)| { |
74 ); |
102 let key = key.extract::<PyBytes>(py).expect( |
75 let p2 = res.get_item(py, 1).extract(py).expect( |
103 "rust-copy-tracing: conversion of copy destination to\ |
76 "rust-copy-tracing: rev_info return is invalid, first item \ |
104 PyBytes failed", |
77 is a not a revision", |
105 ); |
78 ); |
106 let key = key.data(py); |
|
107 let value = value.extract::<PyBytes>(py).expect( |
|
108 "rust-copy-tracing: conversion of copy source to \ |
|
109 PyBytes failed", |
|
110 ); |
|
111 let value = value.data(py); |
|
112 Ok(( |
|
113 HgPathBuf::from_bytes(key), |
|
114 HgPathBuf::from_bytes(value), |
|
115 )) |
|
116 }) |
|
117 .collect(); |
|
118 |
79 |
119 let p2_copies: PyDict = changes |
80 let files = match res.get_item(py, 2).extract::<PyBytes>(py) { |
120 .getattr(py, "copied_from_p2") |
81 Ok(raw) => { |
121 .expect( |
82 // Give responsability for the raw bytes lifetime to |
122 "rust-copy-tracing: retrieval of python attribute \ |
83 // hg-core |
123 `copied_from_p2` failed", |
84 d.data = Some(raw); |
124 ) |
85 let addrs = d.data.as_ref().expect( |
125 .cast_into(py) |
86 "rust-copy-tracing: failed to get a reference to the \ |
126 .expect( |
87 raw bytes for copy data").data(py); |
127 "rust-copy-tracing: failed to convert `copied_from_p2` \ |
88 ChangedFiles::new(addrs) |
128 to PyDict", |
89 } |
129 ); |
90 // value was presumably None, meaning they was no copy data. |
130 let p2_copies: PyResult<_> = p2_copies |
91 Err(_) => ChangedFiles::new_empty(), |
131 .items(py) |
92 }; |
132 .iter() |
|
133 .map(|(key, value)| { |
|
134 let key = key.extract::<PyBytes>(py).expect( |
|
135 "rust-copy-tracing: conversion of copy destination to \ |
|
136 PyBytes failed"); |
|
137 let key = key.data(py); |
|
138 let value = value.extract::<PyBytes>(py).expect( |
|
139 "rust-copy-tracing: conversion of copy source to \ |
|
140 PyBytes failed", |
|
141 ); |
|
142 let value = value.data(py); |
|
143 Ok(( |
|
144 HgPathBuf::from_bytes(key), |
|
145 HgPathBuf::from_bytes(value), |
|
146 )) |
|
147 }) |
|
148 .collect(); |
|
149 |
93 |
150 let removed: PyObject = changes.getattr(py, "removed").expect( |
94 (p1, p2, files) |
151 "rust-copy-tracing: retrieval of python attribute \ |
95 }); |
152 `removed` failed", |
|
153 ); |
|
154 let removed: PyResult<_> = removed |
|
155 .iter(py) |
|
156 .expect( |
|
157 "rust-copy-tracing: getting a python iterator over the \ |
|
158 `removed` set failed", |
|
159 ) |
|
160 .map(|filename| { |
|
161 let filename = filename |
|
162 .expect( |
|
163 "rust-copy-tracing: python iteration over the \ |
|
164 `removed` set failed", |
|
165 ) |
|
166 .extract::<PyBytes>(py) |
|
167 .expect( |
|
168 "rust-copy-tracing: \ |
|
169 conversion of `removed` item to PyBytes failed", |
|
170 ); |
|
171 let filename = filename.data(py); |
|
172 Ok(HgPathBuf::from_bytes(filename)) |
|
173 }) |
|
174 .collect(); |
|
175 |
|
176 let merged: PyObject = changes.getattr(py, "merged").expect( |
|
177 "rust-copy-tracing: retrieval of python attribute \ |
|
178 `merged` failed", |
|
179 ); |
|
180 let merged: PyResult<_> = merged |
|
181 .iter(py) |
|
182 .expect( |
|
183 "rust-copy-tracing: getting a python iterator over the \ |
|
184 `merged` set failed", |
|
185 ) |
|
186 .map(|filename| { |
|
187 let filename = filename |
|
188 .expect( |
|
189 "rust-copy-tracing: python iteration over the \ |
|
190 `merged` set failed", |
|
191 ) |
|
192 .extract::<PyBytes>(py) |
|
193 .expect( |
|
194 "rust-copy-tracing: \ |
|
195 conversion of `merged` item to PyBytes failed", |
|
196 ); |
|
197 let filename = filename.data(py); |
|
198 Ok(HgPathBuf::from_bytes(filename)) |
|
199 }) |
|
200 .collect(); |
|
201 |
|
202 let salvaged: PyObject = changes.getattr(py, "salvaged").expect( |
|
203 "rust-copy-tracing: retrieval of python attribute \ |
|
204 `salvaged` failed", |
|
205 ); |
|
206 let salvaged: PyResult<_> = salvaged |
|
207 .iter(py) |
|
208 .expect( |
|
209 "rust-copy-tracing: getting a python iterator over the \ |
|
210 `salvaged` set failed", |
|
211 ) |
|
212 .map(|filename| { |
|
213 let filename = filename |
|
214 .expect( |
|
215 "rust-copy-tracing: python iteration over the \ |
|
216 `salvaged` set failed", |
|
217 ) |
|
218 .extract::<PyBytes>(py) |
|
219 .expect( |
|
220 "rust-copy-tracing: \ |
|
221 conversion of `salvaged` item to PyBytes failed", |
|
222 ); |
|
223 let filename = filename.data(py); |
|
224 Ok(HgPathBuf::from_bytes(filename)) |
|
225 }) |
|
226 .collect(); |
|
227 files = ChangedFiles::new( |
|
228 removed.unwrap(), |
|
229 merged.unwrap(), |
|
230 salvaged.unwrap(), |
|
231 p1_copies.unwrap(), |
|
232 p2_copies.unwrap(), |
|
233 ); |
|
234 } |
|
235 |
|
236 (p1, p2, files) |
|
237 }; |
|
238 let children: PyResult<_> = children |
96 let children: PyResult<_> = children |
239 .items(py) |
97 .items(py) |
240 .iter() |
98 .iter() |
241 .map(|(k, v)| { |
99 .map(|(k, v)| { |
242 let v: &PyList = v.cast_as(py)?; |
100 let v: &PyList = v.cast_as(py)?; |