diff --git a/.travis.yml b/.travis.yml index da864c74126..b040dee461d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/Cargo.toml b/Cargo.toml index e4f48c7efb4..68517b078f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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", diff --git a/Contributing.md b/Contributing.md index 71b7ae4c502..2c1439ea50b 100644 --- a/Contributing.md +++ b/Contributing.md @@ -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. diff --git a/README.md b/README.md index d086b53f43e..bd81b3f11bd 100644 --- a/README.md +++ b/README.md @@ -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; diff --git a/ci/travis/test.sh b/ci/travis/test.sh index 728e50f744a..6c4c719a393 100755 --- a/ci/travis/test.sh +++ b/ci/travis/test.sh @@ -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" diff --git a/guide/src/SUMMARY.md b/guide/src/SUMMARY.md index 405bb6ac777..d9c755f43bb 100644 --- a/guide/src/SUMMARY.md +++ b/guide/src/SUMMARY.md @@ -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) diff --git a/guide/src/building-and-distribution.md b/guide/src/building_and_distribution.md similarity index 100% rename from guide/src/building-and-distribution.md rename to guide/src/building_and_distribution.md diff --git a/guide/src/class.md b/guide/src/class.md index 885d94e9e5b..0d9e1c7d026 100644 --- a/guide/src/class.md +++ b/guide/src/class.md @@ -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`. ```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` 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}; # diff --git a/guide/src/conversions.md b/guide/src/conversions.md index 39507095048..6a113cd21e4 100644 --- a/guide/src/conversions.md +++ b/guide/src/conversions.md @@ -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; diff --git a/guide/src/exception.md b/guide/src/exception.md index 1f6c58e82f2..cd93b2232fd 100644 --- a/guide/src/exception.md +++ b/guide/src/exception.md @@ -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 { @@ -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; diff --git a/guide/src/function.md b/guide/src/function.md index 836d723fb78..0b951fe1648 100644 --- a/guide/src/function.md +++ b/guide/src/function.md @@ -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, /) diff --git a/guide/src/get_started.md b/guide/src/get_started.md index c1843343fe1..c4b143f66bf 100644 --- a/guide/src/get_started.md +++ b/guide/src/get_started.md @@ -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; diff --git a/guide/src/module.md b/guide/src/module.md index 505487c5c88..b1aec9cc253 100644 --- a/guide/src/module.md +++ b/guide/src/module.md @@ -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; diff --git a/guide/src/rust-cpython.md b/guide/src/rust_cpython.md similarity index 99% rename from guide/src/rust-cpython.md rename to guide/src/rust_cpython.md index 25dbc176aa5..b124c6d8132 100644 --- a/guide/src/rust-cpython.md +++ b/guide/src/rust_cpython.md @@ -25,7 +25,6 @@ py_class!(class MyClass |py| { **pyo3** ```rust -# extern crate pyo3; use pyo3::prelude::*; use pyo3::PyRawObject; diff --git a/src/lib.rs b/src/lib.rs index 56c71130761..454966d3405 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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::{ diff --git a/tests/test_doc.rs b/tests/test_doc.rs deleted file mode 100644 index 6309d4667fd..00000000000 --- a/tests/test_doc.rs +++ /dev/null @@ -1,34 +0,0 @@ -#[cfg(feature = "test-doc")] -use { - docmatic, - std::default::Default, - std::path::{Path, PathBuf}, -}; - -#[cfg(feature = "test-doc")] -fn assert_file>(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") -}