rust: Remove support for passing a dict to the Rust pathutil.dirs()
authorSimon Sapin <simon.sapin@octobus.net>
Mon, 20 Sep 2021 13:16:36 +0200
changeset 48043 627cd8f33db0
parent 48042 1194394510ba
child 48044 f2a9db29cb2d
rust: Remove support for passing a dict to the Rust pathutil.dirs() That is only used by the Python dirstatemap, which not used when Rust is enabled. This allows removing the private `extract_dirstate` function which creates `DirstateEntry` values. This in turn will make easier upcoming changes to `DirstateEntry`. Differential Revision: https://phab.mercurial-scm.org/D11460
rust/hg-cpython/src/dirstate.rs
rust/hg-cpython/src/dirstate/dirs_multiset.rs
tests/test-dirs.py
--- a/rust/hg-cpython/src/dirstate.rs	Mon Sep 20 12:52:32 2021 +0200
+++ b/rust/hg-cpython/src/dirstate.rs	Mon Sep 20 13:16:36 2021 +0200
@@ -21,13 +21,11 @@
     exceptions,
 };
 use cpython::{
-    exc, PyBytes, PyDict, PyErr, PyList, PyModule, PyObject, PyResult,
-    PySequence, Python,
+    PyBytes, PyDict, PyErr, PyList, PyModule, PyObject, PyResult, Python,
 };
 use hg::dirstate_tree::on_disk::V2_FORMAT_MARKER;
-use hg::{utils::hg_path::HgPathBuf, DirstateEntry, EntryState, StateMap};
+use hg::DirstateEntry;
 use libc::{c_char, c_int};
-use std::convert::TryFrom;
 
 // C code uses a custom `dirstate_tuple` type, checks in multiple instances
 // for this type, and raises a Python `Exception` if the check does not pass.
@@ -78,34 +76,6 @@
     maybe_obj.ok_or_else(|| PyErr::fetch(py))
 }
 
-pub fn extract_dirstate(py: Python, dmap: &PyDict) -> Result<StateMap, PyErr> {
-    dmap.items(py)
-        .iter()
-        .map(|(filename, stats)| {
-            let stats = stats.extract::<PySequence>(py)?;
-            let state = stats.get_item(py, 0)?.extract::<PyBytes>(py)?;
-            let state =
-                EntryState::try_from(state.data(py)[0]).map_err(|e| {
-                    PyErr::new::<exc::ValueError, _>(py, e.to_string())
-                })?;
-            let mode = stats.get_item(py, 1)?.extract(py)?;
-            let size = stats.get_item(py, 2)?.extract(py)?;
-            let mtime = stats.get_item(py, 3)?.extract(py)?;
-            let filename = filename.extract::<PyBytes>(py)?;
-            let filename = filename.data(py);
-            Ok((
-                HgPathBuf::from(filename.to_owned()),
-                DirstateEntry {
-                    state,
-                    mode,
-                    size,
-                    mtime,
-                },
-            ))
-        })
-        .collect()
-}
-
 /// Create the module, with `__package__` given from parent
 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
     let dotted_name = &format!("{}.dirstate", package);
--- a/rust/hg-cpython/src/dirstate/dirs_multiset.rs	Mon Sep 20 12:52:32 2021 +0200
+++ b/rust/hg-cpython/src/dirstate/dirs_multiset.rs	Mon Sep 20 13:16:36 2021 +0200
@@ -11,14 +11,13 @@
 use std::cell::RefCell;
 
 use cpython::{
-    exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyObject,
-    PyResult, Python, UnsafePyLeaked,
+    exc, ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyObject, PyResult,
+    Python, UnsafePyLeaked,
 };
 
-use crate::dirstate::extract_dirstate;
 use hg::{
     utils::hg_path::{HgPath, HgPathBuf},
-    DirsMultiset, DirsMultisetIter, DirstateError, DirstateMapError,
+    DirsMultiset, DirsMultisetIter, DirstateMapError,
 };
 
 py_class!(pub class Dirs |py| {
@@ -29,20 +28,11 @@
     def __new__(
         _cls,
         map: PyObject,
-        only_tracked: Option<PyObject> = None
     ) -> PyResult<Self> {
-        let only_tracked_b = if let Some(only_tracked) = only_tracked {
-            only_tracked.extract::<PyBool>(py)?.is_true()
-        } else {
-            false
-        };
-        let inner = if let Ok(map) = map.cast_as::<PyDict>(py) {
-            let dirstate = extract_dirstate(py, &map)?;
-            let dirstate = dirstate.iter().map(|(k, v)| Ok((k, *v)));
-            DirsMultiset::from_dirstate(dirstate, only_tracked_b)
-                .map_err(|e: DirstateError| {
-                    PyErr::new::<exc::ValueError, _>(py, e.to_string())
-                })?
+        let inner = if map.cast_as::<PyDict>(py).is_ok() {
+            let err = "pathutil.dirs() with a dict should only be used by the Python dirstatemap \
+                and should not be used when Rust is enabled";
+            return Err(PyErr::new::<exc::TypeError, _>(py, err.to_string()))
         } else {
             let map: Result<Vec<HgPathBuf>, PyErr> = map
                 .iter(py)?
--- a/tests/test-dirs.py	Mon Sep 20 12:52:32 2021 +0200
+++ b/tests/test-dirs.py	Mon Sep 20 13:16:36 2021 +0200
@@ -13,13 +13,13 @@
             (b'a/a/a', [b'a', b'a/a', b'']),
             (b'alpha/beta/gamma', [b'', b'alpha', b'alpha/beta']),
         ]:
-            d = pathutil.dirs({})
+            d = pathutil.dirs([])
             d.addpath(case)
             self.assertEqual(sorted(d), sorted(want))
 
     def testinvalid(self):
         with self.assertRaises(ValueError):
-            d = pathutil.dirs({})
+            d = pathutil.dirs([])
             d.addpath(b'a//b')