(&self, value: &PyObject, func: F)
| 1823 | } |
| 1824 | |
| 1825 | pub fn extract_elements_with<T, F>(&self, value: &PyObject, func: F) -> PyResult<Vec<T>> |
| 1826 | where |
| 1827 | F: Fn(PyObjectRef) -> PyResult<T>, |
| 1828 | { |
| 1829 | // Type-specific fast paths corresponding to _list_extend() in CPython |
| 1830 | // Objects/listobject.c. Each branch takes an atomic snapshot to avoid |
| 1831 | // race conditions from concurrent mutation (no GIL). |
| 1832 | let cls = value.class(); |
| 1833 | let list_borrow; |
| 1834 | let slice = if cls.is(self.ctx.types.tuple_type) { |
| 1835 | value.downcast_ref::<PyTuple>().unwrap().as_slice() |
| 1836 | } else if cls.is(self.ctx.types.list_type) { |
| 1837 | list_borrow = value.downcast_ref::<PyList>().unwrap().borrow_vec(); |
| 1838 | &list_borrow |
| 1839 | } else if cls.is(self.ctx.types.dict_type) { |
| 1840 | let keys = value.downcast_ref::<PyDict>().unwrap().keys_vec(); |
| 1841 | return keys.into_iter().map(func).collect(); |
| 1842 | } else if cls.is(self.ctx.types.dict_keys_type) { |
| 1843 | let keys = value.downcast_ref::<PyDictKeys>().unwrap().dict.keys_vec(); |
| 1844 | return keys.into_iter().map(func).collect(); |
| 1845 | } else if cls.is(self.ctx.types.dict_values_type) { |
| 1846 | let values = value |
| 1847 | .downcast_ref::<PyDictValues>() |
| 1848 | .unwrap() |
| 1849 | .dict |
| 1850 | .values_vec(); |
| 1851 | return values.into_iter().map(func).collect(); |
| 1852 | } else if cls.is(self.ctx.types.dict_items_type) { |
| 1853 | let items = value |
| 1854 | .downcast_ref::<PyDictItems>() |
| 1855 | .unwrap() |
| 1856 | .dict |
| 1857 | .items_vec(); |
| 1858 | return items |
| 1859 | .into_iter() |
| 1860 | .map(|(k, v)| func(self.ctx.new_tuple(vec![k, v]).into())) |
| 1861 | .collect(); |
| 1862 | } else { |
| 1863 | return self.map_py_iter(value, func); |
| 1864 | }; |
| 1865 | slice.iter().map(|obj| func(obj.clone())).collect() |
| 1866 | } |
| 1867 | |
| 1868 | pub fn map_iterable_object<F, R>(&self, obj: &PyObject, mut f: F) -> PyResult<PyResult<Vec<R>>> |
| 1869 | where |
no test coverage detected