Add pyarg(flatten)

This commit is contained in:
Noah
2020-07-10 11:27:25 -05:00
parent e60a63d4fb
commit 6b6c4da511
3 changed files with 29 additions and 1 deletions

View File

@@ -2076,6 +2076,7 @@ class TestCopyFile(unittest.TestCase):
self.assertRaises(OSError, shutil.copyfile, 'srcfile', 'destfile')
@unittest.skip("TODO: RUSTPYTHON, panics with 'no blocks left to pop'")
@unittest.skipIf(MACOS, "skipped on macOS")
def test_w_dest_open_fails(self):
@@ -2096,6 +2097,7 @@ class TestCopyFile(unittest.TestCase):
self.assertEqual(srcfile._exited_with[1].args,
('Cannot open "destfile"',))
@unittest.skip("TODO: RUSTPYTHON, panics with 'no blocks left to pop'")
@unittest.skipIf(MACOS, "skipped on macOS")
def test_w_dest_close_fails(self):

View File

@@ -12,6 +12,7 @@ enum ParameterKind {
PositionalOnly,
PositionalOrKeyword,
KeywordOnly,
Flatten,
}
impl ParameterKind {
@@ -20,6 +21,7 @@ impl ParameterKind {
"positional_only" => Some(ParameterKind::PositionalOnly),
"positional_or_keyword" => Some(ParameterKind::PositionalOrKeyword),
"keyword_only" => Some(ParameterKind::KeywordOnly),
"flatten" => Some(ParameterKind::Flatten),
_ => None,
}
}
@@ -52,7 +54,7 @@ impl ArgAttribute {
err_span!(
first_arg,
"The first argument to #[pyarg()] must be the parameter type, either \
'positional_only', 'positional_or_keyword', or 'keyword_only'."
'positional_only', 'positional_or_keyword', 'keyword_only', or 'flatten'."
)
})?;
@@ -78,6 +80,9 @@ impl ArgAttribute {
}
fn parse_argument(&mut self, arg: &NestedMeta) -> Result<(), Diagnostic> {
if let ParameterKind::Flatten = self.kind {
bail_span!(arg, "can't put additional arguments on a flatten arg")
}
match arg {
NestedMeta::Meta(Meta::Path(path)) => {
if path_eq(&path, "default") {
@@ -154,6 +159,11 @@ fn generate_field(field: &Field) -> Result<TokenStream2, Diagnostic> {
});
}
}
if let ParameterKind::Flatten = attr.kind {
return Ok(quote! {
#name: ::rustpython_vm::function::FromArgs::from_args(vm, args)?,
});
}
let middle = quote! {
.map(|x| ::rustpython_vm::pyobject::TryFromObject::try_from_object(vm, x)).transpose()?
};
@@ -174,6 +184,7 @@ fn generate_field(field: &Field) -> Result<TokenStream2, Diagnostic> {
ParameterKind::KeywordOnly => quote! {
::rustpython_vm::function::ArgumentError::RequiredKeywordArgument(tringify!(#name))
},
ParameterKind::Flatten => unreachable!(),
};
quote! {
.ok_or_else(|| #err)?
@@ -196,6 +207,7 @@ fn generate_field(field: &Field) -> Result<TokenStream2, Diagnostic> {
#name: args.take_keyword(stringify!(#name))#middle#ending,
}
}
ParameterKind::Flatten => unreachable!(),
};
Ok(file_output)
}

View File

@@ -1476,6 +1476,20 @@ fn os_link(src: PyPathLike, dst: PyPathLike, vm: &VirtualMachine) -> PyResult<()
fs::hard_link(src.path, dst.path).map_err(|err| convert_io_error(vm, err))
}
#[derive(FromArgs)]
struct UtimeArgs {
#[pyarg(positional_or_keyword)]
path: PyPathLike,
#[pyarg(positional_or_keyword, default = "None")]
times: Option<PyTupleRef>,
#[pyarg(keyword_only, default = "None")]
ns: Option<PyTupleRef>,
#[pyarg(flatten)]
dir_fd: DirFd,
#[pyarg(flatten)]
follow_symlinks: FollowSymlinks,
}
fn os_utime(
_path: PyPathLike,
_time: OptionalArg<PyTupleRef>,