linuxansiblepermissionsjinja2umask

jinja2.exceptions.TemplateSyntaxError: expected token ',', got 'integer' (support for hex, octal, and binary integer literals)


In version 3.1.2 this is throwing an exception:

>>> print(jinja2.Template("{{ '%04d' | format(0777 - '0022' | int) }}").render())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/root/.virtualenvs/ansible-playbooks/lib/python3.8/site-packages/jinja2/environment.py", line 1208, in __new__
    return env.from_string(source, template_class=cls)
  File "/root/.virtualenvs/ansible-playbooks/lib/python3.8/site-packages/jinja2/environment.py", line 1105, in from_string
    return cls.from_code(self, self.compile(source), gs, None)
  File "/root/.virtualenvs/ansible-playbooks/lib/python3.8/site-packages/jinja2/environment.py", line 768, in compile
    self.handle_exception(source=source_hint)
  File "/root/.virtualenvs/ansible-playbooks/lib/python3.8/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "<unknown>", line 1, in template
jinja2.exceptions.TemplateSyntaxError: expected token ',', got 'integer'

While this used to work just fine in version 2.11.3:

>>> print(jinja2.Template("{{ '%04d' | format(0777 - '0022' | int) }}").render())
0755

I think the behavior is changed in this PR. What do I need to do to fix it?

The snippet above it coming from this Ansible role configuration:

deploy_cakephp_default_umask: '0022'
deploy_cakephp_default_owner: root
deploy_cakephp_default_group: root
deploy_cakephp_default_directory_mode: "{{ '%04d' | format(0777 - deploy_cakephp_default_umask | int) }}"
deploy_cakephp_default_file_mode: "{{ '%04d' | format(0666 - deploy_cakephp_default_umask | int) }}"

Solution

  • I think your problem comes from Jinja and the version of python your are (were) using. C-style octal literals have been dropped in python 3.0 (see https://docs.python.org/3/reference/lexical_analysis.html#integer-literals)

    Meanwhile, I was able to achieve your requirement using this Jinja2 expression taking advantage of the octal integer literal notation and the format() function:

    {{ '0{0:o}'.format(0o777 - 0o22) }}
    

    See the following test session:

    $ pip list | grep Jinja2
    Jinja2                 3.1.2
    
    $ python --version
    Python 3.10.6
    # same result with 3.8.16
    
    $ python
    Python 3.10.6 (main, May 29 2023, 11:10:38) [GCC 11.3.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import jinja2
    >>> print(jinja2.Template("{{ '0{0:o}'.format(0o777 - 0o22) }}").render())
    0755