Skip to content

Commit b13ad62

Browse files
devin-ai-integration[bot]bot_apk
andcommitted
fix(cdk): Handle TypeError in _literal_eval for nested set literals
When ast.literal_eval() encounters a string like "{{'\''web'\''}, {'\''discover'\''}}" that resembles nested Python set literals, it raises TypeError: unhashable type: '\''set'\'' because sets cannot contain other sets. The existing except clause only caught (ValueError, SyntaxError) but not TypeError. This fix adds TypeError to the except clause so the string is returned as-is, matching the existing behavior for other unparseable literals. Resolves airbytehq/oncall#11543 Co-Authored-By: bot_apk <apk@cognition.ai>
1 parent 6136336 commit b13ad62

2 files changed

Lines changed: 11 additions & 1 deletion

File tree

  • airbyte_cdk/sources/declarative/interpolation
  • unit_tests/sources/declarative/interpolation

airbyte_cdk/sources/declarative/interpolation/jinja.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def eval(
125125
def _literal_eval(self, result: Optional[str], valid_types: Optional[Tuple[Type[Any]]]) -> Any:
126126
try:
127127
evaluated = ast.literal_eval(result) # type: ignore # literal_eval is able to handle None
128-
except (ValueError, SyntaxError):
128+
except (ValueError, SyntaxError, TypeError):
129129
return result
130130
if (not valid_types and not isinstance(evaluated, complex)) or (
131131
valid_types and isinstance(evaluated, valid_types)

unit_tests/sources/declarative/interpolation/test_jinja.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,16 @@ def test_interpolation_private_partition_attribute():
345345
assert actual_output == expected_output
346346

347347

348+
def test_literal_eval_handles_unhashable_set_typeerror():
349+
"""Test that _literal_eval gracefully handles TypeError from ast.literal_eval for nested sets."""
350+
# ast.literal_eval("{{'web'}, {'discover'}}") raises TypeError: unhashable type: 'set'
351+
# The interpolation should return the string as-is instead of propagating the error.
352+
config = {"query": "{{'web'}, {'discover'}}"}
353+
s = "{{ config['query'] }}"
354+
val = interpolation.eval(s, config)
355+
assert val == "{{'web'}, {'discover'}}"
356+
357+
348358
def test_given_complex_when_eval_then_return_string():
349359
s = "9173710294242221J"
350360
config = {}

0 commit comments

Comments
 (0)