[Python](EN) Case of converting key name "on" to True when using PyYAML

Case of converting key name “on” to True when using PyYAML


Environment and Prerequisite

  • Github Actions
  • Python
  • PyYAML


Background

  • on key was automatically changed to True when modifying Github Actions Workflow file dynmically using Python.


Example

When reading and outputting a file using yaml in Python as shown below, you’ll notice that on is replaced with True.

Code

import io
import yaml

file_content = """
name: Workflow Complete Event Test

on:
  workflow_run:
    workflows: [ "Push Main Branch" ]
    types:
      - completed
"""

file_like_object = io.StringIO(file_content)
yaml_content = yaml.safe_load(file_like_object)

print(yaml_content)

Result

{'name': 'Workflow Complete Event Test', True: {'workflow_run': {'workflows': ['Push Main Branch'], 'types': ['completed']}}}


Reason

According to searching, PyYAML supports YAML 1.1 and in version 1.1, "on" is considered as a boolean value which is why it gets converted to True. Since YAML 1.2 is not yet supported, this behavior is intentional, and you will need to find an alternative solution.


Solution

There are many ways to solve it.

  • Modify Loader code
  • Use quote("" or '') to key
  • Use another Python module

Although I was tempted to remove the quotation marks, the second method seemed the simplest and didn’t require changes to the existing YAML module, so I applied that approach.

Code

import io
import yaml

file_content = """
name: Workflow Complete Event Test

'on':
  workflow_run:
    workflows: [ "Push Main Branch" ]
    types:
      - completed
"""

file_like_object = io.StringIO(file_content)
yaml_content = yaml.safe_load(file_like_object)

print(yaml_content)

Result

{'name': 'Workflow Complete Event Test', 'on': {'workflow_run': {'workflows': ['Push Main Branch'], 'types': ['completed']}}}


Others

Use True as key name

  • Key is set to True and it can be accessed via True in Python.

Code

import io
import yaml

file_content = """
name: Workflow Complete Event Test

on:
  workflow_run:
    workflows: [ "Push Main Branch" ]
    types:
      - completed
key:
  on: "test"
"""

file_like_object = io.StringIO(file_content)
yaml_content = yaml.safe_load(file_like_object)

print(yaml_content[True])

Result

{'workflow_run': {'workflows': ['Push Main Branch'], 'types': ['completed']}}


Key name after YAML file created

  • Key is set to true if make file via yaml.dump.

Code

import io
import yaml

file_content = """
name: Workflow Complete Event Test

on:
  workflow_run:
    workflows: [ "Push Main Branch" ]
    types:
      - completed
key:
  on: "test"
"""

file_like_object = io.StringIO(file_content)
yaml_content = yaml.safe_load(file_like_object)

with open('example.yaml', 'w') as file:
    yaml.dump(yaml_content, file)

Result

$ cat example.yaml
name: Workflow Complete Event Test
true:
  workflow_run:
    types:
    - completed
    workflows:
    - Push Main Branch
key:
  true: test


Reference