Skip to content

Regression in 8.x: empty heredoc fails to parse (regression of #101) #309

Description

@livingstaccato

Describe the bug

An empty heredoc fails to parse. This is a regression of #101 ("Unexpected token exception on empty heredoc"), fixed in 2023 and working in 7.2.1 (which returns '').

Software:

  • OS: macOS 15 (arm64)

  • Python version: 3.11.16

  • python-hcl2 versions tested, each in a clean isolated environment:

    • 7.2.1 — returns {'bar': ''}
    • 7.3.1 — returns {'bar': ''}
    • 8.0.0rc1 — raises
    • 8.1.0 — raises
    • 8.1.2 — raises

    So this arrived with the v8 rewrite rather than in a later 8.1.x change.

Snippet of HCL2 code causing the unexpected behaviour:

bar = <<EOF
EOF

Expected behavior (7.2.1)

{'bar': ''}

Exception traceback:

lark.exceptions.UnexpectedCharacters: No terminal matches '<' in the current parser context, at line 1 col 7

bar = <<EOF
      ^
Expected one of:
	* FLOAT_LITERAL
	* HEREDOC_TEMPLATE
	* MINUS
	...

followed by

lark.exceptions.UnexpectedToken: Unexpected token Token('STRING_CHARS', '<<EOF\nEOF\n\n') at line 1, column 7.

Root cause

In hcl2/hcl2.lark, the v8 HEREDOC_TEMPLATE terminal requires at least one body line: the \n? that used to follow the opening marker in 7.x is gone, so a marker immediately followed by the closing delimiter does not match and the input falls through to STRING_CHARS.

A heredoc whose body is a single empty line does parse, which makes the failing case look arbitrary:

>>> hcl2.loads("bar = <<EOF\n\nEOF\n")   # one blank line - OK
{'bar': '"<<EOF\n\nEOF"'}
>>> hcl2.loads("bar = <<EOF\nEOF\n")      # no body - raises

Impact

Generated configurations legitimately contain empty heredocs (an empty user-data script, an empty policy document), and a whole file fails to parse because of one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions