Mercurial > piecrust2
comparison piecrust/data/base.py @ 381:4c9eab0e283b
data: Fix problems with using non-existing metadata on a linked page.
The page data wrapper now has supports for loader to raise a custom exception
to declare that they can't return a value after all (this is especially
useful for the wildcard loader). The returned value, if any, is also now cached
properly.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 10 May 2015 00:37:28 -0700 |
parents | 4b1019bb2533 |
children | 923a9b96411d |
comparison
equal
deleted
inserted
replaced
380:f33712c4cfab | 381:4c9eab0e283b |
---|---|
4 from piecrust.data.assetor import Assetor | 4 from piecrust.data.assetor import Assetor |
5 from piecrust.uriutil import split_uri | 5 from piecrust.uriutil import split_uri |
6 | 6 |
7 | 7 |
8 logger = logging.getLogger(__name__) | 8 logger = logging.getLogger(__name__) |
9 | |
10 | |
11 class LazyPageConfigLoaderHasNoValue(Exception): | |
12 """ An exception that can be returned when a loader for `LazyPageConfig` | |
13 can't return any value. | |
14 """ | |
15 pass | |
9 | 16 |
10 | 17 |
11 class LazyPageConfigData(object): | 18 class LazyPageConfigData(object): |
12 """ An object that represents the configuration header of a page, | 19 """ An object that represents the configuration header of a page, |
13 but also allows for additional data. It's meant to be exposed | 20 but also allows for additional data. It's meant to be exposed |
26 return self._page | 33 return self._page |
27 | 34 |
28 def get(self, name): | 35 def get(self, name): |
29 try: | 36 try: |
30 return self._getValue(name) | 37 return self._getValue(name) |
31 except KeyError: | 38 except LazyPageConfigLoaderHasNoValue: |
32 return None | 39 return None |
33 | 40 |
34 def __getattr__(self, name): | 41 def __getattr__(self, name): |
35 try: | 42 try: |
36 return self._getValue(name) | 43 return self._getValue(name) |
37 except KeyError: | 44 except LazyPageConfigLoaderHasNoValue: |
38 raise AttributeError | 45 raise AttributeError |
39 | 46 |
40 def __getitem__(self, name): | 47 def __getitem__(self, name): |
41 return self._getValue(name) | 48 try: |
49 return self._getValue(name) | |
50 except LazyPageConfigLoaderHasNoValue: | |
51 raise KeyError | |
42 | 52 |
43 def _getValue(self, name): | 53 def _getValue(self, name): |
44 self._load() | 54 self._load() |
55 | |
56 if name in self._values: | |
57 return self._values[name] | |
45 | 58 |
46 if self._loaders: | 59 if self._loaders: |
47 loader = self._loaders.get(name) | 60 loader = self._loaders.get(name) |
48 if loader is not None: | 61 if loader is not None: |
49 try: | 62 try: |
50 self._values[name] = loader(self, name) | 63 self._values[name] = loader(self, name) |
64 except LazyPageConfigLoaderHasNoValue: | |
65 raise | |
51 except Exception as ex: | 66 except Exception as ex: |
52 raise Exception( | 67 raise Exception( |
53 "Error while loading attribute '%s' for: %s" % | 68 "Error while loading attribute '%s' for: %s" % |
54 (name, self._page.rel_path)) from ex | 69 (name, self._page.rel_path)) from ex |
55 | 70 |
59 if self._loaders is not None: | 74 if self._loaders is not None: |
60 del self._loaders[name] | 75 del self._loaders[name] |
61 if len(self._loaders) == 0: | 76 if len(self._loaders) == 0: |
62 self._loaders = None | 77 self._loaders = None |
63 | 78 |
64 elif name not in self._values: | 79 else: |
65 loader = self._loaders.get('*') | 80 loader = self._loaders.get('*') |
66 if loader is not None: | 81 if loader is not None: |
67 try: | 82 try: |
68 self._values[name] = loader(self, name) | 83 self._values[name] = loader(self, name) |
84 except LazyPageConfigLoaderHasNoValue: | |
85 raise | |
69 except Exception as ex: | 86 except Exception as ex: |
70 raise Exception( | 87 raise Exception( |
71 "Error while loading attirbute '%s' for: %s" % | 88 "Error while loading attribute '%s' for: %s" % |
72 (name, self._page.rel_path)) from ex | 89 (name, self._page.rel_path)) from ex |
73 | 90 # We always keep the wildcard loader in the loaders list. |
91 | |
92 assert name in self._values | |
74 return self._values[name] | 93 return self._values[name] |
75 | 94 |
76 def _setValue(self, name, value): | 95 def _setValue(self, name, value): |
77 if self._values is None: | 96 if self._values is None: |
78 raise Exception("Can't call _setValue before this data has been " | 97 raise Exception("Can't call _setValue before this data has been " |