Mercurial > piecrust2
annotate piecrust/configuration.py @ 870:48d25fd68b8d
assets: Fix bug in assetor.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Mon, 12 Jun 2017 22:30:06 -0700 |
parents | f070a4fc033c |
children | 7e51d14097cb |
rev | line source |
---|---|
0 | 1 import re |
2
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
2 import logging |
584
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
3 import collections |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
4 import collections.abc |
0 | 5 import yaml |
67
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
6 from yaml.constructor import ConstructorError |
444
1359b2b0cc73
performance: Use the fast YAML loader if available.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
7 try: |
1359b2b0cc73
performance: Use the fast YAML loader if available.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
8 from yaml import CSafeLoader as SafeLoader |
1359b2b0cc73
performance: Use the fast YAML loader if available.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
9 except ImportError: |
1359b2b0cc73
performance: Use the fast YAML loader if available.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
10 from yaml import SafeLoader |
0 | 11 |
12 | |
2
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
13 logger = logging.getLogger(__name__) |
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
14 |
431
bdeeee777f85
internal: Floats are also allowed in configurations, duh.
Ludovic Chabant <ludovic@chabant.com>
parents:
367
diff
changeset
|
15 default_allowed_types = (dict, list, tuple, float, int, bool, str) |
367
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
16 |
2
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
17 |
853
f070a4fc033c
core: Continue PieCrust3 refactor, simplify pages.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
18 MERGE_NEW_VALUES = 0 |
f070a4fc033c
core: Continue PieCrust3 refactor, simplify pages.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
19 MERGE_OVERWRITE_VALUES = 1 |
f070a4fc033c
core: Continue PieCrust3 refactor, simplify pages.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
20 MERGE_PREPEND_LISTS = 2 |
f070a4fc033c
core: Continue PieCrust3 refactor, simplify pages.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
21 MERGE_APPEND_LISTS = 4 |
f070a4fc033c
core: Continue PieCrust3 refactor, simplify pages.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
22 MERGE_ALL = MERGE_OVERWRITE_VALUES | MERGE_PREPEND_LISTS |
f070a4fc033c
core: Continue PieCrust3 refactor, simplify pages.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
23 |
f070a4fc033c
core: Continue PieCrust3 refactor, simplify pages.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
24 |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
25 class ConfigurationError(Exception): |
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
26 pass |
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
27 |
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
28 |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
29 class Configuration(collections.abc.MutableMapping): |
0 | 30 def __init__(self, values=None, validate=True): |
31 if values is not None: | |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
32 self.setAll(values, validate=validate) |
2
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
33 else: |
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
34 self._values = None |
0 | 35 |
138
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
36 def __getitem__(self, key): |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
37 self._ensureLoaded() |
666
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
38 try: |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
39 return get_dict_value(self._values, key) |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
40 except KeyError: |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
41 raise KeyError("No such item: %s" % key) |
138
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
42 |
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
43 def __setitem__(self, key, value): |
0 | 44 self._ensureLoaded() |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
45 value = self._validateValue(key, value) |
666
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
46 set_dict_value(self._values, key, value) |
0 | 47 |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
48 def __delitem__(self, key): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
49 raise NotImplementedError() |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
50 |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
51 def __iter__(self): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
52 self._ensureLoaded() |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
53 return iter(self._values) |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
54 |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
55 def __len__(self): |
0 | 56 self._ensureLoaded() |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
57 return len(self._values) |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
58 |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
59 def has(self, key): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
60 return key in self |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
61 |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
62 def set(self, key, value): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
63 self[key] = value |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
64 |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
65 def setAll(self, values, validate=False): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
66 if validate: |
584
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
67 values = self._validateAll(values) |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
68 self._values = values |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
69 |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
70 def getAll(self): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
71 self._ensureLoaded() |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
431
diff
changeset
|
72 return self._values |
0 | 73 |
853
f070a4fc033c
core: Continue PieCrust3 refactor, simplify pages.
Ludovic Chabant <ludovic@chabant.com>
parents:
852
diff
changeset
|
74 def merge(self, other, mode=MERGE_ALL): |
0 | 75 self._ensureLoaded() |
138
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
76 |
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
77 if isinstance(other, dict): |
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
78 other_values = other |
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
79 elif isinstance(other, Configuration): |
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
80 other_values = other._values |
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
81 else: |
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
82 raise Exception( |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
83 "Unsupported value type to merge: %s" % type(other)) |
138
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
84 |
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
85 merge_dicts(self._values, other_values, |
b540d431f2da
Make configuration class more like `dict`, add support for merging `dicts`.
Ludovic Chabant <ludovic@chabant.com>
parents:
107
diff
changeset
|
86 validator=self._validateValue) |
0 | 87 |
367
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
88 def validateTypes(self, allowed_types=default_allowed_types): |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
89 self._validateDictTypesRecursive(self._values, allowed_types) |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
90 |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
91 def _validateDictTypesRecursive(self, d, allowed_types): |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
92 for k, v in d.items(): |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
93 if not isinstance(k, str): |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
94 raise ConfigurationError("Key '%s' is not a string." % k) |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
95 self._validateTypeRecursive(v, allowed_types) |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
96 |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
97 def _validateListTypesRecursive(self, l, allowed_types): |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
98 for v in l: |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
99 self._validateTypeRecursive(v, allowed_types) |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
100 |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
101 def _validateTypeRecursive(self, v, allowed_types): |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
102 if v is None: |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
103 return |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
104 if not isinstance(v, allowed_types): |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
105 raise ConfigurationError( |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
106 "Value '%s' is of forbidden type: %s" % (v, type(v))) |
367
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
107 if isinstance(v, dict): |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
108 self._validateDictTypesRecursive(v, allowed_types) |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
109 elif isinstance(v, list): |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
110 self._validateListTypesRecursive(v, allowed_types) |
734f2abf361c
config: Add method to deep-copy a config and validate its contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
301
diff
changeset
|
111 |
0 | 112 def _ensureLoaded(self): |
113 if self._values is None: | |
114 self._load() | |
115 | |
116 def _load(self): | |
117 self._values = self._validateAll({}) | |
118 | |
119 def _validateAll(self, values): | |
120 return values | |
121 | |
122 def _validateValue(self, key_path, value): | |
123 return value | |
124 | |
125 | |
666
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
126 def get_dict_value(d, key): |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
127 bits = key.split('/') |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
128 cur = d |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
129 for b in bits: |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
130 cur = cur[b] |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
131 return cur |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
132 |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
133 |
805
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
134 def get_dict_values(*args): |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
135 for d, key in args: |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
136 try: |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
137 return get_dict_value(d, key) |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
138 except KeyError: |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
139 continue |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
140 raise KeyError() |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
141 |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
142 |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
143 def try_get_dict_value(d, key, *, default=None): |
683
ec384174b8b2
internal: More work/fixes on how default/theme/user configs are merged.
Ludovic Chabant <ludovic@chabant.com>
parents:
666
diff
changeset
|
144 try: |
ec384174b8b2
internal: More work/fixes on how default/theme/user configs are merged.
Ludovic Chabant <ludovic@chabant.com>
parents:
666
diff
changeset
|
145 return get_dict_value(d, key) |
ec384174b8b2
internal: More work/fixes on how default/theme/user configs are merged.
Ludovic Chabant <ludovic@chabant.com>
parents:
666
diff
changeset
|
146 except KeyError: |
ec384174b8b2
internal: More work/fixes on how default/theme/user configs are merged.
Ludovic Chabant <ludovic@chabant.com>
parents:
666
diff
changeset
|
147 return default |
ec384174b8b2
internal: More work/fixes on how default/theme/user configs are merged.
Ludovic Chabant <ludovic@chabant.com>
parents:
666
diff
changeset
|
148 |
ec384174b8b2
internal: More work/fixes on how default/theme/user configs are merged.
Ludovic Chabant <ludovic@chabant.com>
parents:
666
diff
changeset
|
149 |
743
7705b3d981ca
templating: Make the 'categories' taxonomy use a 'pccaturl' function again.
Ludovic Chabant <ludovic@chabant.com>
parents:
683
diff
changeset
|
150 def try_get_dict_values(*args, default=None): |
7705b3d981ca
templating: Make the 'categories' taxonomy use a 'pccaturl' function again.
Ludovic Chabant <ludovic@chabant.com>
parents:
683
diff
changeset
|
151 for d, key in args: |
7705b3d981ca
templating: Make the 'categories' taxonomy use a 'pccaturl' function again.
Ludovic Chabant <ludovic@chabant.com>
parents:
683
diff
changeset
|
152 try: |
7705b3d981ca
templating: Make the 'categories' taxonomy use a 'pccaturl' function again.
Ludovic Chabant <ludovic@chabant.com>
parents:
683
diff
changeset
|
153 return get_dict_value(d, key) |
7705b3d981ca
templating: Make the 'categories' taxonomy use a 'pccaturl' function again.
Ludovic Chabant <ludovic@chabant.com>
parents:
683
diff
changeset
|
154 except KeyError: |
7705b3d981ca
templating: Make the 'categories' taxonomy use a 'pccaturl' function again.
Ludovic Chabant <ludovic@chabant.com>
parents:
683
diff
changeset
|
155 continue |
7705b3d981ca
templating: Make the 'categories' taxonomy use a 'pccaturl' function again.
Ludovic Chabant <ludovic@chabant.com>
parents:
683
diff
changeset
|
156 return default |
7705b3d981ca
templating: Make the 'categories' taxonomy use a 'pccaturl' function again.
Ludovic Chabant <ludovic@chabant.com>
parents:
683
diff
changeset
|
157 |
7705b3d981ca
templating: Make the 'categories' taxonomy use a 'pccaturl' function again.
Ludovic Chabant <ludovic@chabant.com>
parents:
683
diff
changeset
|
158 |
666
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
159 def set_dict_value(d, key, value): |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
160 bits = key.split('/') |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
161 bitslen = len(bits) |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
162 cur = d |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
163 for i, b in enumerate(bits): |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
164 if i == bitslen - 1: |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
165 cur[b] = value |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
166 else: |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
167 if b not in cur: |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
168 cur[b] = {} |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
169 cur = cur[b] |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
170 |
81d9c3a3a0b5
internal: Get rid of the whole "sub cache" business.
Ludovic Chabant <ludovic@chabant.com>
parents:
584
diff
changeset
|
171 |
805
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
172 def merge_dicts(source, merging, *args, |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
173 validator=None, mode=MERGE_ALL): |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
174 _recurse_merge_dicts(source, merging, None, validator, mode) |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
2
diff
changeset
|
175 for other in args: |
805
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
176 _recurse_merge_dicts(source, other, None, validator, mode) |
584
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
177 return source |
0 | 178 |
2
40fa08b261b9
Added unit tests (using `py.test`) for `Configuration`.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
179 |
805
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
180 def _recurse_merge_dicts(local_cur, incoming_cur, parent_path, |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
181 validator, mode): |
5 | 182 for k, v in incoming_cur.items(): |
0 | 183 key_path = k |
184 if parent_path is not None: | |
185 key_path = parent_path + '/' + k | |
186 | |
187 local_v = local_cur.get(k) | |
188 if local_v is not None: | |
189 if isinstance(v, dict) and isinstance(local_v, dict): | |
805
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
190 _recurse_merge_dicts(local_v, v, key_path, |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
191 validator, mode) |
0 | 192 elif isinstance(v, list) and isinstance(local_v, list): |
805
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
193 if mode & MERGE_PREPEND_LISTS: |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
194 local_cur[k] = v + local_v |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
195 elif mode & MERGE_APPEND_LISTS: |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
196 local_cur[k] = local_v + v |
0 | 197 else: |
805
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
198 if mode & MERGE_OVERWRITE_VALUES: |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
199 if validator is not None: |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
200 v = validator(key_path, v) |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
201 local_cur[k] = v |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
202 else: |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
203 if ((mode & (MERGE_PREPEND_LISTS | MERGE_APPEND_LISTS)) or |
fd694f1297c7
config: Cleanup config loading code. Add support for a `local.yml` config.
Ludovic Chabant <ludovic@chabant.com>
parents:
743
diff
changeset
|
204 not isinstance(v, list)): |
584
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
205 if validator is not None: |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
206 v = validator(key_path, v) |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
207 local_cur[k] = v |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
208 |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
209 |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
210 def visit_dict(subject, visitor): |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
211 _recurse_visit_dict(subject, None, visitor) |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
212 |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
213 |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
214 def _recurse_visit_dict(cur, parent_path, visitor): |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
215 for k, v in cur.items(): |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
216 key_path = k |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
217 if parent_path is not None: |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
218 key_path = parent_path + '/' + k |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
219 |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
220 visitor(key_path, v, cur, k) |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
221 if isinstance(v, dict): |
9ccc933ac2c7
internal: Refactor the app configuration class.
Ludovic Chabant <ludovic@chabant.com>
parents:
444
diff
changeset
|
222 _recurse_visit_dict(v, key_path, visitor) |
0 | 223 |
224 | |
225 header_regex = re.compile( | |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
226 r'(---\s*\n)(?P<header>(.*\n)*?)^(---\s*\n)', re.MULTILINE) |
0 | 227 |
228 | |
229 def parse_config_header(text): | |
230 m = header_regex.match(text) | |
231 if m is not None: | |
5 | 232 header = str(m.group('header')) |
107
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
233 config = yaml.load(header, Loader=ConfigurationLoader) |
0 | 234 offset = m.end() |
235 else: | |
236 config = {} | |
237 offset = 0 | |
238 return config, offset | |
239 | |
67
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
240 |
444
1359b2b0cc73
performance: Use the fast YAML loader if available.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
241 class ConfigurationLoader(SafeLoader): |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
242 """ A YAML loader that loads mappings into ordered dictionaries, |
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
243 and supports sexagesimal notations for timestamps. |
67
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
244 """ |
81
d64e4703f5e6
Propertly create `OrderedDict`s when loading YAML.
Ludovic Chabant <ludovic@chabant.com>
parents:
68
diff
changeset
|
245 def __init__(self, *args, **kwargs): |
107
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
246 super(ConfigurationLoader, self).__init__(*args, **kwargs) |
81
d64e4703f5e6
Propertly create `OrderedDict`s when loading YAML.
Ludovic Chabant <ludovic@chabant.com>
parents:
68
diff
changeset
|
247 |
107
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
248 self.add_constructor('tag:yaml.org,2002:map', |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
249 type(self).construct_yaml_map) |
107
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
250 self.add_constructor('tag:yaml.org,2002:omap', |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
251 type(self).construct_yaml_map) |
107
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
252 self.add_constructor('tag:yaml.org,2002:sexagesimal', |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
253 type(self).construct_yaml_time) |
81
d64e4703f5e6
Propertly create `OrderedDict`s when loading YAML.
Ludovic Chabant <ludovic@chabant.com>
parents:
68
diff
changeset
|
254 |
d64e4703f5e6
Propertly create `OrderedDict`s when loading YAML.
Ludovic Chabant <ludovic@chabant.com>
parents:
68
diff
changeset
|
255 def construct_yaml_map(self, node): |
d64e4703f5e6
Propertly create `OrderedDict`s when loading YAML.
Ludovic Chabant <ludovic@chabant.com>
parents:
68
diff
changeset
|
256 data = collections.OrderedDict() |
d64e4703f5e6
Propertly create `OrderedDict`s when loading YAML.
Ludovic Chabant <ludovic@chabant.com>
parents:
68
diff
changeset
|
257 yield data |
d64e4703f5e6
Propertly create `OrderedDict`s when loading YAML.
Ludovic Chabant <ludovic@chabant.com>
parents:
68
diff
changeset
|
258 value = self.construct_mapping(node) |
d64e4703f5e6
Propertly create `OrderedDict`s when loading YAML.
Ludovic Chabant <ludovic@chabant.com>
parents:
68
diff
changeset
|
259 data.update(value) |
d64e4703f5e6
Propertly create `OrderedDict`s when loading YAML.
Ludovic Chabant <ludovic@chabant.com>
parents:
68
diff
changeset
|
260 |
67
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
261 def construct_mapping(self, node, deep=False): |
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
262 if not isinstance(node, yaml.MappingNode): |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
263 raise ConstructorError( |
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
264 None, None, |
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
265 "expected a mapping node, but found %s" % node.id, |
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
266 node.start_mark) |
67
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
267 mapping = collections.OrderedDict() |
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
268 for key_node, value_node in node.value: |
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
269 key = self.construct_object(key_node, deep=deep) |
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
270 if not isinstance(key, collections.Hashable): |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
271 raise ConstructorError( |
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
272 "while constructing a mapping", node.start_mark, |
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
273 "found unhashable key", key_node.start_mark) |
67
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
274 value = self.construct_object(value_node, deep=deep) |
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
275 mapping[key] = value |
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
276 return mapping |
563ce5dd02af
I don't care what the YAML spec says, ordered maps are the only sane way.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
277 |
107
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
278 time_regexp = re.compile( |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
279 r'''^(?P<hour>[0-9][0-9]?) |
107
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
280 :(?P<minute>[0-9][0-9]) |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
281 (:(?P<second>[0-9][0-9]) |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
282 (\.(?P<fraction>[0-9]+))?)?$''', re.X) |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
283 |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
284 def construct_yaml_time(self, node): |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
285 self.construct_scalar(node) |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
286 match = self.time_regexp.match(node.value) |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
287 values = match.groupdict() |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
288 hour = int(values['hour']) |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
289 minute = int(values['minute']) |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
290 second = 0 |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
291 if values['second']: |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
292 second = int(values['second']) |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
293 usec = 0 |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
294 if values['fraction']: |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
295 usec = float('0.' + values['fraction']) |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
296 return second + minute * 60 + hour * 60 * 60 + usec |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
297 |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
298 |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
299 ConfigurationLoader.add_implicit_resolver( |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
300 'tag:yaml.org,2002:sexagesimal', |
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
301 re.compile(r'''^[0-9][0-9]?:[0-9][0-9] |
107
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
302 (:[0-9][0-9](\.[0-9]+)?)?$''', re.X), |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
303 list('0123456789')) |
107
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
304 |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
305 |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
306 # We need to add our `sexagesimal` resolver before the `int` one, which |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
307 # already supports sexagesimal notation in YAML 1.1 (but not 1.2). However, |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
308 # because we know we pretty much always want it for representing time, we |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
309 # need a simple `12:30` to mean 45000, not 750. So that's why we override |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
310 # the default behaviour. |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
311 for ch in list('0123456789'): |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
312 ch_resolvers = ConfigurationLoader.yaml_implicit_resolvers[ch] |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
313 ch_resolvers.insert(0, ch_resolvers.pop()) |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
314 |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
315 |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
316 class ConfigurationDumper(yaml.SafeDumper): |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
317 def represent_ordered_dict(self, data): |
301
45aba3cb7228
config: Make YAML consider `omap` structures as normal maps.
Ludovic Chabant <ludovic@chabant.com>
parents:
204
diff
changeset
|
318 # Not a typo: we're using `map` and not `omap` because we don't want |
45aba3cb7228
config: Make YAML consider `omap` structures as normal maps.
Ludovic Chabant <ludovic@chabant.com>
parents:
204
diff
changeset
|
319 # ugly type tags printed in the generated YAML markup, and because |
45aba3cb7228
config: Make YAML consider `omap` structures as normal maps.
Ludovic Chabant <ludovic@chabant.com>
parents:
204
diff
changeset
|
320 # we always load maps into `OrderedDicts` anyway. |
45aba3cb7228
config: Make YAML consider `omap` structures as normal maps.
Ludovic Chabant <ludovic@chabant.com>
parents:
204
diff
changeset
|
321 return self.represent_mapping('tag:yaml.org,2002:map', data) |
107
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
322 |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
323 |
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
324 ConfigurationDumper.add_representer(collections.OrderedDict, |
852
4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
Ludovic Chabant <ludovic@chabant.com>
parents:
805
diff
changeset
|
325 ConfigurationDumper.represent_ordered_dict) |
107
10fc9c8bf682
Better support for times in YAML interop.
Ludovic Chabant <ludovic@chabant.com>
parents:
81
diff
changeset
|
326 |