Show More
@@ -21,13 +21,11 b' use crate::{' | |||||
21 | exceptions, |
|
21 | exceptions, | |
22 | }; |
|
22 | }; | |
23 | use cpython::{ |
|
23 | use cpython::{ | |
24 |
|
|
24 | PyBytes, PyDict, PyErr, PyList, PyModule, PyObject, PyResult, Python, | |
25 | PySequence, Python, |
|
|||
26 | }; |
|
25 | }; | |
27 | use hg::dirstate_tree::on_disk::V2_FORMAT_MARKER; |
|
26 | use hg::dirstate_tree::on_disk::V2_FORMAT_MARKER; | |
28 | use hg::{utils::hg_path::HgPathBuf, DirstateEntry, EntryState, StateMap}; |
|
27 | use hg::DirstateEntry; | |
29 | use libc::{c_char, c_int}; |
|
28 | use libc::{c_char, c_int}; | |
30 | use std::convert::TryFrom; |
|
|||
31 |
|
29 | |||
32 | // C code uses a custom `dirstate_tuple` type, checks in multiple instances |
|
30 | // C code uses a custom `dirstate_tuple` type, checks in multiple instances | |
33 | // for this type, and raises a Python `Exception` if the check does not pass. |
|
31 | // for this type, and raises a Python `Exception` if the check does not pass. | |
@@ -78,34 +76,6 b' pub fn make_dirstate_item_raw(' | |||||
78 | maybe_obj.ok_or_else(|| PyErr::fetch(py)) |
|
76 | maybe_obj.ok_or_else(|| PyErr::fetch(py)) | |
79 | } |
|
77 | } | |
80 |
|
78 | |||
81 | pub fn extract_dirstate(py: Python, dmap: &PyDict) -> Result<StateMap, PyErr> { |
|
|||
82 | dmap.items(py) |
|
|||
83 | .iter() |
|
|||
84 | .map(|(filename, stats)| { |
|
|||
85 | let stats = stats.extract::<PySequence>(py)?; |
|
|||
86 | let state = stats.get_item(py, 0)?.extract::<PyBytes>(py)?; |
|
|||
87 | let state = |
|
|||
88 | EntryState::try_from(state.data(py)[0]).map_err(|e| { |
|
|||
89 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) |
|
|||
90 | })?; |
|
|||
91 | let mode = stats.get_item(py, 1)?.extract(py)?; |
|
|||
92 | let size = stats.get_item(py, 2)?.extract(py)?; |
|
|||
93 | let mtime = stats.get_item(py, 3)?.extract(py)?; |
|
|||
94 | let filename = filename.extract::<PyBytes>(py)?; |
|
|||
95 | let filename = filename.data(py); |
|
|||
96 | Ok(( |
|
|||
97 | HgPathBuf::from(filename.to_owned()), |
|
|||
98 | DirstateEntry { |
|
|||
99 | state, |
|
|||
100 | mode, |
|
|||
101 | size, |
|
|||
102 | mtime, |
|
|||
103 | }, |
|
|||
104 | )) |
|
|||
105 | }) |
|
|||
106 | .collect() |
|
|||
107 | } |
|
|||
108 |
|
||||
109 | /// Create the module, with `__package__` given from parent |
|
79 | /// Create the module, with `__package__` given from parent | |
110 | pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> { |
|
80 | pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> { | |
111 | let dotted_name = &format!("{}.dirstate", package); |
|
81 | let dotted_name = &format!("{}.dirstate", package); |
@@ -11,14 +11,13 b'' | |||||
11 | use std::cell::RefCell; |
|
11 | use std::cell::RefCell; | |
12 |
|
12 | |||
13 | use cpython::{ |
|
13 | use cpython::{ | |
14 |
exc, ObjectProtocol |
|
14 | exc, ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyObject, PyResult, | |
15 |
|
|
15 | Python, UnsafePyLeaked, | |
16 | }; |
|
16 | }; | |
17 |
|
17 | |||
18 | use crate::dirstate::extract_dirstate; |
|
|||
19 | use hg::{ |
|
18 | use hg::{ | |
20 | utils::hg_path::{HgPath, HgPathBuf}, |
|
19 | utils::hg_path::{HgPath, HgPathBuf}, | |
21 |
DirsMultiset, DirsMultisetIter, |
|
20 | DirsMultiset, DirsMultisetIter, DirstateMapError, | |
22 | }; |
|
21 | }; | |
23 |
|
22 | |||
24 | py_class!(pub class Dirs |py| { |
|
23 | py_class!(pub class Dirs |py| { | |
@@ -29,20 +28,11 b' py_class!(pub class Dirs |py| {' | |||||
29 | def __new__( |
|
28 | def __new__( | |
30 | _cls, |
|
29 | _cls, | |
31 | map: PyObject, |
|
30 | map: PyObject, | |
32 | only_tracked: Option<PyObject> = None |
|
|||
33 | ) -> PyResult<Self> { |
|
31 | ) -> PyResult<Self> { | |
34 | let only_tracked_b = if let Some(only_tracked) = only_tracked { |
|
32 | let inner = if map.cast_as::<PyDict>(py).is_ok() { | |
35 | only_tracked.extract::<PyBool>(py)?.is_true() |
|
33 | let err = "pathutil.dirs() with a dict should only be used by the Python dirstatemap \ | |
36 | } else { |
|
34 | and should not be used when Rust is enabled"; | |
37 | false |
|
35 | return Err(PyErr::new::<exc::TypeError, _>(py, err.to_string())) | |
38 | }; |
|
|||
39 | let inner = if let Ok(map) = map.cast_as::<PyDict>(py) { |
|
|||
40 | let dirstate = extract_dirstate(py, &map)?; |
|
|||
41 | let dirstate = dirstate.iter().map(|(k, v)| Ok((k, *v))); |
|
|||
42 | DirsMultiset::from_dirstate(dirstate, only_tracked_b) |
|
|||
43 | .map_err(|e: DirstateError| { |
|
|||
44 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) |
|
|||
45 | })? |
|
|||
46 | } else { |
|
36 | } else { | |
47 | let map: Result<Vec<HgPathBuf>, PyErr> = map |
|
37 | let map: Result<Vec<HgPathBuf>, PyErr> = map | |
48 | .iter(py)? |
|
38 | .iter(py)? |
@@ -13,13 +13,13 b' class dirstests(unittest.TestCase):' | |||||
13 | (b'a/a/a', [b'a', b'a/a', b'']), |
|
13 | (b'a/a/a', [b'a', b'a/a', b'']), | |
14 | (b'alpha/beta/gamma', [b'', b'alpha', b'alpha/beta']), |
|
14 | (b'alpha/beta/gamma', [b'', b'alpha', b'alpha/beta']), | |
15 | ]: |
|
15 | ]: | |
16 |
d = pathutil.dirs( |
|
16 | d = pathutil.dirs([]) | |
17 | d.addpath(case) |
|
17 | d.addpath(case) | |
18 | self.assertEqual(sorted(d), sorted(want)) |
|
18 | self.assertEqual(sorted(d), sorted(want)) | |
19 |
|
19 | |||
20 | def testinvalid(self): |
|
20 | def testinvalid(self): | |
21 | with self.assertRaises(ValueError): |
|
21 | with self.assertRaises(ValueError): | |
22 |
d = pathutil.dirs( |
|
22 | d = pathutil.dirs([]) | |
23 | d.addpath(b'a//b') |
|
23 | d.addpath(b'a//b') | |
24 |
|
24 | |||
25 |
|
25 |
General Comments 0
You need to be logged in to leave comments.
Login now