Skip to content

Commit 424a689

Browse files
committed
Fix pushsource-ls unable to serialize BootMode as YAML
pushsource-ls with YAML format enabled would crash if encountering a BootMode field (as used on AMI push items). This is because pyyaml does not enable any representer for enums by default. Fix it by adding a custom representer which will simply serialize the underlying value (e.g. BootMode.hybrid becomes "hybrid"). Note this is only being fixed for pushsource-ls and not in pushsource library proper because there does not seem to be a single universally-correct method of serializing enums into YAML. The chosen representation here is merely something "good enough" for pushsource-ls use-cases.
1 parent 5bf1bbc commit 424a689

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

src/pushsource/_impl/list_cmd.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,40 @@
2525
from argparse import ArgumentParser, RawDescriptionHelpFormatter
2626
import subprocess
2727
import sys
28+
import enum
2829

2930
import attr
3031
import yaml
3132

33+
import pushsource
3234
from pushsource import Source
3335

3436
LOG = logging.getLogger("pushsource-ls")
3537

3638

39+
class ItemDumper(yaml.SafeDumper):
40+
# Custom dumper adding support for any types appearing on pushitems
41+
# which are not natively supported by pyyaml.
42+
43+
@classmethod
44+
def represent_enum(cls, dumper: yaml.Dumper, value: enum.Enum):
45+
# enums are unwrapped and represented using whatever's the underlying
46+
# type, e.g. a string enum of value "foo" will be serialized the
47+
# same as a plain string "foo".
48+
return dumper.represent_data(value.value)
49+
50+
@classmethod
51+
def add_enum_representers(cls):
52+
# Register our enum representer for any enum classes in the API.
53+
for attrname in dir(pushsource):
54+
attrval = getattr(pushsource, attrname)
55+
if isinstance(attrval, enum.EnumType):
56+
cls.add_representer(attrval, cls.represent_enum)
57+
58+
59+
ItemDumper.add_enum_representers()
60+
61+
3762
def format_python(item):
3863
return repr(item) + ","
3964

@@ -51,7 +76,7 @@ def format_python_black(item):
5176

5277
def format_yaml(item):
5378
data = {type(item).__name__: attr.asdict(item, recurse=True)}
54-
return yaml.dump([data], Dumper=yaml.SafeDumper)
79+
return yaml.dump([data], Dumper=ItemDumper)
5580

5681

5782
def default_format():

0 commit comments

Comments
 (0)