Skip to content

Commit 2c4ff73

Browse files
committed
Test examples in user guide with travis
Also ignore inheritance example in class.md since it does not work currently, see PyO3#381
1 parent 0866dd8 commit 2c4ff73

File tree

12 files changed

+58
-10
lines changed

12 files changed

+58
-10
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ extension-module = []
5555
# are welcome.
5656
# abi3 = []
5757

58+
# Use this feature to test the examples in the user guide
59+
test-doc = []
60+
5861
[workspace]
5962
members = [
6063
"pyo3cls",

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ features = ["extension-module"]
5151
**`src/lib.rs`**
5252

5353
```rust
54+
// Not required when using Rust 2018
55+
extern crate pyo3;
56+
5457
use pyo3::prelude::*;
5558
use pyo3::wrap_pyfunction;
5659

@@ -95,6 +98,9 @@ pyo3 = "0.6.0-alpha.4"
9598
Example program displaying the value of `sys.version`:
9699

97100
```rust
101+
// Not required when using Rust 2018
102+
extern crate pyo3;
103+
98104
use pyo3::prelude::*;
99105
use pyo3::types::PyDict;
100106

ci/travis/test.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#!/bin/bash
22
set -ex
33

4-
cargo test --features "$FEATURES num-complex"
4+
cargo clean
5+
cargo test --features "$FEATURES num-complex test-doc"
56
if [ $TRAVIS_JOB_NAME = 'Minimum nightly' ]; then
67
cargo fmt --all -- --check
78
cargo clippy --features "$FEATURES num-complex"

guide/src/class.md

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
To define python custom class, rust struct needs to be annotated with `#[pyclass]` attribute.
66

77
```rust
8+
# extern crate pyo3;
89
# use pyo3::prelude::*;
910

1011
#[pyclass]
@@ -34,6 +35,7 @@ You can get an instance of `PyRef` by `PyRef::new`, which does 3 things:
3435

3536
You can use `PyRef` just like `&T`, because it implements `Deref<Target=T>`.
3637
```rust
38+
# extern crate pyo3;
3739
# use pyo3::prelude::*;
3840
# use pyo3::types::PyDict;
3941
#[pyclass]
@@ -53,6 +55,7 @@ dict.set_item("obj", obj).unwrap();
5355
### `PyRefMut`
5456
`PyRefMut` is a mutable version of `PyRef`.
5557
```rust
58+
# extern crate pyo3;
5659
# use pyo3::prelude::*;
5760
#[pyclass]
5861
struct MyClass {
@@ -70,6 +73,7 @@ obj.num = 5;
7073

7174
You can use it to avoid lifetime problems.
7275
```rust
76+
# extern crate pyo3;
7377
# use pyo3::prelude::*;
7478
#[pyclass]
7579
struct MyClass {
@@ -109,6 +113,7 @@ To declare a constructor, you need to define a class method and annotate it with
109113
attribute. Only the python `__new__` method can be specified, `__init__` is not available.
110114

111115
```rust
116+
# extern crate pyo3;
112117
# use pyo3::prelude::*;
113118
# use pyo3::PyRawObject;
114119
#[pyclass]
@@ -149,7 +154,8 @@ By default `PyObject` is used as default base class. To override default base cl
149154
`new` method accepts `PyRawObject` object. `obj` instance must be initialized
150155
with value of custom class struct. Subclass must call parent's `new` method.
151156

152-
```rust
157+
```rust,ignore
158+
# extern crate pyo3;
153159
# use pyo3::prelude::*;
154160
# use pyo3::PyRawObject;
155161
#[pyclass]
@@ -183,7 +189,7 @@ impl SubClass {
183189
}
184190
185191
fn method2(&self) -> PyResult<()> {
186-
self.get_base().method()
192+
self.get_base().method()
187193
}
188194
}
189195
```
@@ -199,6 +205,7 @@ Descriptor methods can be defined in
199205
attributes. i.e.
200206

201207
```rust
208+
# extern crate pyo3;
202209
# use pyo3::prelude::*;
203210
# #[pyclass]
204211
# struct MyClass {
@@ -223,6 +230,7 @@ Descriptor name becomes function name with prefix removed. This is useful in cas
223230
rust's special keywords like `type`.
224231

225232
```rust
233+
# extern crate pyo3;
226234
# use pyo3::prelude::*;
227235
# #[pyclass]
228236
# struct MyClass {
@@ -251,6 +259,7 @@ Also both `#[getter]` and `#[setter]` attributes accepts one parameter.
251259
If parameter is specified, it is used and property name. i.e.
252260

253261
```rust
262+
# extern crate pyo3;
254263
# use pyo3::prelude::*;
255264
# #[pyclass]
256265
# struct MyClass {
@@ -278,6 +287,7 @@ In this case property `number` is defined. And it is available from python code
278287
For simple cases you can also define getters and setters in your Rust struct field definition, for example:
279288

280289
```rust
290+
# extern crate pyo3;
281291
# use pyo3::prelude::*;
282292
#[pyclass]
283293
struct MyClass {
@@ -296,6 +306,7 @@ wrappers for all functions in this block with some variations, like descriptors,
296306
class method static methods, etc.
297307

298308
```rust
309+
# extern crate pyo3;
299310
# use pyo3::prelude::*;
300311
# #[pyclass]
301312
# struct MyClass {
@@ -323,6 +334,7 @@ The return type must be `PyResult<T>` for some `T` that implements `IntoPyObject
323334
get injected by method wrapper. i.e
324335

325336
```rust
337+
# extern crate pyo3;
326338
# use pyo3::prelude::*;
327339
# #[pyclass]
328340
# struct MyClass {
@@ -346,6 +358,7 @@ To specify class method for custom class, method needs to be annotated
346358
with`#[classmethod]` attribute.
347359

348360
```rust
361+
# extern crate pyo3;
349362
# use pyo3::prelude::*;
350363
# use pyo3::types::PyType;
351364
# #[pyclass]
@@ -378,6 +391,7 @@ with `#[staticmethod]` attribute. The return type must be `PyResult<T>`
378391
for some `T` that implements `IntoPyObject`.
379392

380393
```rust
394+
# extern crate pyo3;
381395
# use pyo3::prelude::*;
382396
# #[pyclass]
383397
# struct MyClass {
@@ -400,6 +414,7 @@ To specify custom `__call__` method for custom class, call method needs to be an
400414
with `#[call]` attribute. Arguments of the method are specified same as for instance method.
401415

402416
```rust
417+
# extern crate pyo3;
403418
# use pyo3::prelude::*;
404419
use pyo3::types::PyTuple;
405420
# #[pyclass]
@@ -443,6 +458,7 @@ Each parameter could one of following type:
443458

444459
Example:
445460
```rust
461+
# extern crate pyo3;
446462
# use pyo3::prelude::*;
447463
use pyo3::types::{PyDict, PyTuple};
448464
#
@@ -545,6 +561,8 @@ These correspond to the slots `tp_traverse` and `tp_clear` in the Python C API.
545561
as every cycle must contain at least one mutable reference.
546562
Example:
547563
```rust
564+
extern crate pyo3;
565+
548566
use pyo3::prelude::*;
549567
use pyo3::PyTraverseError;
550568
use pyo3::gc::{PyGCProtocol, PyVisit};
@@ -585,14 +603,16 @@ collector, and it is possible to track them with `gc` module methods.
585603
Iterators can be defined using the
586604
[`PyIterProtocol`](https://docs.rs/pyo3/0.6.0-alpha.4/class/iter/trait.PyIterProtocol.html) trait.
587605
It includes two methods `__iter__` and `__next__`:
588-
* `fn __iter__(&mut self) -> PyResult<impl IntoPyObject>`
589-
* `fn __next__(&mut self) -> PyResult<Option<impl IntoPyObject>>`
606+
* `fn __iter__(slf: PyRefMut<Self>) -> PyResult<impl IntoPyObject>`
607+
* `fn __next__(slf: PyRefMut<Self>) -> PyResult<Option<impl IntoPyObject>>`
590608

591609
Returning `Ok(None)` from `__next__` indicates that that there are no further items.
592610

593611
Example:
594612

595613
```rust
614+
extern crate pyo3;
615+
596616
use pyo3::prelude::*;
597617
use pyo3::PyIterProtocol;
598618

guide/src/conversions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ provides two methods:
2424
Both methods accept `args` and `kwargs` arguments.
2525

2626
```rust
27+
# extern crate pyo3;
2728
use pyo3::prelude::*;
2829
use pyo3::types::{PyDict, PyTuple};
2930

@@ -61,6 +62,7 @@ fn main() {
6162
[`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.
6263

6364
```rust
65+
# extern crate pyo3;
6466
use pyo3::prelude::*;
6567
use pyo3::types::{IntoPyDict, PyDict};
6668
use std::collections::HashMap;

guide/src/exception.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
You can use the `create_exception!` macro to define a new exception type:
66

77
```rust
8+
# extern crate pyo3;
89
use pyo3::create_exception;
910

1011
create_exception!(module, MyError, pyo3::exceptions::Exception);
@@ -16,6 +17,7 @@ create_exception!(module, MyError, pyo3::exceptions::Exception);
1617
For example:
1718

1819
```rust
20+
# extern crate pyo3;
1921
use pyo3::prelude::*;
2022
use pyo3::create_exception;
2123
use pyo3::types::PyDict;
@@ -40,6 +42,7 @@ fn main() {
4042
To raise an exception, first you need to obtain an exception type and construct a new [`PyErr`](https://docs.rs/pyo3/0.2.7/struct.PyErr.html), then call [`PyErr::restore()`](https://docs.rs/pyo3/0.2.7/struct.PyErr.html#method.restore) method to write the exception back to the Python interpreter's global state.
4143

4244
```rust
45+
# extern crate pyo3;
4346
use pyo3::{Python, PyErr};
4447
use pyo3::exceptions;
4548

@@ -64,6 +67,7 @@ has corresponding rust type, exceptions defined by `create_exception!` and `impo
6467
have rust type as well.
6568

6669
```rust
70+
# extern crate pyo3;
6771
# use pyo3::exceptions;
6872
# use pyo3::prelude::*;
6973
# fn check_for_error() -> bool {false}
@@ -82,6 +86,7 @@ Python has an [`isinstance`](https://docs.python.org/3/library/functions.html#is
8286
in `PyO3` there is a [`Python::is_instance()`](https://docs.rs/pyo3/0.2.7/struct.Python.html#method.is_instance) method which does the same thing.
8387

8488
```rust
89+
# extern crate pyo3;
8590
use pyo3::Python;
8691
use pyo3::types::{PyBool, PyList};
8792

@@ -100,6 +105,7 @@ fn main() {
100105
To check the type of an exception, you can simply do:
101106

102107
```rust
108+
# extern crate pyo3;
103109
# use pyo3::exceptions;
104110
# use pyo3::prelude::*;
105111
# fn main() {
@@ -151,6 +157,7 @@ The code snippet above will raise `OSError` in Python if `TcpListener::bind()` r
151157
types so `try!` macro or `?` operator can be used.
152158

153159
```rust
160+
# extern crate pyo3;
154161
use pyo3::prelude::*;
155162

156163
fn parse_int(s: String) -> PyResult<usize> {
@@ -168,6 +175,7 @@ It is possible to use exception defined in python code as native rust types.
168175
for that exception.
169176

170177
```rust
178+
# extern crate pyo3;
171179
use pyo3::prelude::*;
172180
use pyo3::import_exception;
173181

guide/src/function.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ the function to a [module](./module.md)
66
One way is defining the function in the module definition.
77

88
```rust
9+
# extern crate pyo3;
910
use pyo3::prelude::*;
1011

1112
#[pymodule]
@@ -30,6 +31,7 @@ as first parameter, the function name as second and an instance of `Python`
3031
as third.
3132

3233
```rust
34+
# extern crate pyo3;
3335
use pyo3::prelude::*;
3436
use pyo3::wrap_pyfunction;
3537

@@ -60,6 +62,7 @@ built-ins are new in Python 3 — in Python 2, it is simply considered to be par
6062
of the doc-string.
6163

6264
```rust
65+
# extern crate pyo3;
6366
use pyo3::prelude::*;
6467

6568
/// add(a, b, /)
@@ -73,7 +76,7 @@ fn add(a: u64, b: u64) -> u64 {
7376
```
7477

7578
When annotated like this, signatures are also correctly displayed in IPython.
76-
```
79+
```ignore
7780
>>> pyo3_test.add?
7881
Signature: pyo3_test.add(a, b, /)
7982
Docstring: This function adds two unsigned 64-bit integers.

guide/src/get_started.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ features = ["extension-module"]
4545
**`src/lib.rs`**
4646

4747
```rust
48+
# extern crate pyo3;
4849
use pyo3::prelude::*;
4950
use pyo3::wrap_pyfunction;
5051

@@ -89,6 +90,7 @@ pyo3 = "0.5"
8990
Example program displaying the value of `sys.version`:
9091

9192
```rust
93+
# extern crate pyo3;
9294
use pyo3::prelude::*;
9395
use pyo3::types::PyDict;
9496

guide/src/module.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
As shown in the Getting Started chapter, you can create a module as follows:
44

55
```rust
6+
# extern crate pyo3;
67
use pyo3::prelude::*;
78

89
// add bindings to the generated python module
@@ -52,6 +53,7 @@ Which means that the above Python code will print `This module is implemented in
5253
In python, modules are first class objects. This means can store them as values or add them to dicts or other modules:
5354

5455
```rust
56+
# extern crate pyo3;
5557
use pyo3::prelude::*;
5658
use pyo3::{wrap_pyfunction, wrap_pymodule};
5759
use pyo3::types::PyDict;

guide/src/rust-cpython.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ py_class!(class MyClass |py| {
2525
**pyo3**
2626

2727
```rust
28+
# extern crate pyo3;
2829
use pyo3::prelude::*;
2930
use pyo3::PyRawObject;
3031

pyo3-derive-backend/src/pymethod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ fn impl_wrap_init(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec<'_>) -> Toke
182182
unsafe extern "C" fn __wrap(
183183
_slf: *mut ::pyo3::ffi::PyObject,
184184
_args: *mut ::pyo3::ffi::PyObject,
185-
_kwargs: *mut ::pyo3::ffi::PyObject) -> libc::c_int
185+
_kwargs: *mut ::pyo3::ffi::PyObject) -> ::std::os::raw::c_int
186186
{
187187
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
188188
let _pool = ::pyo3::GILPool::new();
@@ -305,7 +305,7 @@ pub(crate) fn impl_wrap_setter(
305305
#[allow(unused_mut)]
306306
unsafe extern "C" fn __wrap(
307307
_slf: *mut ::pyo3::ffi::PyObject,
308-
_value: *mut ::pyo3::ffi::PyObject, _: *mut ::std::os::raw::c_void) -> libc::c_int
308+
_value: *mut ::pyo3::ffi::PyObject, _: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int
309309
{
310310
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
311311
let _pool = ::pyo3::GILPool::new();

tests/test_doc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@ fn assert_file<P: AsRef<Path>>(path: P) {
1414
doc.test_file(path.as_ref())
1515
}
1616

17-
#[ignore]
1817
#[test]
18+
#[cfg(feature = "test-doc")]
1919
fn test_guide() {
2020
let guide_path = PathBuf::from("guide").join("src");
2121
for entry in guide_path.read_dir().unwrap() {
2222
assert_file(entry.unwrap().path())
2323
}
2424
}
2525

26-
#[ignore]
2726
#[test]
27+
#[cfg(feature = "test-doc")]
2828
fn test_readme() {
2929
assert_file("README.md")
3030
}

0 commit comments

Comments
 (0)