Implement optional parameters for reference types
This commit is contained in:
parent
9707c5ab72
commit
d615c319f6
|
@ -258,8 +258,17 @@ macro_rules! py_argparse_parse_plist_impl {
|
|||
($($tail)*)
|
||||
}
|
||||
};
|
||||
// Optional parameter with reference extraction
|
||||
{ $callback:ident $initial_args:tt [ $($output:tt)* ]
|
||||
( $name:ident : &$t:ty = $default:expr, $($tail:tt)* )
|
||||
} => {
|
||||
py_argparse_parse_plist_impl! {
|
||||
$callback $initial_args
|
||||
[ $($output)* { $name:&$t = [ {} {$default} {$t} ] } ]
|
||||
($($tail)*)
|
||||
}
|
||||
};
|
||||
// Optional parameter
|
||||
// TODO: with reference extraction?
|
||||
{ $callback:ident $initial_args:tt [ $($output:tt)* ]
|
||||
( $name:ident : $t:ty = $default:expr , $($tail:tt)* )
|
||||
} => {
|
||||
|
@ -353,8 +362,8 @@ macro_rules! py_argparse_param_description {
|
|||
is_optional: false
|
||||
}
|
||||
);
|
||||
// optional parameter with a default value
|
||||
{ $pname:ident : $ptype:ty = [ {} {$default:expr} {} ] } => (
|
||||
// optional parameters
|
||||
{ $pname:ident : $ptype:ty = [ {} {$default:expr} {$($rtype:tt)*} ] } => (
|
||||
$crate::argparse::ParamDescription {
|
||||
name: stringify!($pname),
|
||||
is_optional: true
|
||||
|
@ -401,6 +410,19 @@ macro_rules! py_argparse_extract {
|
|||
Err(e) => Err(e)
|
||||
}
|
||||
};
|
||||
// optional parameter with reference extraction
|
||||
( $py:expr, $iter:expr, $body:block,
|
||||
[ { $pname:ident : $ptype:ty = [ {} {$default:expr} {$rtype:ty} ] } $($tail:tt)* ]
|
||||
) => {
|
||||
//unwrap() asserts the iterated sequence is long enough (which should be guaranteed);
|
||||
match <$rtype as $crate::RefFromPyObject>::with_extracted($py,
|
||||
$iter.next().unwrap().as_ref().unwrap_or($default.into_py_object($py).as_object()),
|
||||
|$pname: $ptype| py_argparse_extract!($py, $iter, $body, [$($tail)*])
|
||||
) {
|
||||
Ok(v) => v,
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -443,9 +465,10 @@ mod test {
|
|||
let gil_guard = Python::acquire_gil();
|
||||
let py = gil_guard.python();
|
||||
let mut called = false;
|
||||
let tuple = (0,).to_py_object(py);
|
||||
py_argparse!(py, None, &tuple, None, (x: usize = 42) {
|
||||
let tuple = (0, "foo").to_py_object(py);
|
||||
py_argparse!(py, None, &tuple, None, (x: usize = 42, y: &str = "abc") {
|
||||
assert_eq!(x, 0);
|
||||
assert_eq!(y, "foo");
|
||||
called = true;
|
||||
Ok(())
|
||||
}).unwrap();
|
||||
|
@ -453,8 +476,9 @@ mod test {
|
|||
|
||||
let mut called = false;
|
||||
let tuple = PyTuple::new(py, &[]);
|
||||
py_argparse!(py, None, &tuple, None, (x: usize = 42) {
|
||||
py_argparse!(py, None, &tuple, None, (x: usize = 42, y: &str = "abc") {
|
||||
assert_eq!(x, 42);
|
||||
assert_eq!(y, "abc");
|
||||
called = true;
|
||||
Ok(())
|
||||
}).unwrap();
|
||||
|
|
11
src/lib.rs
11
src/lib.rs
|
@ -59,20 +59,20 @@
|
|||
//! extern crate cpython;
|
||||
//!
|
||||
//! use cpython::{Python, PyDict, PyResult};
|
||||
//!
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let gil = Python::acquire_gil();
|
||||
//! hello(gil.python()).unwrap();
|
||||
//! }
|
||||
//!
|
||||
//!
|
||||
//! fn hello(py: Python) -> PyResult<()> {
|
||||
//! let sys = py.import("sys")?;
|
||||
//! let version: String = sys.get(py, "version")?.extract(py)?;
|
||||
//!
|
||||
//!
|
||||
//! let locals = PyDict::new(py);
|
||||
//! locals.set_item(py, "os", py.import("os")?)?;
|
||||
//! let user: String = py.eval("os.getenv('USER') or os.getenv('USERNAME')", None, Some(&locals))?.extract(py)?;
|
||||
//!
|
||||
//!
|
||||
//! println!("Hello {}, I'm Python {}", user, version);
|
||||
//! Ok(())
|
||||
//! }
|
||||
|
@ -238,7 +238,7 @@ pub mod _detail {
|
|||
/// ```
|
||||
/// The full example project can be found at:
|
||||
/// https://github.com/dgrunwald/rust-cpython/tree/master/extensions/hello
|
||||
///
|
||||
///
|
||||
/// Rust will compile the code into a file named `libhello.so`, but we have to
|
||||
/// rename the file in order to use it with Python:
|
||||
///
|
||||
|
@ -357,4 +357,3 @@ pub unsafe fn py_module_initializer_impl(
|
|||
mem::forget(guard);
|
||||
ret
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue