Show More
@@ -14,9 +14,9 b' use crate::{' | |||||
14 | use cpython::{ |
|
14 | use cpython::{ | |
15 | buffer::{Element, PyBuffer}, |
|
15 | buffer::{Element, PyBuffer}, | |
16 | exc::{IndexError, ValueError}, |
|
16 | exc::{IndexError, ValueError}, | |
17 |
ObjectProtocol |
|
17 | ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyInt, PyList, PyModule, | |
18 |
|
|
18 | PyObject, PyResult, PySet, PyString, PyTuple, Python, PythonObject, | |
19 |
|
|
19 | ToPyObject, UnsafePyLeaked, | |
20 | }; |
|
20 | }; | |
21 | use hg::{ |
|
21 | use hg::{ | |
22 | errors::HgError, |
|
22 | errors::HgError, | |
@@ -123,14 +123,10 b' py_class!(pub class MixedIndex |py| {' | |||||
123 | def get_rev(&self, node: PyBytes) -> PyResult<Option<PyRevision>> { |
|
123 | def get_rev(&self, node: PyBytes) -> PyResult<Option<PyRevision>> { | |
124 | let opt = self.get_nodetree(py)?.borrow(); |
|
124 | let opt = self.get_nodetree(py)?.borrow(); | |
125 | let nt = opt.as_ref().unwrap(); |
|
125 | let nt = opt.as_ref().unwrap(); | |
126 | let idx = &*self.cindex(py).borrow(); |
|
|||
127 | let ridx = &*self.index(py).borrow(); |
|
126 | let ridx = &*self.index(py).borrow(); | |
128 | let node = node_from_py_bytes(py, &node)?; |
|
127 | let node = node_from_py_bytes(py, &node)?; | |
129 | let rust_rev = |
|
128 | let rust_rev = | |
130 | nt.find_bin(ridx, node.into()).map_err(|e| nodemap_error(py, e))?; |
|
129 | nt.find_bin(ridx, node.into()).map_err(|e| nodemap_error(py, e))?; | |
131 | let c_rev = |
|
|||
132 | nt.find_bin(idx, node.into()).map_err(|e| nodemap_error(py, e))?; |
|
|||
133 | assert_eq!(rust_rev, c_rev); |
|
|||
134 | Ok(rust_rev.map(Into::into)) |
|
130 | Ok(rust_rev.map(Into::into)) | |
135 |
|
131 | |||
136 | } |
|
132 | } | |
@@ -202,24 +198,22 b' py_class!(pub class MixedIndex |py| {' | |||||
202 | let node = node_from_py_object(py, &node_bytes)?; |
|
198 | let node = node_from_py_object(py, &node_bytes)?; | |
203 |
|
199 | |||
204 | let rev = self.len(py)? as BaseRevision; |
|
200 | let rev = self.len(py)? as BaseRevision; | |
205 | let mut idx = self.cindex(py).borrow_mut(); |
|
|||
206 |
|
201 | |||
207 | // This is ok since we will just add the revision to the index |
|
202 | // This is ok since we will just add the revision to the index | |
208 | let rev = Revision(rev); |
|
203 | let rev = Revision(rev); | |
209 | idx.append(py, tup.clone_ref(py))?; |
|
|||
210 | self.index(py) |
|
204 | self.index(py) | |
211 | .borrow_mut() |
|
205 | .borrow_mut() | |
212 | .append(py_tuple_to_revision_data_params(py, tup)?) |
|
206 | .append(py_tuple_to_revision_data_params(py, tup)?) | |
213 | .unwrap(); |
|
207 | .unwrap(); | |
|
208 | let idx = &*self.index(py).borrow(); | |||
214 | self.get_nodetree(py)?.borrow_mut().as_mut().unwrap() |
|
209 | self.get_nodetree(py)?.borrow_mut().as_mut().unwrap() | |
215 |
.insert( |
|
210 | .insert(idx, &node, rev) | |
216 | .map_err(|e| nodemap_error(py, e))?; |
|
211 | .map_err(|e| nodemap_error(py, e))?; | |
217 | Ok(py.None()) |
|
212 | Ok(py.None()) | |
218 | } |
|
213 | } | |
219 |
|
214 | |||
220 | def __delitem__(&self, key: PyObject) -> PyResult<()> { |
|
215 | def __delitem__(&self, key: PyObject) -> PyResult<()> { | |
221 | // __delitem__ is both for `del idx[r]` and `del idx[r1:r2]` |
|
216 | // __delitem__ is both for `del idx[r]` and `del idx[r1:r2]` | |
222 | self.cindex(py).borrow().inner().del_item(py, &key)?; |
|
|||
223 | let start = key.getattr(py, "start")?; |
|
217 | let start = key.getattr(py, "start")?; | |
224 | let start = UncheckedRevision(start.extract(py)?); |
|
218 | let start = UncheckedRevision(start.extract(py)?); | |
225 | let start = self.index(py) |
|
219 | let start = self.index(py) | |
@@ -237,80 +231,60 b' py_class!(pub class MixedIndex |py| {' | |||||
237 | } |
|
231 | } | |
238 |
|
232 | |||
239 | // |
|
233 | // | |
240 | // Reforwarded C index API |
|
234 | // Index methods previously reforwarded to C index (tp_methods) | |
|
235 | // Same ordering as in revlog.c | |||
241 | // |
|
236 | // | |
242 |
|
237 | |||
243 | // index_methods (tp_methods). Same ordering as in revlog.c |
|
|||
244 |
|
||||
245 | /// return the gca set of the given revs |
|
238 | /// return the gca set of the given revs | |
246 | def ancestors(&self, *args, **kw) -> PyResult<PyObject> { |
|
239 | def ancestors(&self, *args, **_kw) -> PyResult<PyObject> { | |
247 | let rust_res = self.inner_ancestors(py, args)?; |
|
240 | let rust_res = self.inner_ancestors(py, args)?; | |
248 |
|
||||
249 | let c_res = self.call_cindex(py, "ancestors", args, kw)?; |
|
|||
250 | // the algorithm should always provide the results in reverse ordering |
|
|||
251 | assert_py_eq(py, "ancestors", &rust_res, &c_res)?; |
|
|||
252 |
|
||||
253 | Ok(rust_res) |
|
241 | Ok(rust_res) | |
254 | } |
|
242 | } | |
255 |
|
243 | |||
256 | /// return the heads of the common ancestors of the given revs |
|
244 | /// return the heads of the common ancestors of the given revs | |
257 | def commonancestorsheads(&self, *args, **kw) -> PyResult<PyObject> { |
|
245 | def commonancestorsheads(&self, *args, **_kw) -> PyResult<PyObject> { | |
258 | let rust_res = self.inner_commonancestorsheads(py, args)?; |
|
246 | let rust_res = self.inner_commonancestorsheads(py, args)?; | |
259 |
|
||||
260 | let c_res = self.call_cindex(py, "commonancestorsheads", args, kw)?; |
|
|||
261 | // the algorithm should always provide the results in reverse ordering |
|
|||
262 | assert_py_eq(py, "commonancestorsheads", &rust_res, &c_res)?; |
|
|||
263 |
|
||||
264 | Ok(rust_res) |
|
247 | Ok(rust_res) | |
265 | } |
|
248 | } | |
266 |
|
249 | |||
267 | /// Clear the index caches and inner py_class data. |
|
250 | /// Clear the index caches and inner py_class data. | |
268 | /// It is Python's responsibility to call `update_nodemap_data` again. |
|
251 | /// It is Python's responsibility to call `update_nodemap_data` again. | |
269 |
def clearcaches(&self |
|
252 | def clearcaches(&self) -> PyResult<PyObject> { | |
270 | self.nt(py).borrow_mut().take(); |
|
253 | self.nt(py).borrow_mut().take(); | |
271 | self.docket(py).borrow_mut().take(); |
|
254 | self.docket(py).borrow_mut().take(); | |
272 | self.nodemap_mmap(py).borrow_mut().take(); |
|
255 | self.nodemap_mmap(py).borrow_mut().take(); | |
273 | self.index(py).borrow().clear_caches(); |
|
256 | self.index(py).borrow().clear_caches(); | |
274 | self.call_cindex(py, "clearcaches", args, kw) |
|
257 | Ok(py.None()) | |
275 | } |
|
258 | } | |
276 |
|
259 | |||
277 | /// return the raw binary string representing a revision |
|
260 | /// return the raw binary string representing a revision | |
278 | def entry_binary(&self, *args, **kw) -> PyResult<PyObject> { |
|
261 | def entry_binary(&self, *args, **_kw) -> PyResult<PyObject> { | |
279 | let rindex = self.index(py).borrow(); |
|
262 | let rindex = self.index(py).borrow(); | |
280 | let rev = UncheckedRevision(args.get_item(py, 0).extract(py)?); |
|
263 | let rev = UncheckedRevision(args.get_item(py, 0).extract(py)?); | |
281 | let rust_bytes = rindex.check_revision(rev).and_then( |
|
264 | let rust_bytes = rindex.check_revision(rev).and_then( | |
282 | |r| rindex.entry_binary(r)) |
|
265 | |r| rindex.entry_binary(r)) | |
283 | .ok_or_else(|| rev_not_in_index(py, rev))?; |
|
266 | .ok_or_else(|| rev_not_in_index(py, rev))?; | |
284 | let rust_res = PyBytes::new(py, rust_bytes).into_object(); |
|
267 | let rust_res = PyBytes::new(py, rust_bytes).into_object(); | |
285 |
|
||||
286 | let c_res = self.call_cindex(py, "entry_binary", args, kw)?; |
|
|||
287 | assert_py_eq(py, "entry_binary", &rust_res, &c_res)?; |
|
|||
288 | Ok(rust_res) |
|
268 | Ok(rust_res) | |
289 | } |
|
269 | } | |
290 |
|
270 | |||
291 | /// return a binary packed version of the header |
|
271 | /// return a binary packed version of the header | |
292 | def pack_header(&self, *args, **kw) -> PyResult<PyObject> { |
|
272 | def pack_header(&self, *args, **_kw) -> PyResult<PyObject> { | |
293 | let rindex = self.index(py).borrow(); |
|
273 | let rindex = self.index(py).borrow(); | |
294 | let packed = rindex.pack_header(args.get_item(py, 0).extract(py)?); |
|
274 | let packed = rindex.pack_header(args.get_item(py, 0).extract(py)?); | |
295 | let rust_res = PyBytes::new(py, &packed).into_object(); |
|
275 | let rust_res = PyBytes::new(py, &packed).into_object(); | |
296 |
|
||||
297 | let c_res = self.call_cindex(py, "pack_header", args, kw)?; |
|
|||
298 | assert_py_eq(py, "pack_header", &rust_res, &c_res)?; |
|
|||
299 | Ok(rust_res) |
|
276 | Ok(rust_res) | |
300 | } |
|
277 | } | |
301 |
|
278 | |||
302 | /// compute phases |
|
279 | /// compute phases | |
303 | def computephasesmapsets(&self, *args, **kw) -> PyResult<PyObject> { |
|
280 | def computephasesmapsets(&self, *args, **_kw) -> PyResult<PyObject> { | |
304 | let py_roots = args.get_item(py, 0).extract::<PyDict>(py)?; |
|
281 | let py_roots = args.get_item(py, 0).extract::<PyDict>(py)?; | |
305 | let rust_res = self.inner_computephasesmapsets(py, py_roots)?; |
|
282 | let rust_res = self.inner_computephasesmapsets(py, py_roots)?; | |
306 |
|
||||
307 | let c_res = self.call_cindex(py, "computephasesmapsets", args, kw)?; |
|
|||
308 | assert_py_eq(py, "computephasesmapsets", &rust_res, &c_res)?; |
|
|||
309 | Ok(rust_res) |
|
283 | Ok(rust_res) | |
310 | } |
|
284 | } | |
311 |
|
285 | |||
312 | /// reachableroots |
|
286 | /// reachableroots | |
313 | def reachableroots2(&self, *args, **kw) -> PyResult<PyObject> { |
|
287 | def reachableroots2(&self, *args, **_kw) -> PyResult<PyObject> { | |
314 | let rust_res = self.inner_reachableroots2( |
|
288 | let rust_res = self.inner_reachableroots2( | |
315 | py, |
|
289 | py, | |
316 | UncheckedRevision(args.get_item(py, 0).extract(py)?), |
|
290 | UncheckedRevision(args.get_item(py, 0).extract(py)?), | |
@@ -318,51 +292,34 b' py_class!(pub class MixedIndex |py| {' | |||||
318 | args.get_item(py, 2), |
|
292 | args.get_item(py, 2), | |
319 | args.get_item(py, 3).extract(py)?, |
|
293 | args.get_item(py, 3).extract(py)?, | |
320 | )?; |
|
294 | )?; | |
321 |
|
||||
322 | let c_res = self.call_cindex(py, "reachableroots2", args, kw)?; |
|
|||
323 | // ordering of C result depends on how the computation went, and |
|
|||
324 | // Rust result ordering is arbitrary. Hence we compare after |
|
|||
325 | // sorting the results (in Python to avoid reconverting everything |
|
|||
326 | // back to Rust structs). |
|
|||
327 | assert_py_eq_normalized(py, "reachableroots2", &rust_res, &c_res, |
|
|||
328 | |v| format!("sorted({})", v))?; |
|
|||
329 |
|
||||
330 | Ok(rust_res) |
|
295 | Ok(rust_res) | |
331 | } |
|
296 | } | |
332 |
|
297 | |||
333 | /// get head revisions |
|
298 | /// get head revisions | |
334 |
def headrevs(&self |
|
299 | def headrevs(&self) -> PyResult<PyObject> { | |
335 | let rust_res = self.inner_headrevs(py)?; |
|
300 | let rust_res = self.inner_headrevs(py)?; | |
336 |
|
||||
337 | let c_res = self.call_cindex(py, "headrevs", args, kw)?; |
|
|||
338 | assert_py_eq(py, "headrevs", &rust_res, &c_res)?; |
|
|||
339 | Ok(rust_res) |
|
301 | Ok(rust_res) | |
340 | } |
|
302 | } | |
341 |
|
303 | |||
342 | /// get filtered head revisions |
|
304 | /// get filtered head revisions | |
343 | def headrevsfiltered(&self, *args, **kw) -> PyResult<PyObject> { |
|
305 | def headrevsfiltered(&self, *args, **_kw) -> PyResult<PyObject> { | |
344 | let rust_res = self.inner_headrevsfiltered(py, &args.get_item(py, 0))?; |
|
306 | let rust_res = self.inner_headrevsfiltered(py, &args.get_item(py, 0))?; | |
345 | let c_res = self.call_cindex(py, "headrevsfiltered", args, kw)?; |
|
|||
346 |
|
||||
347 | assert_py_eq(py, "headrevsfiltered", &rust_res, &c_res)?; |
|
|||
348 | Ok(rust_res) |
|
307 | Ok(rust_res) | |
349 | } |
|
308 | } | |
350 |
|
309 | |||
351 | /// True if the object is a snapshot |
|
310 | /// True if the object is a snapshot | |
352 | def issnapshot(&self, *args, **kw) -> PyResult<bool> { |
|
311 | def issnapshot(&self, *args, **_kw) -> PyResult<bool> { | |
353 | let index = self.index(py).borrow(); |
|
312 | let index = self.index(py).borrow(); | |
354 | let result = index |
|
313 | let result = index | |
355 | .is_snapshot(UncheckedRevision(args.get_item(py, 0).extract(py)?)) |
|
314 | .is_snapshot(UncheckedRevision(args.get_item(py, 0).extract(py)?)) | |
356 | .map_err(|e| { |
|
315 | .map_err(|e| { | |
357 | PyErr::new::<cpython::exc::ValueError, _>(py, e.to_string()) |
|
316 | PyErr::new::<cpython::exc::ValueError, _>(py, e.to_string()) | |
358 | })?; |
|
317 | })?; | |
359 | let cresult = self.call_cindex(py, "issnapshot", args, kw)?; |
|
|||
360 | assert_eq!(result, cresult.extract(py)?); |
|
|||
361 | Ok(result) |
|
318 | Ok(result) | |
362 | } |
|
319 | } | |
363 |
|
320 | |||
364 | /// Gather snapshot data in a cache dict |
|
321 | /// Gather snapshot data in a cache dict | |
365 | def findsnapshots(&self, *args, **kw) -> PyResult<PyObject> { |
|
322 | def findsnapshots(&self, *args, **_kw) -> PyResult<PyObject> { | |
366 | let index = self.index(py).borrow(); |
|
323 | let index = self.index(py).borrow(); | |
367 | let cache: PyDict = args.get_item(py, 0).extract(py)?; |
|
324 | let cache: PyDict = args.get_item(py, 0).extract(py)?; | |
368 | // this methods operates by setting new values in the cache, |
|
325 | // this methods operates by setting new values in the cache, | |
@@ -382,24 +339,11 b' py_class!(pub class MixedIndex |py| {' | |||||
382 | end_rev, |
|
339 | end_rev, | |
383 | &mut cache_wrapper, |
|
340 | &mut cache_wrapper, | |
384 | ).map_err(|_| revlog_error(py))?; |
|
341 | ).map_err(|_| revlog_error(py))?; | |
385 |
|
||||
386 | let c_args = PyTuple::new( |
|
|||
387 | py, |
|
|||
388 | &[ |
|
|||
389 | c_cache.clone_ref(py).into_object(), |
|
|||
390 | args.get_item(py, 1), |
|
|||
391 | args.get_item(py, 2) |
|
|||
392 | ] |
|
|||
393 | ); |
|
|||
394 | self.call_cindex(py, "findsnapshots", &c_args, kw)?; |
|
|||
395 | assert_py_eq(py, "findsnapshots cache", |
|
|||
396 | &cache_wrapper.into_object(), |
|
|||
397 | &c_cache.into_object())?; |
|
|||
398 | Ok(py.None()) |
|
342 | Ok(py.None()) | |
399 | } |
|
343 | } | |
400 |
|
344 | |||
401 | /// determine revisions with deltas to reconstruct fulltext |
|
345 | /// determine revisions with deltas to reconstruct fulltext | |
402 | def deltachain(&self, *args, **kw) -> PyResult<PyObject> { |
|
346 | def deltachain(&self, *args, **_kw) -> PyResult<PyObject> { | |
403 | let index = self.index(py).borrow(); |
|
347 | let index = self.index(py).borrow(); | |
404 | let rev = args.get_item(py, 0).extract::<BaseRevision>(py)?.into(); |
|
348 | let rev = args.get_item(py, 0).extract::<BaseRevision>(py)?.into(); | |
405 | let stop_rev = |
|
349 | let stop_rev = | |
@@ -422,13 +366,7 b' py_class!(pub class MixedIndex |py| {' | |||||
422 | PyErr::new::<cpython::exc::ValueError, _>(py, e.to_string()) |
|
366 | PyErr::new::<cpython::exc::ValueError, _>(py, e.to_string()) | |
423 | })?; |
|
367 | })?; | |
424 |
|
368 | |||
425 | let cresult = self.call_cindex(py, "deltachain", args, kw)?; |
|
|||
426 | let cchain: Vec<BaseRevision> = |
|
|||
427 | cresult.get_item(py, 0)?.extract::<Vec<BaseRevision>>(py)?; |
|
|||
428 | let chain: Vec<_> = chain.into_iter().map(|r| r.0).collect(); |
|
369 | let chain: Vec<_> = chain.into_iter().map(|r| r.0).collect(); | |
429 | assert_eq!(chain, cchain); |
|
|||
430 | assert_eq!(stopped, cresult.get_item(py, 1)?.extract(py)?); |
|
|||
431 |
|
||||
432 | Ok( |
|
370 | Ok( | |
433 | PyTuple::new( |
|
371 | PyTuple::new( | |
434 | py, |
|
372 | py, | |
@@ -442,16 +380,13 b' py_class!(pub class MixedIndex |py| {' | |||||
442 | } |
|
380 | } | |
443 |
|
381 | |||
444 | /// slice planned chunk read to reach a density threshold |
|
382 | /// slice planned chunk read to reach a density threshold | |
445 | def slicechunktodensity(&self, *args, **kw) -> PyResult<PyObject> { |
|
383 | def slicechunktodensity(&self, *args, **_kw) -> PyResult<PyObject> { | |
446 | let rust_res = self.inner_slicechunktodensity( |
|
384 | let rust_res = self.inner_slicechunktodensity( | |
447 | py, |
|
385 | py, | |
448 | args.get_item(py, 0), |
|
386 | args.get_item(py, 0), | |
449 | args.get_item(py, 1).extract(py)?, |
|
387 | args.get_item(py, 1).extract(py)?, | |
450 | args.get_item(py, 2).extract(py)? |
|
388 | args.get_item(py, 2).extract(py)? | |
451 | )?; |
|
389 | )?; | |
452 |
|
||||
453 | let c_res = self.call_cindex(py, "slicechunktodensity", args, kw)?; |
|
|||
454 | assert_py_eq(py, "slicechunktodensity", &rust_res, &c_res)?; |
|
|||
455 | Ok(rust_res) |
|
390 | Ok(rust_res) | |
456 | } |
|
391 | } | |
457 |
|
392 | |||
@@ -468,23 +403,6 b' py_class!(pub class MixedIndex |py| {' | |||||
468 |
|
403 | |||
469 | def __getitem__(&self, key: PyObject) -> PyResult<PyObject> { |
|
404 | def __getitem__(&self, key: PyObject) -> PyResult<PyObject> { | |
470 | let rust_res = self.inner_getitem(py, key.clone_ref(py))?; |
|
405 | let rust_res = self.inner_getitem(py, key.clone_ref(py))?; | |
471 |
|
||||
472 | // this conversion seems needless, but that's actually because |
|
|||
473 | // `index_getitem` does not handle conversion from PyLong, |
|
|||
474 | // which expressions such as [e for e in index] internally use. |
|
|||
475 | // Note that we don't seem to have a direct way to call |
|
|||
476 | // PySequence_GetItem (does the job), which would possibly be better |
|
|||
477 | // for performance |
|
|||
478 | // gracinet 2023: the above comment can be removed when we use |
|
|||
479 | // the pure Rust impl only. Note also that `key` can be a binary |
|
|||
480 | // node id. |
|
|||
481 | let c_key = match key.extract::<BaseRevision>(py) { |
|
|||
482 | Ok(rev) => rev.to_py_object(py).into_object(), |
|
|||
483 | Err(_) => key, |
|
|||
484 | }; |
|
|||
485 | let c_res = self.cindex(py).borrow().inner().get_item(py, c_key)?; |
|
|||
486 |
|
||||
487 | assert_py_eq(py, "__getitem__", &rust_res, &c_res)?; |
|
|||
488 | Ok(rust_res) |
|
406 | Ok(rust_res) | |
489 | } |
|
407 | } | |
490 |
|
408 | |||
@@ -492,7 +410,6 b' py_class!(pub class MixedIndex |py| {' | |||||
492 | // ObjectProtocol does not seem to provide contains(), so |
|
410 | // ObjectProtocol does not seem to provide contains(), so | |
493 | // this is an equivalent implementation of the index_contains() |
|
411 | // this is an equivalent implementation of the index_contains() | |
494 | // defined in revlog.c |
|
412 | // defined in revlog.c | |
495 | let cindex = self.cindex(py).borrow(); |
|
|||
496 | match item.extract::<i32>(py) { |
|
413 | match item.extract::<i32>(py) { | |
497 | Ok(rev) => { |
|
414 | Ok(rev) => { | |
498 | Ok(rev >= -1 && rev < self.len(py)? as BaseRevision) |
|
415 | Ok(rev >= -1 && rev < self.len(py)? as BaseRevision) | |
@@ -500,15 +417,6 b' py_class!(pub class MixedIndex |py| {' | |||||
500 | Err(_) => { |
|
417 | Err(_) => { | |
501 | let item_bytes: PyBytes = item.extract(py)?; |
|
418 | let item_bytes: PyBytes = item.extract(py)?; | |
502 | let rust_res = self.has_node(py, item_bytes)?; |
|
419 | let rust_res = self.has_node(py, item_bytes)?; | |
503 |
|
||||
504 | let c_res = cindex.inner().call_method( |
|
|||
505 | py, |
|
|||
506 | "has_node", |
|
|||
507 | PyTuple::new(py, &[item.clone_ref(py)]), |
|
|||
508 | None)? |
|
|||
509 | .extract(py)?; |
|
|||
510 |
|
||||
511 | assert_eq!(rust_res, c_res); |
|
|||
512 | Ok(rust_res) |
|
420 | Ok(rust_res) | |
513 | } |
|
421 | } | |
514 | } |
|
422 | } | |
@@ -532,11 +440,6 b' py_class!(pub class MixedIndex |py| {' | |||||
532 | @property |
|
440 | @property | |
533 | def entry_size(&self) -> PyResult<PyInt> { |
|
441 | def entry_size(&self) -> PyResult<PyInt> { | |
534 | let rust_res: PyInt = INDEX_ENTRY_SIZE.to_py_object(py); |
|
442 | let rust_res: PyInt = INDEX_ENTRY_SIZE.to_py_object(py); | |
535 |
|
||||
536 | let c_res = self.cindex(py).borrow().inner() |
|
|||
537 | .getattr(py, "entry_size")?; |
|
|||
538 | assert_py_eq(py, "entry_size", rust_res.as_object(), &c_res)?; |
|
|||
539 |
|
||||
540 | Ok(rust_res) |
|
443 | Ok(rust_res) | |
541 | } |
|
444 | } | |
542 |
|
445 | |||
@@ -545,11 +448,6 b' py_class!(pub class MixedIndex |py| {' | |||||
545 | // will be entirely removed when the Rust index yet useful to |
|
448 | // will be entirely removed when the Rust index yet useful to | |
546 | // implement in Rust to detangle things when removing `self.cindex` |
|
449 | // implement in Rust to detangle things when removing `self.cindex` | |
547 | let rust_res: PyInt = 1.to_py_object(py); |
|
450 | let rust_res: PyInt = 1.to_py_object(py); | |
548 |
|
||||
549 | let c_res = self.cindex(py).borrow().inner() |
|
|||
550 | .getattr(py, "rust_ext_compat")?; |
|
|||
551 | assert_py_eq(py, "rust_ext_compat", rust_res.as_object(), &c_res)?; |
|
|||
552 |
|
||||
553 | Ok(rust_res) |
|
451 | Ok(rust_res) | |
554 | } |
|
452 | } | |
555 |
|
453 | |||
@@ -672,12 +570,6 b" struct PySnapshotsCache<'p> {" | |||||
672 | dict: PyDict, |
|
570 | dict: PyDict, | |
673 | } |
|
571 | } | |
674 |
|
572 | |||
675 | impl<'p> PySnapshotsCache<'p> { |
|
|||
676 | fn into_object(self) -> PyObject { |
|
|||
677 | self.dict.into_object() |
|
|||
678 | } |
|
|||
679 | } |
|
|||
680 |
|
||||
681 | impl<'p> SnapshotsCache for PySnapshotsCache<'p> { |
|
573 | impl<'p> SnapshotsCache for PySnapshotsCache<'p> { | |
682 | fn insert_for( |
|
574 | fn insert_for( | |
683 | &mut self, |
|
575 | &mut self, | |
@@ -731,8 +623,6 b' impl MixedIndex {' | |||||
731 |
|
623 | |||
732 | fn len(&self, py: Python) -> PyResult<usize> { |
|
624 | fn len(&self, py: Python) -> PyResult<usize> { | |
733 | let rust_index_len = self.index(py).borrow().len(); |
|
625 | let rust_index_len = self.index(py).borrow().len(); | |
734 | let cindex_len = self.cindex(py).borrow().inner().len(py)?; |
|
|||
735 | assert_eq!(rust_index_len, cindex_len); |
|
|||
736 | Ok(rust_index_len) |
|
626 | Ok(rust_index_len) | |
737 | } |
|
627 | } | |
738 |
|
628 | |||
@@ -767,20 +657,6 b' impl MixedIndex {' | |||||
767 | Ok(self.nt(py)) |
|
657 | Ok(self.nt(py)) | |
768 | } |
|
658 | } | |
769 |
|
659 | |||
770 | /// forward a method call to the underlying C index |
|
|||
771 | fn call_cindex( |
|
|||
772 | &self, |
|
|||
773 | py: Python, |
|
|||
774 | name: &str, |
|
|||
775 | args: &PyTuple, |
|
|||
776 | kwargs: Option<&PyDict>, |
|
|||
777 | ) -> PyResult<PyObject> { |
|
|||
778 | self.cindex(py) |
|
|||
779 | .borrow() |
|
|||
780 | .inner() |
|
|||
781 | .call_method(py, name, args, kwargs) |
|
|||
782 | } |
|
|||
783 |
|
||||
784 | pub fn clone_cindex(&self, py: Python) -> cindex::Index { |
|
660 | pub fn clone_cindex(&self, py: Python) -> cindex::Index { | |
785 | self.cindex(py).borrow().clone_ref(py) |
|
661 | self.cindex(py).borrow().clone_ref(py) | |
786 | } |
|
662 | } | |
@@ -1144,51 +1020,6 b' fn nodemap_error(py: Python, err: NodeMa' | |||||
1144 | } |
|
1020 | } | |
1145 | } |
|
1021 | } | |
1146 |
|
1022 | |||
1147 | /// assert two Python objects to be equal from a Python point of view |
|
|||
1148 | /// |
|
|||
1149 | /// `method` is a label for the assertion error message, intended to be the |
|
|||
1150 | /// name of the caller. |
|
|||
1151 | /// `normalizer` is a function that takes a Python variable name and returns |
|
|||
1152 | /// an expression that the conparison will actually use. |
|
|||
1153 | /// Foe example: `|v| format!("sorted({})", v)` |
|
|||
1154 | fn assert_py_eq_normalized( |
|
|||
1155 | py: Python, |
|
|||
1156 | method: &str, |
|
|||
1157 | rust: &PyObject, |
|
|||
1158 | c: &PyObject, |
|
|||
1159 | normalizer: impl FnOnce(&str) -> String + Copy, |
|
|||
1160 | ) -> PyResult<()> { |
|
|||
1161 | let locals = PyDict::new(py); |
|
|||
1162 | locals.set_item(py, "rust".into_py_object(py).into_object(), rust)?; |
|
|||
1163 | locals.set_item(py, "c".into_py_object(py).into_object(), c)?; |
|
|||
1164 | // let lhs = format!(normalizer_fmt, "rust"); |
|
|||
1165 | // let rhs = format!(normalizer_fmt, "c"); |
|
|||
1166 | let is_eq: PyBool = py |
|
|||
1167 | .eval( |
|
|||
1168 | &format!("{} == {}", &normalizer("rust"), &normalizer("c")), |
|
|||
1169 | None, |
|
|||
1170 | Some(&locals), |
|
|||
1171 | )? |
|
|||
1172 | .extract(py)?; |
|
|||
1173 | assert!( |
|
|||
1174 | is_eq.is_true(), |
|
|||
1175 | "{} results differ. Rust: {:?} C: {:?} (before any normalization)", |
|
|||
1176 | method, |
|
|||
1177 | rust, |
|
|||
1178 | c |
|
|||
1179 | ); |
|
|||
1180 | Ok(()) |
|
|||
1181 | } |
|
|||
1182 |
|
||||
1183 | fn assert_py_eq( |
|
|||
1184 | py: Python, |
|
|||
1185 | method: &str, |
|
|||
1186 | rust: &PyObject, |
|
|||
1187 | c: &PyObject, |
|
|||
1188 | ) -> PyResult<()> { |
|
|||
1189 | assert_py_eq_normalized(py, method, rust, c, |v| v.to_owned()) |
|
|||
1190 | } |
|
|||
1191 |
|
||||
1192 | /// Create the module, with __package__ given from parent |
|
1023 | /// Create the module, with __package__ given from parent | |
1193 | pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> { |
|
1024 | pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> { | |
1194 | let dotted_name = &format!("{}.revlog", package); |
|
1025 | let dotted_name = &format!("{}.revlog", package); |
General Comments 0
You need to be logged in to leave comments.
Login now