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 "