Merge branch 'master' into pyclass-new-layout

This commit is contained in:
kngwyu 2019-12-29 23:51:51 +09:00
commit 8f8785d7c2
4 changed files with 68 additions and 23 deletions

View file

@ -1,34 +1,33 @@
name: Test
on: [push]
on: [push, pull_request]
jobs:
build:
runs-on: windows-latest
strategy:
max-parallel: 3
max-parallel: 4
matrix:
python-version: [3.5, 3.6, 3.7]
steps:
- uses: actions/checkout@v1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Set Python PATH
run: ci/actions/setup
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
default: true
- name: Build
run: cargo build --verbose
- name: Install test dependencies
run: |
python -m pip install -U pip setuptools
pip install setuptools-rust pytest pytest-benchmark tox tox-venv
- name: Test
run: ci/actions/test
- uses: actions/checkout@v1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Set Python PATH
run: ci/actions/setup
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
default: true
- name: Build
run: cargo build --verbose
- name: Install test dependencies
run: |
python -m pip install -U pip setuptools
pip install setuptools-rust pytest pytest-benchmark tox tox-venv
- name: Test
run: ci/actions/test

View file

@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## Unreleased
* Support for `#[name = "foo"]` attribute for `#[pyfunction]` and in `#[pymethods]`. [#692](https://github.com/PyO3/pyo3/pull/692)
* Implemented `FromPyObject` for `HashMap` and `BTreeMap`
## [0.8.4]

2
src/lib.rs Normal file → Executable file
View file

@ -157,6 +157,8 @@ pub mod derive_utils;
mod err;
pub mod exceptions;
/// Raw ffi declarations for the c interface of python
#[allow(clippy::unknown_clippy_lints)]
#[allow(clippy::missing_safety_doc)]
pub mod ffi;
pub mod freelist;
mod gil;

View file

@ -10,7 +10,9 @@ use crate::AsPyPointer;
use crate::IntoPyPointer;
use crate::Python;
use crate::{ffi, IntoPy};
use crate::{FromPyObject, PyTryFrom};
use crate::{ToBorrowedObject, ToPyObject};
use std::collections::{BTreeMap, HashMap};
use std::{cmp, collections, hash};
/// Represents a Python `dict`.
@ -308,6 +310,37 @@ where
}
}
impl<'source, K, V, S> FromPyObject<'source> for HashMap<K, V, S>
where
K: FromPyObject<'source> + cmp::Eq + hash::Hash,
V: FromPyObject<'source>,
S: hash::BuildHasher + Default,
{
fn extract(ob: &'source PyAny) -> Result<Self, PyErr> {
let dict = <PyDict as PyTryFrom>::try_from(ob)?;
let mut ret = HashMap::default();
for (k, v) in dict.iter() {
ret.insert(K::extract(k)?, V::extract(v)?);
}
Ok(ret)
}
}
impl<'source, K, V> FromPyObject<'source> for BTreeMap<K, V>
where
K: FromPyObject<'source> + cmp::Ord,
V: FromPyObject<'source>,
{
fn extract(ob: &'source PyAny) -> Result<Self, PyErr> {
let dict = <PyDict as PyTryFrom>::try_from(ob)?;
let mut ret = BTreeMap::new();
for (k, v) in dict.iter() {
ret.insert(K::extract(k)?, V::extract(v)?);
}
Ok(ret)
}
}
#[cfg(test)]
mod test {
use crate::conversion::IntoPy;
@ -326,6 +359,10 @@ mod test {
let dict = [(7, 32)].into_py_dict(py);
assert_eq!(32, dict.get_item(7i32).unwrap().extract::<i32>().unwrap());
assert_eq!(None, dict.get_item(8i32));
let map: HashMap<i32, i32> = [(7, 32)].iter().cloned().collect();
assert_eq!(map, dict.extract().unwrap());
let map: BTreeMap<i32, i32> = [(7, 32)].iter().cloned().collect();
assert_eq!(map, dict.extract().unwrap());
}
#[test]
@ -336,6 +373,10 @@ mod test {
let dict = PyDict::from_sequence(py, items.to_object(py)).unwrap();
assert_eq!(1, dict.get_item("a").unwrap().extract::<i32>().unwrap());
assert_eq!(2, dict.get_item("b").unwrap().extract::<i32>().unwrap());
let map: HashMap<&str, i32> = [("a", 1), ("b", 2)].iter().cloned().collect();
assert_eq!(map, dict.extract().unwrap());
let map: BTreeMap<&str, i32> = [("a", 1), ("b", 2)].iter().cloned().collect();
assert_eq!(map, dict.extract().unwrap());
}
#[test]
@ -582,6 +623,7 @@ mod test {
assert!(py_map.len() == 1);
assert!(py_map.get_item(1).unwrap().extract::<i32>().unwrap() == 1);
assert_eq!(map, py_map.extract().unwrap());
}
#[test]
@ -597,6 +639,7 @@ mod test {
assert!(py_map.len() == 1);
assert!(py_map.get_item(1).unwrap().extract::<i32>().unwrap() == 1);
assert_eq!(map, py_map.extract().unwrap());
}
#[test]