##// END OF EJS Templates
pathutil: replace the `skip` argument of `dirs` with a boolean...
marmoute -
r48756:e02f9af7 default
parent child Browse files
Show More
@@ -161,7 +161,7 b' bail:'
161 161 return ret;
162 162 }
163 163
164 static int dirs_fromdict(PyObject *dirs, PyObject *source, char skipchar)
164 static int dirs_fromdict(PyObject *dirs, PyObject *source, bool only_tracked)
165 165 {
166 166 PyObject *key, *value;
167 167 Py_ssize_t pos = 0;
@@ -171,13 +171,13 b' static int dirs_fromdict(PyObject *dirs,'
171 171 PyErr_SetString(PyExc_TypeError, "expected string key");
172 172 return -1;
173 173 }
174 if (skipchar) {
174 if (only_tracked) {
175 175 if (!dirstate_tuple_check(value)) {
176 176 PyErr_SetString(PyExc_TypeError,
177 177 "expected a dirstate tuple");
178 178 return -1;
179 179 }
180 if (((dirstateItemObject *)value)->state == skipchar)
180 if (((dirstateItemObject *)value)->state == 'r')
181 181 continue;
182 182 }
183 183
@@ -218,15 +218,17 b' static int dirs_fromiter(PyObject *dirs,'
218 218 * Calculate a refcounted set of directory names for the files in a
219 219 * dirstate.
220 220 */
221 static int dirs_init(dirsObject *self, PyObject *args)
221 static int dirs_init(dirsObject *self, PyObject *args, PyObject *kwargs)
222 222 {
223 223 PyObject *dirs = NULL, *source = NULL;
224 char skipchar = 0;
224 int only_tracked = 0;
225 225 int ret = -1;
226 static char *keywords_name[] = {"map", "only_tracked", NULL};
226 227
227 228 self->dict = NULL;
228 229
229 if (!PyArg_ParseTuple(args, "|Oc:__init__", &source, &skipchar))
230 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:__init__",
231 keywords_name, &source, &only_tracked))
230 232 return -1;
231 233
232 234 dirs = PyDict_New();
@@ -237,10 +239,10 b' static int dirs_init(dirsObject *self, P'
237 239 if (source == NULL)
238 240 ret = 0;
239 241 else if (PyDict_Check(source))
240 ret = dirs_fromdict(dirs, source, skipchar);
241 else if (skipchar)
242 ret = dirs_fromdict(dirs, source, (bool)only_tracked);
243 else if (only_tracked)
242 244 PyErr_SetString(PyExc_ValueError,
243 "skip character is only supported "
245 "`only_tracked` is only supported "
244 246 "with a dict source");
245 247 else
246 248 ret = dirs_fromiter(dirs, source);
@@ -377,7 +377,7 b' class dirstatemap(object):'
377 377
378 378 @propertycache
379 379 def _dirs(self):
380 return pathutil.dirs(self._map, b'r')
380 return pathutil.dirs(self._map, only_tracked=True)
381 381
382 382 @propertycache
383 383 def _alldirs(self):
@@ -315,20 +315,19 b' def finddirs(path):'
315 315 class dirs(object):
316 316 '''a multiset of directory names from a set of file paths'''
317 317
318 def __init__(self, map, skip=None):
318 def __init__(self, map, only_tracked=False):
319 319 """
320 320 a dict map indicates a dirstate while a list indicates a manifest
321 321 """
322 322 self._dirs = {}
323 323 addpath = self.addpath
324 if isinstance(map, dict) and skip is not None:
324 if isinstance(map, dict) and only_tracked:
325 325 for f, s in pycompat.iteritems(map):
326 if s.state != skip:
326 if s.state != b'r':
327 327 addpath(f)
328 elif skip is not None:
329 raise error.ProgrammingError(
330 b"skip character is only supported with a dict source"
331 )
328 elif only_tracked:
329 msg = b"`only_tracked` is only supported with a dict source"
330 raise error.ProgrammingError(msg)
332 331 else:
333 332 for f in map:
334 333 addpath(f)
@@ -33,7 +33,7 b' impl DirsMultiset {'
33 33 /// If `skip_state` is provided, skips dirstate entries with equal state.
34 34 pub fn from_dirstate<I, P>(
35 35 dirstate: I,
36 skip_state: Option<EntryState>,
36 only_tracked: bool,
37 37 ) -> Result<Self, DirstateError>
38 38 where
39 39 I: IntoIterator<
@@ -48,8 +48,8 b' impl DirsMultiset {'
48 48 let (filename, entry) = item?;
49 49 let filename = filename.as_ref();
50 50 // This `if` is optimized out of the loop
51 if let Some(skip) = skip_state {
52 if skip != entry.state {
51 if only_tracked {
52 if entry.state != EntryState::Removed {
53 53 multiset.add_path(filename)?;
54 54 }
55 55 } else {
@@ -343,7 +343,7 b' mod tests {'
343 343
344 344 let new = DirsMultiset::from_dirstate(
345 345 StateMap::default().into_iter().map(Ok),
346 None,
346 false,
347 347 )
348 348 .unwrap();
349 349 let expected = DirsMultiset {
@@ -385,7 +385,7 b' mod tests {'
385 385 .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v))
386 386 .collect();
387 387
388 let new = DirsMultiset::from_dirstate(input_map, None).unwrap();
388 let new = DirsMultiset::from_dirstate(input_map, false).unwrap();
389 389 let expected = DirsMultiset {
390 390 inner: expected_inner,
391 391 };
@@ -414,14 +414,12 b' mod tests {'
414 414 });
415 415
416 416 // "a" incremented with "a/c" and "a/d/"
417 let expected_inner = [("", 1), ("a", 2)]
417 let expected_inner = [("", 1), ("a", 3)]
418 418 .iter()
419 419 .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v))
420 420 .collect();
421 421
422 let new =
423 DirsMultiset::from_dirstate(input_map, Some(EntryState::Normal))
424 .unwrap();
422 let new = DirsMultiset::from_dirstate(input_map, true).unwrap();
425 423 let expected = DirsMultiset {
426 424 inner: expected_inner,
427 425 };
@@ -334,7 +334,7 b' impl DirstateMap {'
334 334 if self.all_dirs.is_none() {
335 335 self.all_dirs = Some(DirsMultiset::from_dirstate(
336 336 self.state_map.iter().map(|(k, v)| Ok((k, *v))),
337 None,
337 false,
338 338 )?);
339 339 }
340 340 Ok(())
@@ -344,7 +344,7 b' impl DirstateMap {'
344 344 if self.dirs.is_none() {
345 345 self.dirs = Some(DirsMultiset::from_dirstate(
346 346 self.state_map.iter().map(|(k, v)| Ok((k, *v))),
347 Some(EntryState::Removed),
347 true,
348 348 )?);
349 349 }
350 350 Ok(())
@@ -9,19 +9,16 b''
9 9 //! `hg-core` package.
10 10
11 11 use std::cell::RefCell;
12 use std::convert::TryInto;
13 12
14 13 use cpython::{
15 exc, ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyObject, PyResult,
16 Python, UnsafePyLeaked,
14 exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyObject,
15 PyResult, Python, UnsafePyLeaked,
17 16 };
18 17
19 18 use crate::dirstate::extract_dirstate;
20 19 use hg::{
21 errors::HgError,
22 20 utils::hg_path::{HgPath, HgPathBuf},
23 21 DirsMultiset, DirsMultisetIter, DirstateError, DirstateMapError,
24 EntryState,
25 22 };
26 23
27 24 py_class!(pub class Dirs |py| {
@@ -32,22 +29,17 b' py_class!(pub class Dirs |py| {'
32 29 def __new__(
33 30 _cls,
34 31 map: PyObject,
35 skip: Option<PyObject> = None
32 only_tracked: Option<PyObject> = None
36 33 ) -> PyResult<Self> {
37 let mut skip_state: Option<EntryState> = None;
38 if let Some(skip) = skip {
39 skip_state = Some(
40 skip.extract::<PyBytes>(py)?.data(py)[0]
41 .try_into()
42 .map_err(|e: HgError| {
43 PyErr::new::<exc::ValueError, _>(py, e.to_string())
44 })?,
45 );
46 }
34 let only_tracked_b = if let Some(only_tracked) = only_tracked {
35 only_tracked.extract::<PyBool>(py)?.is_true()
36 } else {
37 false
38 };
47 39 let inner = if let Ok(map) = map.cast_as::<PyDict>(py) {
48 40 let dirstate = extract_dirstate(py, &map)?;
49 41 let dirstate = dirstate.iter().map(|(k, v)| Ok((k, *v)));
50 DirsMultiset::from_dirstate(dirstate, skip_state)
42 DirsMultiset::from_dirstate(dirstate, only_tracked_b)
51 43 .map_err(|e: DirstateError| {
52 44 PyErr::new::<exc::ValueError, _>(py, e.to_string())
53 45 })?
General Comments 0
You need to be logged in to leave comments. Login now