Skip to content

Commit 58b7334

Browse files
allow expression as an object key (limitation: expression must be wrapped in parentheses) (#222)
1 parent 14b840e commit 58b7334

File tree

6 files changed

+29
-13
lines changed

6 files changed

+29
-13
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77

88
## \[Unreleased\]
99

10-
- Nothing yet
10+
### Fixed
11+
12+
- Issue parsing inline expression as an object key; **see Limitations in README.md** ([#222](https://github.com/amplify-education/python-hcl2/pull/222))
1113

1214
## \[7.1.0\] - 2025-04-10
1315

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,16 @@ We’ll try to answer any PR’s promptly.
104104
name = "prefix1-${"prefix2-${local.foo_bar}"}" //interpolates into "prefix1-prefix2-foo-bar"
105105
}
106106
```
107+
108+
### Using inline expression as an object key
109+
110+
- Object key can be an expression as long as it is wrapped in parentheses:
111+
```terraform
112+
locals {
113+
foo = "bar"
114+
baz = {
115+
(format("key_prefix_%s", local.foo)) : "value"
116+
# format("key_prefix_%s", local.foo) : "value" this will fail
117+
}
118+
}
119+
```

hcl2/hcl2.lark

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ EQ : /[ \t]*=(?!=|>)/
7575

7676
tuple : "[" (new_line_or_comment* expression new_line_or_comment* ",")* (new_line_or_comment* expression)? new_line_or_comment* "]"
7777
object : "{" new_line_or_comment? (new_line_or_comment* (object_elem | (object_elem COMMA)) new_line_or_comment*)* "}"
78-
object_elem : LPAR? object_elem_key RPAR? ( EQ | COLON ) expression
79-
object_elem_key : float_lit | int_lit | identifier | STRING_LIT | object_elem_key_dot_accessor
78+
object_elem : object_elem_key ( EQ | COLON ) expression
79+
object_elem_key : float_lit | int_lit | identifier | STRING_LIT | object_elem_key_dot_accessor | object_elem_key_expression
80+
object_elem_key_expression : LPAR expression RPAR
8081
object_elem_key_dot_accessor : identifier (DOT identifier)+
8182

8283
heredoc_template : /<<(?P<heredoc>[a-zA-Z][a-zA-Z0-9._-]+)\n?(?:.|\n)*?\n\s*(?P=heredoc)\n/
@@ -98,7 +99,7 @@ full_splat : "[*]" (get_attr | index)*
9899

99100
FOR_OBJECT_ARROW : "=>"
100101
!for_tuple_expr : "[" new_line_or_comment? for_intro new_line_or_comment? expression new_line_or_comment? for_cond? new_line_or_comment? "]"
101-
!for_object_expr : "{" new_line_or_comment? for_intro new_line_or_comment? expression FOR_OBJECT_ARROW new_line_or_comment? expression "..."? new_line_or_comment? for_cond? new_line_or_comment? "}"
102+
!for_object_expr : "{" new_line_or_comment? for_intro new_line_or_comment? expression FOR_OBJECT_ARROW new_line_or_comment? expression new_line_or_comment? "..."? new_line_or_comment? for_cond? new_line_or_comment? "}"
102103
!for_intro : "for" new_line_or_comment? identifier ("," identifier new_line_or_comment?)? new_line_or_comment? "in" new_line_or_comment? expression new_line_or_comment? ":" new_line_or_comment?
103104
!for_cond : "if" new_line_or_comment? expression
104105

hcl2/transformer.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,21 +98,19 @@ def tuple(self, args: List) -> List:
9898
def object_elem(self, args: List) -> Dict:
9999
# This returns a dict with a single key/value pair to make it easier to merge these
100100
# into a bigger dict that is returned by the "object" function
101-
if args[0] == Token("LPAR", "("):
102-
key = self.strip_quotes(str(args[1].children[0]))
103-
key = f"({key})"
104-
key = self.to_string_dollar(key)
105-
value = args[4]
106-
else:
107-
key = self.strip_quotes(str(args[0].children[0]))
108-
value = args[2]
101+
102+
key = self.strip_quotes(str(args[0].children[0]))
103+
value = args[2]
109104

110105
value = self.to_string_dollar(value)
111106
return {key: value}
112107

113108
def object_elem_key_dot_accessor(self, args: List) -> str:
114109
return "".join(args)
115110

111+
def object_elem_key_expression(self, args: List) -> str:
112+
return self.to_string_dollar("".join(args))
113+
116114
def object(self, args: List) -> Dict:
117115
args = self.strip_new_line_tokens(args)
118116
result: Dict[str, Any] = {}

test/helpers/terraform-config-json/variables.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@
4747
"foo": "${var.account}_bar",
4848
"bar": {
4949
"baz": 1,
50-
"${(var.account)}": 2
50+
"${(var.account)}": 2,
51+
"${(format(\"key_prefix_%s\", local.foo))}": 3
5152
},
5253
"tuple": ["${local.foo}"],
5354
"empty_tuple": []

test/helpers/terraform-config/variables.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ locals {
99
bar = {
1010
baz : 1
1111
(var.account) : 2
12+
(format("key_prefix_%s", local.foo)) : 3
1213
}
1314
tuple = [local.foo]
1415
empty_tuple = []

0 commit comments

Comments
 (0)