Merge pull request #454 from Alexander-N/doctest

Use doc-comment to test guide and readme
This commit is contained in:
konstin 2019-04-23 22:12:15 +02:00 committed by GitHub
commit ffb66a33b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 25 additions and 89 deletions

View File

@ -12,7 +12,6 @@ matrix:
include:
- name: Python 3.5
python: "3.5"
env: FEATURES="test-doc"
- name: Python 3.6
python: "3.6"
- name: Python 3.7

View File

@ -26,10 +26,10 @@ pyo3cls = { path = "pyo3cls", version = "=0.7.0-alpha.1" }
mashup = "0.1.9"
num-complex = { version = "0.2.1", optional = true }
inventory = "0.1.3"
doc-comment = "0.3"
[dev-dependencies]
assert_approx_eq = "1.1.0"
docmatic = "0.1.2"
indoc = "0.3.1"
[build-dependencies]
@ -52,9 +52,6 @@ extension-module = []
# are welcome.
# abi3 = []
# Use this feature to test the examples in the user guide
test-doc = []
[workspace]
members = [
"pyo3cls",

View File

@ -9,8 +9,6 @@ Here are some things you should check for submitting your pull request:
- If applicable, add an entry in the changelog.
- If applicable, add documentation to all new items and extend the guide.
- If applicable, add tests for all new or fixed functions
- Run `cargo test` or if you changed examples in README or the guide,
`cargo test --features test-doc` (you might have to clean out your
`target` directory if it complains about multiple matching libs)
- Run `cargo test` or if you changed examples in README or the guide
You might want to run `tox` (`pip install tox`) locally to check compatibility with all supported python versions. If you're using linux or mac you might find the Makefile helpful for testing.

View File

@ -53,9 +53,6 @@ features = ["extension-module"]
**`src/lib.rs`**
```rust
// Not required when using Rust 2018
extern crate pyo3;
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
@ -100,9 +97,6 @@ pyo3 = "0.7.0-alpha.1"
Example program displaying the value of `sys.version`:
```rust
// Not required when using Rust 2018
extern crate pyo3;
use pyo3::prelude::*;
use pyo3::types::IntoPyDict;

View File

@ -1,8 +1,6 @@
#!/bin/bash
set -ex
cargo clean
# run `cargo test` only if testing against cpython.
if ! [[ $FEATURES == *"pypy"* ]]; then
cargo test --features "$FEATURES num-complex"

View File

@ -9,6 +9,6 @@
- [Parallelism](parallelism.md)
- [Debugging](debugging.md)
- [Advanced Topics](advanced.md)
- [Building and Distribution](building-and-distribution.md)
- [Building and Distribution](building_and_distribution.md)
- [PyPy support](pypy.md)
- [Appendix: Pyo3 and rust-cpython](rust-cpython.md)
- [Appendix: PyO3 and rust-cpython](rust_cpython.md)

View File

@ -6,7 +6,6 @@ To define a custom python class, a rust struct needs to be annotated with the
`#[pyclass]` attribute.
```rust
# extern crate pyo3;
# use pyo3::prelude::*;
#[pyclass]
@ -36,7 +35,6 @@ You can get an instance of `PyRef` by `PyRef::new`, which does 3 things:
You can use `PyRef` just like `&T`, because it implements `Deref<Target=T>`.
```rust
# extern crate pyo3;
# use pyo3::prelude::*;
# use pyo3::types::PyDict;
#[pyclass]
@ -56,7 +54,6 @@ dict.set_item("obj", obj).unwrap();
### `PyRefMut`
`PyRefMut` is a mutable version of `PyRef`.
```rust
# extern crate pyo3;
# use pyo3::prelude::*;
#[pyclass]
struct MyClass {
@ -74,7 +71,6 @@ obj.num = 5;
You can use it to avoid lifetime problems.
```rust
# extern crate pyo3;
# use pyo3::prelude::*;
#[pyclass]
struct MyClass {
@ -113,7 +109,6 @@ To declare a constructor, you need to define a class method and annotate it with
attribute. Only the python `__new__` method can be specified, `__init__` is not available.
```rust
# extern crate pyo3;
# use pyo3::prelude::*;
# use pyo3::PyRawObject;
#[pyclass]
@ -155,7 +150,6 @@ By default `PyObject` is used as default base class. To override default base cl
with value of custom class struct. Subclass must call parent's `new` method.
```rust,ignore
# extern crate pyo3;
# use pyo3::prelude::*;
# use pyo3::PyRawObject;
#[pyclass]
@ -205,7 +199,6 @@ Descriptor methods can be defined in
attributes. i.e.
```rust
# extern crate pyo3;
# use pyo3::prelude::*;
# #[pyclass]
# struct MyClass {
@ -229,8 +222,7 @@ If function name starts with `get_` or `set_` for getter or setter respectively.
Descriptor name becomes function name with prefix removed. This is useful in case of
rust's special keywords like `type`.
```rust,ignore
# extern crate pyo3;
```rust
# use pyo3::prelude::*;
# #[pyclass]
# struct MyClass {
@ -258,8 +250,7 @@ In this case property `num` is defined. And it is available from python code as
Also both `#[getter]` and `#[setter]` attributes accepts one parameter.
If this parameter is specified, it is used as a property name. i.e.
```rust,ignore
# extern crate pyo3;
```rust
# use pyo3::prelude::*;
# #[pyclass]
# struct MyClass {
@ -286,8 +277,7 @@ In this case the property `number` is defined and is available from python code
For simple cases you can also define getters and setters in your Rust struct field definition, for example:
```rust,ignore
# extern crate pyo3;
```rust
# use pyo3::prelude::*;
#[pyclass]
struct MyClass {
@ -305,7 +295,6 @@ To define a python compatible method, `impl` block for struct has to be annotate
block with some variations, like descriptors, class method static methods, etc.
```rust
# extern crate pyo3;
# use pyo3::prelude::*;
# #[pyclass]
# struct MyClass {
@ -333,7 +322,6 @@ The return type must be `PyResult<T>` for some `T` that implements `IntoPyObject
get injected by method wrapper. i.e
```rust
# extern crate pyo3;
# use pyo3::prelude::*;
# #[pyclass]
# struct MyClass {
@ -357,7 +345,6 @@ To specify a class method for a custom class, the method needs to be annotated
with the `#[classmethod]` attribute.
```rust
# extern crate pyo3;
# use pyo3::prelude::*;
# use pyo3::types::PyType;
# #[pyclass]
@ -390,7 +377,6 @@ To specify a static method for a custom class, method needs to be annotated with
`IntoPyObject`.
```rust
# extern crate pyo3;
# use pyo3::prelude::*;
# #[pyclass]
# struct MyClass {
@ -413,7 +399,6 @@ To specify a custom `__call__` method for a custom class, call methods need to b
the `#[call]` attribute. Arguments of the method are specified same as for instance method.
```rust
# extern crate pyo3;
# use pyo3::prelude::*;
use pyo3::types::PyTuple;
# #[pyclass]
@ -456,7 +441,6 @@ Each parameter could be one of following type:
Example:
```rust
# extern crate pyo3;
# use pyo3::prelude::*;
use pyo3::types::{PyDict, PyTuple};
#

View File

@ -24,7 +24,6 @@ provides two methods:
Both methods accept `args` and `kwargs` arguments.
```rust
# extern crate pyo3;
use pyo3::prelude::*;
use pyo3::types::{PyDict, PyTuple};
@ -62,7 +61,6 @@ fn main() {
[`IntoPyDict`][IntoPyDict] trait to convert other dict-like containers, e.g. `HashMap`, `BTreeMap` as well as tuples with up to 10 elements and `Vec`s where each element is a two element tuple.
```rust
# extern crate pyo3;
use pyo3::prelude::*;
use pyo3::types::{IntoPyDict, PyDict};
use std::collections::HashMap;

View File

@ -5,7 +5,6 @@
You can use the `create_exception!` macro to define a new exception type:
```rust
# extern crate pyo3;
use pyo3::create_exception;
create_exception!(module, MyError, pyo3::exceptions::Exception);
@ -17,7 +16,6 @@ create_exception!(module, MyError, pyo3::exceptions::Exception);
For example:
```rust
# extern crate pyo3;
use pyo3::prelude::*;
use pyo3::create_exception;
use pyo3::types::IntoPyDict;
@ -40,7 +38,6 @@ fn main() {
To raise an exception, first you need to obtain an exception type and construct a new [`PyErr`](https://docs.rs/pyo3/0.7.0-alpha.1/struct.PyErr.html), then call [`PyErr::restore()`](https://docs.rs/pyo3/0.7.0-alpha.1/struct.PyErr.html#method.restore) method to write the exception back to the Python interpreter's global state.
```rust
# extern crate pyo3;
use pyo3::{Python, PyErr};
use pyo3::exceptions;
@ -65,7 +62,6 @@ has corresponding rust type, exceptions defined by `create_exception!` and `impo
have rust type as well.
```rust
# extern crate pyo3;
# use pyo3::exceptions;
# use pyo3::prelude::*;
# fn check_for_error() -> bool {false}
@ -84,7 +80,6 @@ Python has an [`isinstance`](https://docs.python.org/3/library/functions.html#is
in `PyO3` there is a [`Python::is_instance()`](https://docs.rs/pyo3/0.7.0-alpha.1/struct.Python.html#method.is_instance) method which does the same thing.
```rust
# extern crate pyo3;
use pyo3::Python;
use pyo3::types::{PyBool, PyList};
@ -103,7 +98,6 @@ fn main() {
To check the type of an exception, you can simply do:
```rust
# extern crate pyo3;
# use pyo3::exceptions;
# use pyo3::prelude::*;
# fn main() {
@ -155,7 +149,6 @@ The code snippet above will raise `OSError` in Python if `TcpListener::bind()` r
types so `try!` macro or `?` operator can be used.
```rust
# extern crate pyo3;
use pyo3::prelude::*;
fn parse_int(s: String) -> PyResult<usize> {
@ -173,7 +166,6 @@ It is possible to use exception defined in python code as native rust types.
for that exception.
```rust
# extern crate pyo3;
use pyo3::prelude::*;
use pyo3::import_exception;

View File

@ -6,7 +6,6 @@ the function to a [module](./module.md)
One way is defining the function in the module definition.
```rust
# extern crate pyo3;
use pyo3::prelude::*;
#[pymodule]
@ -31,7 +30,6 @@ as first parameter, the function name as second and an instance of `Python`
as third.
```rust
# extern crate pyo3;
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
@ -62,7 +60,6 @@ built-ins are new in Python 3 — in Python 2, it is simply considered to be par
of the doc-string.
```rust
# extern crate pyo3;
use pyo3::prelude::*;
/// add(a, b, /)

View File

@ -45,7 +45,6 @@ features = ["extension-module"]
**`src/lib.rs`**
```rust
# extern crate pyo3;
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
@ -90,7 +89,6 @@ pyo3 = "0.6"
Example program displaying the value of `sys.version`:
```rust
# extern crate pyo3;
use pyo3::prelude::*;
use pyo3::types::IntoPyDict;

View File

@ -3,7 +3,6 @@
As shown in the Getting Started chapter, you can create a module as follows:
```rust
# extern crate pyo3;
use pyo3::prelude::*;
// add bindings to the generated python module
@ -53,7 +52,6 @@ Which means that the above Python code will print `This module is implemented in
In python, modules are first class objects. This means can store them as values or add them to dicts or other modules:
```rust
# extern crate pyo3;
use pyo3::prelude::*;
use pyo3::{wrap_pyfunction, wrap_pymodule};
use pyo3::types::IntoPyDict;

View File

@ -25,7 +25,6 @@ py_class!(class MyClass |py| {
**pyo3**
```rust
# extern crate pyo3;
use pyo3::prelude::*;
use pyo3::PyRawObject;

View File

@ -116,6 +116,24 @@
//! Ok(())
//! }
//! ```
use doc_comment::doctest;
// Test readme and user guide
doctest!("../README.md", readme_md);
doctest!("../guide/src/advanced.md", guide_advanced_md);
doctest!(
"../guide/src/building_and_distribution.md",
guide_building_and_distribution_md
);
doctest!("../guide/src/class.md", guide_class_md);
doctest!("../guide/src/conversions.md", guide_conversions_md);
doctest!("../guide/src/debugging.md", guide_debugging_md);
doctest!("../guide/src/exception.md", guide_exception_md);
doctest!("../guide/src/function.md", guide_function_md);
doctest!("../guide/src/get_started.md", guide_get_started_md);
doctest!("../guide/src/module.md", guide_module_md);
doctest!("../guide/src/parallelism.md", guide_parallelism_md);
doctest!("../guide/src/rust_cpython.md", guide_rust_cpython_md);
pub use crate::class::*;
pub use crate::conversion::{

View File

@ -1,34 +0,0 @@
#[cfg(feature = "test-doc")]
use {
docmatic,
std::default::Default,
std::path::{Path, PathBuf},
};
#[cfg(feature = "test-doc")]
fn assert_file<P: AsRef<Path>>(path: P) {
let mut doc = docmatic::Assert::default();
if cfg!(windows) {
doc.library_path(
option_env!("PYTHON")
.map(|py| PathBuf::from(py).join("libs"))
.unwrap(),
);
}
doc.test_file(path.as_ref())
}
#[test]
#[cfg(feature = "test-doc")]
fn test_guide() {
let guide_path = PathBuf::from("guide").join("src");
for entry in guide_path.read_dir().unwrap() {
assert_file(entry.unwrap().path())
}
}
#[test]
#[cfg(feature = "test-doc")]
fn test_readme() {
assert_file("README.md")
}