Add !date and !decimal YAML constructors to avoid unsafe parsing mode

At some point the defaults for pyyaml were switched to safe parsing mode, so
that the previous arbitrary Python YAML tags like
"!!python/object/apply:datetime.date [2017, 9, 1]" no longer work. A better way
is to define our own explicit constructors to avoid unsafe mode.
This commit is contained in:
Ben Sturmfels 2025-09-19 17:21:47 +10:00
parent 579f6dde4b
commit 61b9683743
Signed by: bsturmfels
GPG key ID: 023C05E2C9C068F0
2 changed files with 458 additions and 449 deletions

File diff suppressed because it is too large Load diff

View file

@ -6,7 +6,6 @@ import importlib
import itertools import itertools
import pathlib import pathlib
import shutil import shutil
import re
import pytest import pytest
import yaml import yaml
@ -14,14 +13,23 @@ from import2ledger import importers, strparse
from . import DATA_DIR from . import DATA_DIR
try:
load_yaml = yaml.full_load def decimal_constructor(loader, node):
except AttributeError: value = loader.construct_scalar(node)
load_yaml = yaml.load return decimal.Decimal(value)
def date_constructor(loader, node):
value = loader.construct_scalar(node)
return datetime.date.fromisoformat(value)
class TestImporters: class TestImporters:
Loader = yaml.Loader
Loader.add_constructor('!decimal', decimal_constructor)
Loader.add_constructor('!date', date_constructor)
with pathlib.Path(DATA_DIR, 'imports.yml').open() as yaml_file: with pathlib.Path(DATA_DIR, 'imports.yml').open() as yaml_file:
test_data = load_yaml(yaml_file) test_data = yaml.load(yaml_file, Loader=Loader)
for test in test_data: for test in test_data:
test['source'] = DATA_DIR / test['source'] test['source'] = DATA_DIR / test['source']