-
-
Notifications
You must be signed in to change notification settings - Fork 224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow to pass named arguments to macro calls #910
Conversation
d9aab11
to
aa0f1e6
Compare
Rebased. |
askama_derive/src/generator.rs
Outdated
{ | ||
// First we check that all named arguments actually exist in the called item. | ||
for arg in args.iter() { | ||
if let Expr::NamedArgument(arg_name, _) = arg { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do let .. else
for the outer branch here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really see how it would improve the code since there is no else
clause here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It reduces rightward drift for the further check, so I would still like to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now there is a good reason for it (the break
which was added only recently) so adding it!
c4334fb
to
3ac9aa0
Compare
Is there anything else to be done here? |
2333266
to
4ce1fd4
Compare
Updated! I applied your suggestions and also enforced that named arguments should always be the last arguments. As mentioned above, it allowed to remove a loop since we can check if we have named arguments by checking if the last argument is a named one. |
4ce1fd4
to
f197e33
Compare
Squashed commits so named arguments coming last are now part of the first commit. |
8dbb722
to
3ef34e5
Compare
The idea of using a With this, we avoid allocating other I updated the code comments as well. |
3ef34e5
to
92b4ac0
Compare
{% macro heading(arg1, arg2, arg3, arg4) %} | ||
{% endmacro %} | ||
|
||
{% call heading("something", "b", arg4="ah", arg2="title") %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, sorry, these aren't quite the semantics I was going for. The positional arguments should always retain their position, so it should not be allowed to specify arg2
by name here since the call also passes two positional arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That however seems a bit too much of a restriction imo. We can't mix named and unnamed arguments, so I would at least want to be able to specify some arguments by name (because it's not obvious what they are just from the value) whether or not it is one of the first arguments without having to specify all arguments as named ones. If that makes sense to you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No -- I feel quite strongly that arguments passed as positional should go into the expected positional argument slot, and should not be able to be displaced by later named arguments (IIRC there's precedence for this in how Python does it?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree but it's your project so I'll update as such.
941a6db
to
28f3c4d
Compare
Updated to follow what you asked, added a test to check the compilation error and updated documentation. |
askama_derive/src/generator.rs
Outdated
// * If there is one, we add it and move to the next argument. | ||
// * If there isn't one, then we pick the next argument (we can do it without checking | ||
// anything since named arguments are always last). | ||
let mut args_iterator = args |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The args_iterator
approach is unnecessarily complex. We can just have an allow_positional
that is initialized to true
which is changed to false
on the first occurrence of a named argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'll make less good error messages but as you prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How less good? Do you have an example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before I could say it's bad to use named argument "x" here
. Now I simply provide the argument name of the template macro. I could maybe provide the index too.
But I have to admit, before it was a bit strange too:
is taking the position of an unnamed argument
Not very clear.
28f3c4d
to
c354990
Compare
Updated! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, thanks for sticking with this, I think this is in a pretty good shape now!
Thanks for all the review rounds! I'll continue my docs.rs migration and come back here if anything else is missing. :) |
Sounds great! |
Fixes #885.
Based on https://github.com/djc/askama/pull/909 (so only the last 3 commits are relevant to this PR).
I made a very permissive implementation which allows to mix named and non-named arguments. The only thing we need to check outside of the parser is that the named arguments actually have an equivalent in the called macro. For the rest, everything is checked in the parser directly, which allows nicer error messages.