[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 toTrue
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 viaTrue
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 viayaml.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