Skip to content

Commit 758416f

Browse files
committed
Use custom YAML loader when loading contexts
1 parent d06aa24 commit 758416f

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

pattern_library/utils.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
from pattern_library.context_modifiers import registry
2323
from pattern_library.exceptions import TemplateIsNotPattern
2424

25+
# Define our own yaml loader so we can register constructors on it without
26+
# polluting the original loader from the library.
27+
class PatternLibraryLoader(yaml.FullLoader):
28+
pass
29+
2530

2631
def path_to_section():
2732
section_config = get_sections()
@@ -100,7 +105,7 @@ def get_pattern_config_str(template_name):
100105
def get_pattern_config(template_name):
101106
config_str = get_pattern_config_str(template_name)
102107
if config_str:
103-
return yaml.load(config_str, Loader=yaml.FullLoader)
108+
return yaml.load(config_str, Loader=PatternLibraryLoader)
104109
return {}
105110

106111

tests/tests/test_utils.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import os
2+
from unittest import mock
23

4+
import yaml
35
from django.conf import settings
46
from django.test import SimpleTestCase, override_settings
7+
from yaml.constructor import ConstructorError
58

69
from pattern_library.utils import (
10+
get_pattern_config,
711
get_pattern_config_str,
812
get_renderer,
913
get_template_dirs,
14+
PatternLibraryLoader,
1015
)
1116

1217

@@ -121,3 +126,31 @@ def test_atom_yml(self):
121126

122127
self.assertNotEqual(result, "")
123128
self.assertIn("atom_var value from test_atom.yml", result)
129+
130+
@mock.patch("pattern_library.utils.get_pattern_config_str")
131+
def test_custom_yaml_tag_error_if_unregistered(self, get_pattern_config_str):
132+
get_pattern_config_str.return_value = "context:\n atom_var: !customtag"
133+
134+
self.assertRaises(
135+
ConstructorError,
136+
get_pattern_config,
137+
"patterns/atoms/test_custom_yaml_tag/test_custom_yaml_tag.html",
138+
)
139+
140+
@mock.patch("pattern_library.utils.get_pattern_config_str")
141+
def test_custom_yaml_tag(self, get_pattern_config_str):
142+
get_pattern_config_str.return_value = "context:\n atom_var: !customtag"
143+
yaml.add_constructor(
144+
"!customtag",
145+
lambda loader, node: 42,
146+
Loader=PatternLibraryLoader,
147+
)
148+
# PyYAML's API doesn't have a remove_constructor() function so we do
149+
# that manually to avoid leaving things on the loader after the test
150+
# is finished.
151+
self.addCleanup(PatternLibraryLoader.yaml_constructors.pop, "!customtag")
152+
153+
self.assertEqual(
154+
get_pattern_config("mocked.html"),
155+
{"context": {"atom_var": 42}},
156+
)

0 commit comments

Comments
 (0)