##// END OF EJS Templates
rust-cpython: add panicking version of borrow_mut() and use it...
Yuya Nishihara -
r44664:cacdc766 default draft
parent child Browse files
Show More
@@ -72,7 +72,7 b' py_class!(pub class Dirs |py| {'
72 }
72 }
73
73
74 def addpath(&self, path: PyObject) -> PyResult<PyObject> {
74 def addpath(&self, path: PyObject) -> PyResult<PyObject> {
75 self.inner_shared(py).borrow_mut()?.add_path(
75 self.inner_shared(py).borrow_mut().add_path(
76 HgPath::new(path.extract::<PyBytes>(py)?.data(py)),
76 HgPath::new(path.extract::<PyBytes>(py)?.data(py)),
77 ).and(Ok(py.None())).or_else(|e| {
77 ).and(Ok(py.None())).or_else(|e| {
78 match e {
78 match e {
@@ -90,7 +90,7 b' py_class!(pub class Dirs |py| {'
90 }
90 }
91
91
92 def delpath(&self, path: PyObject) -> PyResult<PyObject> {
92 def delpath(&self, path: PyObject) -> PyResult<PyObject> {
93 self.inner_shared(py).borrow_mut()?.delete_path(
93 self.inner_shared(py).borrow_mut().delete_path(
94 HgPath::new(path.extract::<PyBytes>(py)?.data(py)),
94 HgPath::new(path.extract::<PyBytes>(py)?.data(py)),
95 )
95 )
96 .and(Ok(py.None()))
96 .and(Ok(py.None()))
@@ -53,7 +53,7 b' py_class!(pub class DirstateMap |py| {'
53 }
53 }
54
54
55 def clear(&self) -> PyResult<PyObject> {
55 def clear(&self) -> PyResult<PyObject> {
56 self.inner_shared(py).borrow_mut()?.clear();
56 self.inner_shared(py).borrow_mut().clear();
57 Ok(py.None())
57 Ok(py.None())
58 }
58 }
59
59
@@ -80,7 +80,7 b' py_class!(pub class DirstateMap |py| {'
80 size: PyObject,
80 size: PyObject,
81 mtime: PyObject
81 mtime: PyObject
82 ) -> PyResult<PyObject> {
82 ) -> PyResult<PyObject> {
83 self.inner_shared(py).borrow_mut()?.add_file(
83 self.inner_shared(py).borrow_mut().add_file(
84 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
84 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
85 oldstate.extract::<PyBytes>(py)?.data(py)[0]
85 oldstate.extract::<PyBytes>(py)?.data(py)[0]
86 .try_into()
86 .try_into()
@@ -108,7 +108,7 b' py_class!(pub class DirstateMap |py| {'
108 oldstate: PyObject,
108 oldstate: PyObject,
109 size: PyObject
109 size: PyObject
110 ) -> PyResult<PyObject> {
110 ) -> PyResult<PyObject> {
111 self.inner_shared(py).borrow_mut()?
111 self.inner_shared(py).borrow_mut()
112 .remove_file(
112 .remove_file(
113 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
113 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
114 oldstate.extract::<PyBytes>(py)?.data(py)[0]
114 oldstate.extract::<PyBytes>(py)?.data(py)[0]
@@ -132,7 +132,7 b' py_class!(pub class DirstateMap |py| {'
132 f: PyObject,
132 f: PyObject,
133 oldstate: PyObject
133 oldstate: PyObject
134 ) -> PyResult<PyBool> {
134 ) -> PyResult<PyBool> {
135 self.inner_shared(py).borrow_mut()?
135 self.inner_shared(py).borrow_mut()
136 .drop_file(
136 .drop_file(
137 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
137 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
138 oldstate.extract::<PyBytes>(py)?.data(py)[0]
138 oldstate.extract::<PyBytes>(py)?.data(py)[0]
@@ -163,7 +163,7 b' py_class!(pub class DirstateMap |py| {'
163 ))
163 ))
164 })
164 })
165 .collect();
165 .collect();
166 self.inner_shared(py).borrow_mut()?
166 self.inner_shared(py).borrow_mut()
167 .clear_ambiguous_times(files?, now.extract(py)?);
167 .clear_ambiguous_times(files?, now.extract(py)?);
168 Ok(py.None())
168 Ok(py.None())
169 }
169 }
@@ -198,7 +198,7 b' py_class!(pub class DirstateMap |py| {'
198
198
199 def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> {
199 def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> {
200 let d = d.extract::<PyBytes>(py)?;
200 let d = d.extract::<PyBytes>(py)?;
201 Ok(self.inner_shared(py).borrow_mut()?
201 Ok(self.inner_shared(py).borrow_mut()
202 .has_tracked_dir(HgPath::new(d.data(py)))
202 .has_tracked_dir(HgPath::new(d.data(py)))
203 .map_err(|e| {
203 .map_err(|e| {
204 PyErr::new::<exc::ValueError, _>(py, e.to_string())
204 PyErr::new::<exc::ValueError, _>(py, e.to_string())
@@ -208,7 +208,7 b' py_class!(pub class DirstateMap |py| {'
208
208
209 def hasdir(&self, d: PyObject) -> PyResult<PyBool> {
209 def hasdir(&self, d: PyObject) -> PyResult<PyBool> {
210 let d = d.extract::<PyBytes>(py)?;
210 let d = d.extract::<PyBytes>(py)?;
211 Ok(self.inner_shared(py).borrow_mut()?
211 Ok(self.inner_shared(py).borrow_mut()
212 .has_dir(HgPath::new(d.data(py)))
212 .has_dir(HgPath::new(d.data(py)))
213 .map_err(|e| {
213 .map_err(|e| {
214 PyErr::new::<exc::ValueError, _>(py, e.to_string())
214 PyErr::new::<exc::ValueError, _>(py, e.to_string())
@@ -217,7 +217,7 b' py_class!(pub class DirstateMap |py| {'
217 }
217 }
218
218
219 def parents(&self, st: PyObject) -> PyResult<PyTuple> {
219 def parents(&self, st: PyObject) -> PyResult<PyTuple> {
220 self.inner_shared(py).borrow_mut()?
220 self.inner_shared(py).borrow_mut()
221 .parents(st.extract::<PyBytes>(py)?.data(py))
221 .parents(st.extract::<PyBytes>(py)?.data(py))
222 .and_then(|d| {
222 .and_then(|d| {
223 Ok((PyBytes::new(py, &d.p1), PyBytes::new(py, &d.p2))
223 Ok((PyBytes::new(py, &d.p1), PyBytes::new(py, &d.p2))
@@ -235,13 +235,13 b' py_class!(pub class DirstateMap |py| {'
235 let p1 = extract_node_id(py, &p1)?;
235 let p1 = extract_node_id(py, &p1)?;
236 let p2 = extract_node_id(py, &p2)?;
236 let p2 = extract_node_id(py, &p2)?;
237
237
238 self.inner_shared(py).borrow_mut()?
238 self.inner_shared(py).borrow_mut()
239 .set_parents(&DirstateParents { p1, p2 });
239 .set_parents(&DirstateParents { p1, p2 });
240 Ok(py.None())
240 Ok(py.None())
241 }
241 }
242
242
243 def read(&self, st: PyObject) -> PyResult<Option<PyObject>> {
243 def read(&self, st: PyObject) -> PyResult<Option<PyObject>> {
244 match self.inner_shared(py).borrow_mut()?
244 match self.inner_shared(py).borrow_mut()
245 .read(st.extract::<PyBytes>(py)?.data(py))
245 .read(st.extract::<PyBytes>(py)?.data(py))
246 {
246 {
247 Ok(Some(parents)) => Ok(Some(
247 Ok(Some(parents)) => Ok(Some(
@@ -268,7 +268,7 b' py_class!(pub class DirstateMap |py| {'
268 p2: extract_node_id(py, &p2)?,
268 p2: extract_node_id(py, &p2)?,
269 };
269 };
270
270
271 match self.inner_shared(py).borrow_mut()?.pack(parents, now) {
271 match self.inner_shared(py).borrow_mut().pack(parents, now) {
272 Ok(packed) => Ok(PyBytes::new(py, &packed)),
272 Ok(packed) => Ok(PyBytes::new(py, &packed)),
273 Err(_) => Err(PyErr::new::<exc::OSError, _>(
273 Err(_) => Err(PyErr::new::<exc::OSError, _>(
274 py,
274 py,
@@ -280,7 +280,7 b' py_class!(pub class DirstateMap |py| {'
280 def filefoldmapasdict(&self) -> PyResult<PyDict> {
280 def filefoldmapasdict(&self) -> PyResult<PyDict> {
281 let dict = PyDict::new(py);
281 let dict = PyDict::new(py);
282 for (key, value) in
282 for (key, value) in
283 self.inner_shared(py).borrow_mut()?.build_file_fold_map().iter()
283 self.inner_shared(py).borrow_mut().build_file_fold_map().iter()
284 {
284 {
285 dict.set_item(py, key.as_ref().to_vec(), value.as_ref().to_vec())?;
285 dict.set_item(py, key.as_ref().to_vec(), value.as_ref().to_vec())?;
286 }
286 }
@@ -336,7 +336,7 b' py_class!(pub class DirstateMap |py| {'
336
336
337 def getdirs(&self) -> PyResult<Dirs> {
337 def getdirs(&self) -> PyResult<Dirs> {
338 // TODO don't copy, share the reference
338 // TODO don't copy, share the reference
339 self.inner_shared(py).borrow_mut()?.set_dirs()
339 self.inner_shared(py).borrow_mut().set_dirs()
340 .map_err(|e| {
340 .map_err(|e| {
341 PyErr::new::<exc::ValueError, _>(py, e.to_string())
341 PyErr::new::<exc::ValueError, _>(py, e.to_string())
342 })?;
342 })?;
@@ -353,7 +353,7 b' py_class!(pub class DirstateMap |py| {'
353 }
353 }
354 def getalldirs(&self) -> PyResult<Dirs> {
354 def getalldirs(&self) -> PyResult<Dirs> {
355 // TODO don't copy, share the reference
355 // TODO don't copy, share the reference
356 self.inner_shared(py).borrow_mut()?.set_all_dirs()
356 self.inner_shared(py).borrow_mut().set_all_dirs()
357 .map_err(|e| {
357 .map_err(|e| {
358 PyErr::new::<exc::ValueError, _>(py, e.to_string())
358 PyErr::new::<exc::ValueError, _>(py, e.to_string())
359 })?;
359 })?;
@@ -431,7 +431,7 b' py_class!(pub class DirstateMap |py| {'
431 ) -> PyResult<PyObject> {
431 ) -> PyResult<PyObject> {
432 let key = key.extract::<PyBytes>(py)?;
432 let key = key.extract::<PyBytes>(py)?;
433 let value = value.extract::<PyBytes>(py)?;
433 let value = value.extract::<PyBytes>(py)?;
434 self.inner_shared(py).borrow_mut()?.copy_map.insert(
434 self.inner_shared(py).borrow_mut().copy_map.insert(
435 HgPathBuf::from_bytes(key.data(py)),
435 HgPathBuf::from_bytes(key.data(py)),
436 HgPathBuf::from_bytes(value.data(py)),
436 HgPathBuf::from_bytes(value.data(py)),
437 );
437 );
@@ -445,7 +445,7 b' py_class!(pub class DirstateMap |py| {'
445 let key = key.extract::<PyBytes>(py)?;
445 let key = key.extract::<PyBytes>(py)?;
446 match self
446 match self
447 .inner_shared(py)
447 .inner_shared(py)
448 .borrow_mut()?
448 .borrow_mut()
449 .copy_map
449 .copy_map
450 .remove(HgPath::new(key.data(py)))
450 .remove(HgPath::new(key.data(py)))
451 {
451 {
@@ -202,7 +202,19 b" impl<'a, T> PySharedRef<'a, T> {"
202 self.data.borrow(self.py)
202 self.data.borrow(self.py)
203 }
203 }
204
204
205 pub fn borrow_mut(&self) -> PyResult<RefMut<'a, T>> {
205 /// Mutably borrows the wrapped value.
206 ///
207 /// # Panics
208 ///
209 /// Panics if the value is currently borrowed through `PySharedRef`
210 /// or `PyLeaked`.
211 pub fn borrow_mut(&self) -> RefMut<'a, T> {
212 self.try_borrow_mut().expect("already borrowed")
213 }
214
215 /// Mutably borrows the wrapped value, returning an error if the value
216 /// is currently borrowed.
217 pub fn try_borrow_mut(&self) -> PyResult<RefMut<'a, T>> {
206 self.data.try_borrow_mut(self.py)
218 self.data.try_borrow_mut(self.py)
207 }
219 }
208
220
@@ -572,7 +584,7 b' mod test {'
572 let (gil, owner) = prepare_env();
584 let (gil, owner) = prepare_env();
573 let py = gil.python();
585 let py = gil.python();
574 let leaked = owner.string_shared(py).leak_immutable();
586 let leaked = owner.string_shared(py).leak_immutable();
575 owner.string_shared(py).borrow_mut().unwrap().clear();
587 owner.string_shared(py).borrow_mut().clear();
576 assert!(leaked.try_borrow(py).is_err());
588 assert!(leaked.try_borrow(py).is_err());
577 }
589 }
578
590
@@ -582,7 +594,7 b' mod test {'
582 let py = gil.python();
594 let py = gil.python();
583 let leaked = owner.string_shared(py).leak_immutable();
595 let leaked = owner.string_shared(py).leak_immutable();
584 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) };
596 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) };
585 owner.string_shared(py).borrow_mut().unwrap().clear();
597 owner.string_shared(py).borrow_mut().clear();
586 assert!(leaked_iter.try_borrow_mut(py).is_err());
598 assert!(leaked_iter.try_borrow_mut(py).is_err());
587 }
599 }
588
600
@@ -592,40 +604,40 b' mod test {'
592 let (gil, owner) = prepare_env();
604 let (gil, owner) = prepare_env();
593 let py = gil.python();
605 let py = gil.python();
594 let leaked = owner.string_shared(py).leak_immutable();
606 let leaked = owner.string_shared(py).leak_immutable();
595 owner.string_shared(py).borrow_mut().unwrap().clear();
607 owner.string_shared(py).borrow_mut().clear();
596 let _leaked_iter = unsafe { leaked.map(py, |s| s.chars()) };
608 let _leaked_iter = unsafe { leaked.map(py, |s| s.chars()) };
597 }
609 }
598
610
599 #[test]
611 #[test]
600 fn test_borrow_mut_while_leaked_ref() {
612 fn test_try_borrow_mut_while_leaked_ref() {
601 let (gil, owner) = prepare_env();
613 let (gil, owner) = prepare_env();
602 let py = gil.python();
614 let py = gil.python();
603 assert!(owner.string_shared(py).borrow_mut().is_ok());
615 assert!(owner.string_shared(py).try_borrow_mut().is_ok());
604 let leaked = owner.string_shared(py).leak_immutable();
616 let leaked = owner.string_shared(py).leak_immutable();
605 {
617 {
606 let _leaked_ref = leaked.try_borrow(py).unwrap();
618 let _leaked_ref = leaked.try_borrow(py).unwrap();
607 assert!(owner.string_shared(py).borrow_mut().is_err());
619 assert!(owner.string_shared(py).try_borrow_mut().is_err());
608 {
620 {
609 let _leaked_ref2 = leaked.try_borrow(py).unwrap();
621 let _leaked_ref2 = leaked.try_borrow(py).unwrap();
610 assert!(owner.string_shared(py).borrow_mut().is_err());
622 assert!(owner.string_shared(py).try_borrow_mut().is_err());
611 }
623 }
612 assert!(owner.string_shared(py).borrow_mut().is_err());
624 assert!(owner.string_shared(py).try_borrow_mut().is_err());
613 }
625 }
614 assert!(owner.string_shared(py).borrow_mut().is_ok());
626 assert!(owner.string_shared(py).try_borrow_mut().is_ok());
615 }
627 }
616
628
617 #[test]
629 #[test]
618 fn test_borrow_mut_while_leaked_ref_mut() {
630 fn test_try_borrow_mut_while_leaked_ref_mut() {
619 let (gil, owner) = prepare_env();
631 let (gil, owner) = prepare_env();
620 let py = gil.python();
632 let py = gil.python();
621 assert!(owner.string_shared(py).borrow_mut().is_ok());
633 assert!(owner.string_shared(py).try_borrow_mut().is_ok());
622 let leaked = owner.string_shared(py).leak_immutable();
634 let leaked = owner.string_shared(py).leak_immutable();
623 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) };
635 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) };
624 {
636 {
625 let _leaked_ref = leaked_iter.try_borrow_mut(py).unwrap();
637 let _leaked_ref = leaked_iter.try_borrow_mut(py).unwrap();
626 assert!(owner.string_shared(py).borrow_mut().is_err());
638 assert!(owner.string_shared(py).try_borrow_mut().is_err());
627 }
639 }
628 assert!(owner.string_shared(py).borrow_mut().is_ok());
640 assert!(owner.string_shared(py).try_borrow_mut().is_ok());
629 }
641 }
630
642
631 #[test]
643 #[test]
@@ -638,10 +650,19 b' mod test {'
638 }
650 }
639
651
640 #[test]
652 #[test]
653 fn test_try_borrow_mut_while_borrow() {
654 let (gil, owner) = prepare_env();
655 let py = gil.python();
656 let _ref = owner.string_shared(py).borrow();
657 assert!(owner.string_shared(py).try_borrow_mut().is_err());
658 }
659
660 #[test]
661 #[should_panic(expected = "already borrowed")]
641 fn test_borrow_mut_while_borrow() {
662 fn test_borrow_mut_while_borrow() {
642 let (gil, owner) = prepare_env();
663 let (gil, owner) = prepare_env();
643 let py = gil.python();
664 let py = gil.python();
644 let _ref = owner.string_shared(py).borrow();
665 let _ref = owner.string_shared(py).borrow();
645 assert!(owner.string_shared(py).borrow_mut().is_err());
666 owner.string_shared(py).borrow_mut();
646 }
667 }
647 }
668 }
General Comments 0
You need to be logged in to leave comments. Login now