Skip to content

Add required attribute to blocks#1233

Merged
amy-lei merged 1 commit intopallets:masterfrom
MLH-Fellowship:required-blocks
Jan 29, 2021
Merged

Add required attribute to blocks#1233
amy-lei merged 1 commit intopallets:masterfrom
MLH-Fellowship:required-blocks

Conversation

@amy-lei
Copy link
Copy Markdown
Contributor

@amy-lei amy-lei commented Jun 12, 2020

Resolves #1147

Summary:

  • Added required field to blocks
    • Block nodes now have 4 fields (scoped must come before required if used together)
    • Must be overridden at some point, although not necessarily by the direct child. TemplateRuntimeError raised otherwise.
    • Required block itself cannot contain anything other than comments or whitespace. TemplateSyntaxError raised otherwise.
    • With current implementation, rendering the template containing the required block will also raise a TemplateRuntimeError.

Test:

  • Added tests to test_inheritance.py
    • Tested up to three levels, made sure correct errors are raised, tested that scoped still works in conjunction with required
  • Patched test_idtracking.py to include the new field when instantiating Block nodes

Files affected:

  • parser.py
  • compile.py
  • nodes.py
  • test_inheritance.py
  • test_idtracking.py

Comment thread src/jinja2/parser.py Outdated
Comment thread src/jinja2/nodes.py
Comment thread CHANGES.rst Outdated
Comment thread src/jinja2/nodes.py
Comment thread src/jinja2/lexer.py Outdated
Comment thread src/jinja2/parser.py Outdated
Comment thread src/jinja2/nodes.py Outdated
@davidism
Copy link
Copy Markdown
Member

davidism commented Jun 22, 2020

look_and_skip_if will fail if there's more than two optional attributes, since it would be possible to arrange a combination where the first attribute we look for comes last in the list of tokens.

A possible solution is a "look and skip while" method instead, which will keep looking until there are no more of the given type of token. In this case, looking through all names for one that matches the name we're currently looking for, accumulating other names then pushing them all back.

Token has a test_any function, did we already consider using that?

@amy-lei
Copy link
Copy Markdown
Contributor Author

amy-lei commented Jun 22, 2020

look_and_skip_if will fail if there's more than two optional attributes, since it would be possible to arrange a combination where the first attribute we look for comes last in the list of tokens.

Is this for other nodes in general? Hmm, yeah look_and_skip_if was only designed with Block nodes in mind since they had just 2 attributes.

A possible solution is a "look and skip while" method instead, which will keep looking until there are no more of the given type of token. In this case, looking through all names for one that matches the name we're currently looking for, accumulating other names then pushing them all back.

This sounds like it'll be more useful. I can give it a try

Token has a test_any function, did we already consider using that?

Yeah, one of the earlier iterations tried this. I think the issue I ran into was preventing duplicates like {% block name scoped scoped %}, and having to do something like setattr(node, token.type, True) since test_any won't know which value resulted in the match.

Do you think it would be better to play around with test_any more before trying a look_and_skip_while?

@davidism
Copy link
Copy Markdown
Member

I'll take a look at this, I need to experiment to see what feels right.

@davidism
Copy link
Copy Markdown
Member

Was looking through the docs, and found another case of a tag having two optional keywords. include can have ignore missing and with context, and they must appear in that order if they're both used. https://jinja.palletsprojects.com/en/2.11.x/templates/#include Looks like whoever implemented that didn't want to deal with arbitrary order either, especially for phrases instead of words. 🙂

I think for now the easiest thing to do is just document that required comes last. We can always relax that requirement later if it starts coming up a lot, but I don't want figuring that out to block merging this.

@amy-lei
Copy link
Copy Markdown
Contributor Author

amy-lei commented Jun 23, 2020

Was looking through the docs, and found another case of a tag having two optional keywords. include can have ignore missing and with context, and they must appear in that order if they're both used. https://jinja.palletsprojects.com/en/2.11.x/templates/#include Looks like whoever implemented that didn't want to deal with arbitrary order either, especially for phrases instead of words. 🙂

I think for now the easiest thing to do is just document that required comes last. We can always relax that requirement later if it starts coming up a lot, but I don't want figuring that out to block merging this.

Awesome! Didn't notice include was a similar case. This really does simplify the problem 😄 . I'll update the docs and switch them to skip_if's.

required blocks must be overridden at some point, although not
necessarily by the direct child template
@amy-lei amy-lei added this to the 3.0.0 milestone Jan 29, 2021
@amy-lei amy-lei merged commit 35e8f0a into pallets:master Jan 29, 2021
@amy-lei amy-lei deleted the required-blocks branch January 29, 2021 15:36
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Feb 13, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

{% block <name> required %}

2 participants