From f69da058e23ec908ef9122990079d250f581c9f5 Mon Sep 17 00:00:00 2001 From: Fabian Fuelling Date: Wed, 22 Oct 2025 11:50:07 +0200 Subject: [PATCH 1/3] Replace PyYaml with ruyaml --- api_deploy/schema.py | 33 ++++++++++++++++++++++++++++----- setup.py | 2 +- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/api_deploy/schema.py b/api_deploy/schema.py index 1f73623..c54830b 100644 --- a/api_deploy/schema.py +++ b/api_deploy/schema.py @@ -1,12 +1,35 @@ from typing import Dict -import yaml +import io +import ruyaml -yaml.Dumper.ignore_aliases = lambda *args: True +_yaml = ruyaml.YAML(typ='safe') +# avoid YAML aliases/anchors in output +_yaml.representer.ignore_aliases = lambda *args: True + + +def _dump_to_string(data, sort_keys=False): + # Optional key sorting to mimic previous behavior when requested + def _sort(obj): + if isinstance(obj, dict): + # sort by key, recursively + return {k: _sort(obj[k]) for k in sorted(obj.keys())} + if isinstance(obj, list): + return [ + _sort(i) for i in obj + ] + return obj + + if sort_keys: + data = _sort(data) + stream = io.StringIO() + _yaml.dump(data, stream) + return stream.getvalue() class YamlDict(Dict): def __init__(self, schema) -> None: - content = yaml.load(schema, yaml.Loader) or {} + # ruyaml.YAML.load accepts str, bytes, and file-like objects + content = _yaml.load(schema) or {} super().__init__(content) @classmethod @@ -19,7 +42,7 @@ def to_file(self, file_path): target.write(self.dump()) def dump(self, sort_keys=False): - return yaml.dump(self, sort_keys=sort_keys) + return _dump_to_string(self, sort_keys=sort_keys) class Schema(YamlDict): @@ -34,4 +57,4 @@ def dump(self, sort_keys=False): 'x-amazon-apigateway-request-validators': self.get('x-amazon-apigateway-request-validators', {}), 'x-amazon-apigateway-minimum-compression-size': 0 , } - return yaml.dump(data, sort_keys=sort_keys) + return _dump_to_string(data, sort_keys=sort_keys) diff --git a/setup.py b/setup.py index bfd3c25..310eb7c 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ def readme(): 'click>=8.1.3, <9', 'mergedeep>=1.3.4', 'boto3>=1.26.118', - 'PyYAML>=6.0', + 'ruyaml>=0.91', 'requests>=2.31.0', 'Jinja2==3.1.2', 'urllib3<2', From b4f9d900faf0dc81a46306a29aeda387094960b4 Mon Sep 17 00:00:00 2001 From: Traxmaxx <320272+Traxmaxx@users.noreply.github.com> Date: Wed, 22 Oct 2025 12:03:51 +0200 Subject: [PATCH 2/3] add test case for stringified octal values --- tests/openapi/complex_source.yml | 7 +++++++ tests/openapi/complex_target.yml | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/tests/openapi/complex_source.yml b/tests/openapi/complex_source.yml index e8edff7..6eb831d 100644 --- a/tests/openapi/complex_source.yml +++ b/tests/openapi/complex_source.yml @@ -403,6 +403,13 @@ components: enum: - draft - submitted + offerCode: + type: string + readOnly: true + enum: + - "0116" + - "0118" + - "0119" stateTransitions: $ref: "#/components/schemas/StateTransitionList" _meta: diff --git a/tests/openapi/complex_target.yml b/tests/openapi/complex_target.yml index 439c1f5..d70e421 100644 --- a/tests/openapi/complex_target.yml +++ b/tests/openapi/complex_target.yml @@ -1252,6 +1252,7 @@ components: - attachments - comment - state + - offerCode - stateTransitions - _meta - _links @@ -1307,6 +1308,13 @@ components: enum: - draft - submitted + offerCode: + type: string + readOnly: true + enum: + - "0116" + - "0118" + - "0119" stateTransitions: type: array readOnly: true @@ -1704,6 +1712,7 @@ components: - attachments - comment - state + - offerCode - stateTransitions - _meta - _links @@ -1759,6 +1768,13 @@ components: enum: - draft - submitted + offerCode: + type: string + readOnly: true + enum: + - "0116" + - "0118" + - "0119" stateTransitions: type: array readOnly: true From 96f8a266bd3c0b9ea1b01d131c3f77feb66539a5 Mon Sep 17 00:00:00 2001 From: Traxmaxx <320272+Traxmaxx@users.noreply.github.com> Date: Wed, 22 Oct 2025 12:38:10 +0200 Subject: [PATCH 3/3] fix: use fixed version and disallow upgrades --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 310eb7c..ead308a 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ def readme(): 'click>=8.1.3, <9', 'mergedeep>=1.3.4', 'boto3>=1.26.118', - 'ruyaml>=0.91', + 'ruyaml==0.91', 'requests>=2.31.0', 'Jinja2==3.1.2', 'urllib3<2',