Fix the interpretation of '*'
This commit is contained in:
parent
96115eaaaa
commit
25069baef4
|
@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
* Usage of raw identifiers with `#[pyo3(set)]`. [#745](https://github.com/PyO3/pyo3/pull/745)
|
||||
* Usage of `PyObject` with `#[pyo3(get)]`. [#760](https://github.com/PyO3/pyo3/pull/760)
|
||||
* `#[pymethods]` used in conjunction with `#[cfg]`. #[769](https://github.com/PyO3/pyo3/pull/769)
|
||||
* Interpretation of `*`. #[792](https://github.com/PyO3/pyo3/pull/792)
|
||||
|
||||
### Removed
|
||||
|
||||
|
|
|
@ -206,17 +206,6 @@ impl<'a> FnSpec<'a> {
|
|||
false
|
||||
}
|
||||
|
||||
pub fn accept_args(&self) -> bool {
|
||||
for s in self.attrs.iter() {
|
||||
match *s {
|
||||
Argument::VarArgs(_) => return true,
|
||||
Argument::VarArgsSeparator => return true,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn is_kwargs(&self, name: &syn::Ident) -> bool {
|
||||
for s in self.attrs.iter() {
|
||||
if let Argument::KeywordArgs(ref path) = s {
|
||||
|
@ -226,15 +215,6 @@ impl<'a> FnSpec<'a> {
|
|||
false
|
||||
}
|
||||
|
||||
pub fn accept_kwargs(&self) -> bool {
|
||||
for s in self.attrs.iter() {
|
||||
if let Argument::KeywordArgs(_) = s {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn default_value(&self, name: &syn::Ident) -> Option<TokenStream> {
|
||||
for s in self.attrs.iter() {
|
||||
match *s {
|
||||
|
|
|
@ -406,15 +406,6 @@ fn impl_call(_cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream {
|
|||
quote! { _slf.#fname(#(#names),*) }
|
||||
}
|
||||
|
||||
/// Converts a bool to "true" or "false"
|
||||
fn bool_to_ident(condition: bool) -> syn::Ident {
|
||||
if condition {
|
||||
syn::Ident::new("true", Span::call_site())
|
||||
} else {
|
||||
syn::Ident::new("false", Span::call_site())
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_arg_params_(spec: &FnSpec<'_>, body: TokenStream, into_result: TokenStream) -> TokenStream {
|
||||
if spec.args.is_empty() {
|
||||
return quote! {
|
||||
|
@ -431,8 +422,8 @@ fn impl_arg_params_(spec: &FnSpec<'_>, body: TokenStream, into_result: TokenStre
|
|||
continue;
|
||||
}
|
||||
let name = arg.name;
|
||||
let kwonly = bool_to_ident(spec.is_kw_only(&arg.name));
|
||||
let opt = bool_to_ident(arg.optional.is_some() || spec.default_value(&arg.name).is_some());
|
||||
let kwonly = spec.is_kw_only(&arg.name);
|
||||
let opt = arg.optional.is_some() || spec.default_value(&arg.name).is_some();
|
||||
|
||||
params.push(quote! {
|
||||
pyo3::derive_utils::ParamDescription {
|
||||
|
@ -449,8 +440,16 @@ fn impl_arg_params_(spec: &FnSpec<'_>, body: TokenStream, into_result: TokenStre
|
|||
param_conversion.push(impl_arg_param(&arg, &spec, idx, &mut option_pos));
|
||||
}
|
||||
|
||||
let accept_args = bool_to_ident(spec.accept_args());
|
||||
let accept_kwargs = bool_to_ident(spec.accept_kwargs());
|
||||
let (mut accept_args, mut accept_kwargs) = (false, false);
|
||||
|
||||
for s in spec.attrs.iter() {
|
||||
use crate::pyfunction::Argument;
|
||||
match s {
|
||||
Argument::VarArgs(_) => accept_args = true,
|
||||
Argument::KeywordArgs(_) => accept_kwargs = true,
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
let num_normal_params = params.len();
|
||||
// create array of arguments, and then parse
|
||||
quote! {
|
||||
|
|
|
@ -61,7 +61,7 @@ pub fn parse_fn_args<'p>(
|
|||
if i < nargs {
|
||||
raise_error!("got multiple values for argument: {}", p.name)
|
||||
}
|
||||
kwargs.as_ref().unwrap().del_item(p.name).unwrap();
|
||||
kwargs.as_ref().unwrap().del_item(p.name)?;
|
||||
Some(kwarg)
|
||||
}
|
||||
None => {
|
||||
|
|
|
@ -231,11 +231,15 @@ impl MethArgs {
|
|||
[a.to_object(py), args.into(), kwargs.to_object(py)].to_object(py)
|
||||
}
|
||||
|
||||
#[args("*", c = 10)]
|
||||
fn get_pos_arg_kw_sep(&self, a: i32, b: i32, c: i32) -> PyResult<i32> {
|
||||
Ok(a + b + c)
|
||||
}
|
||||
|
||||
#[args(kwargs = "**")]
|
||||
fn get_pos_kw(&self, py: Python, a: i32, kwargs: Option<&PyDict>) -> PyObject {
|
||||
[a.to_object(py), kwargs.to_object(py)].to_object(py)
|
||||
}
|
||||
|
||||
// "args" can be anything that can be extracted from PyTuple
|
||||
#[args(args = "*")]
|
||||
fn args_as_vec(&self, args: Vec<i32>) -> i32 {
|
||||
|
@ -264,7 +268,7 @@ fn meth_args() {
|
|||
py_run!(py, inst, "assert inst.get_default() == 10");
|
||||
py_run!(py, inst, "assert inst.get_default(100) == 100");
|
||||
py_run!(py, inst, "assert inst.get_kwarg() == 10");
|
||||
py_run!(py, inst, "assert inst.get_kwarg(100) == 10");
|
||||
py_expect_exception!(py, inst, "inst.get_kwarg(100)", TypeError);
|
||||
py_run!(py, inst, "assert inst.get_kwarg(test=100) == 100");
|
||||
py_run!(py, inst, "assert inst.get_kwargs() == [(), None]");
|
||||
py_run!(py, inst, "assert inst.get_kwargs(1,2,3) == [(1,2,3), None]");
|
||||
|
@ -295,6 +299,16 @@ fn meth_args() {
|
|||
py_expect_exception!(py, inst, "inst.get_pos_arg_kw(1, a=1)", TypeError);
|
||||
py_expect_exception!(py, inst, "inst.get_pos_arg_kw(b=2)", TypeError);
|
||||
|
||||
py_run!(py, inst, "assert inst.get_pos_arg_kw_sep(1, 2, c=3) == 6");
|
||||
py_run!(py, inst, "assert inst.get_pos_arg_kw_sep(1, 2) == 13");
|
||||
py_expect_exception!(py, inst, "assert inst.get_pos_arg_kw_sep(1)", TypeError);
|
||||
py_expect_exception!(
|
||||
py,
|
||||
inst,
|
||||
"assert inst.get_pos_arg_kw_sep(1, 2, 3)",
|
||||
TypeError
|
||||
);
|
||||
|
||||
py_run!(py, inst, "assert inst.get_pos_kw(1, b=2) == [1, {'b': 2}]");
|
||||
py_expect_exception!(py, inst, "inst.get_pos_kw(1,2)", TypeError);
|
||||
|
||||
|
|
Loading…
Reference in New Issue