Mercurial > piecrust2
annotate piecrust/data/base.py @ 1188:a7c43131d871
bake: Fix file write flushing problem with Python 3.8+
Writing the cache files fails in Python 3.8 because it looks like flushing
behaviour has changed. We need to explicitly flush. And even then, in very
rare occurrences, it looks like it can still run into racing conditions,
so we do a very hacky and ugly "retry" loop when fetching cached data :(
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 15 Jun 2021 22:36:23 -0700 |
parents | 501bd4ab7e06 |
children |
rev | line source |
---|---|
1010
501bd4ab7e06
internal: Remove unused parameter.
Ludovic Chabant <ludovic@chabant.com>
parents:
989
diff
changeset
|
1 import time |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
2 import collections.abc |
381
4c9eab0e283b
data: Fix problems with using non-existing metadata on a linked page.
Ludovic Chabant <ludovic@chabant.com>
parents:
369
diff
changeset
|
3 |
4c9eab0e283b
data: Fix problems with using non-existing metadata on a linked page.
Ludovic Chabant <ludovic@chabant.com>
parents:
369
diff
changeset
|
4 |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
5 class MergedMapping(collections.abc.Mapping): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
6 """ Provides a dictionary-like object that's really the aggregation of |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
7 multiple dictionary-like objects. |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
8 """ |
1010
501bd4ab7e06
internal: Remove unused parameter.
Ludovic Chabant <ludovic@chabant.com>
parents:
989
diff
changeset
|
9 def __init__(self, dicts, path=''): |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
10 self._dicts = dicts |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
11 self._path = path |
226
e9dc18a275ff
data: Add ability for `IPaginationSource`s to specify how to get settings.
Ludovic Chabant <ludovic@chabant.com>
parents:
158
diff
changeset
|
12 |
12
30a42341cfa8
Define page slugs properly, avoid recursions with debug data.
Ludovic Chabant <ludovic@chabant.com>
parents:
6
diff
changeset
|
13 def __getattr__(self, name): |
30a42341cfa8
Define page slugs properly, avoid recursions with debug data.
Ludovic Chabant <ludovic@chabant.com>
parents:
6
diff
changeset
|
14 try: |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
15 return self[name] |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
16 except KeyError: |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
17 raise AttributeError("No such attribute: %s" % self._subp(name)) |
12
30a42341cfa8
Define page slugs properly, avoid recursions with debug data.
Ludovic Chabant <ludovic@chabant.com>
parents:
6
diff
changeset
|
18 |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
19 def __getitem__(self, name): |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
20 values = [] |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
21 for d in self._dicts: |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
22 try: |
713
d446029c9478
data: Support both objects and dictionaries in `MergedMapping`.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
23 val = getattr(d, name) |
d446029c9478
data: Support both objects and dictionaries in `MergedMapping`.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
24 values.append(val) |
d446029c9478
data: Support both objects and dictionaries in `MergedMapping`.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
25 continue |
d446029c9478
data: Support both objects and dictionaries in `MergedMapping`.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
26 except AttributeError: |
d446029c9478
data: Support both objects and dictionaries in `MergedMapping`.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
27 pass |
d446029c9478
data: Support both objects and dictionaries in `MergedMapping`.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
28 |
d446029c9478
data: Support both objects and dictionaries in `MergedMapping`.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
29 try: |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
30 val = d[name] |
713
d446029c9478
data: Support both objects and dictionaries in `MergedMapping`.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
31 values.append(val) |
d446029c9478
data: Support both objects and dictionaries in `MergedMapping`.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
32 continue |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
33 except KeyError: |
713
d446029c9478
data: Support both objects and dictionaries in `MergedMapping`.
Ludovic Chabant <ludovic@chabant.com>
parents:
440
diff
changeset
|
34 pass |
236
eaf18442bff8
internal: Add support for "wildcard" loader in `LazyPageConfigData`.
Ludovic Chabant <ludovic@chabant.com>
parents:
228
diff
changeset
|
35 |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
36 if len(values) == 0: |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
37 raise KeyError("No such item: %s" % self._subp(name)) |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
38 if len(values) == 1: |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
39 return values[0] |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
40 |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
41 for val in values: |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
42 if not isinstance(val, (dict, collections.abc.Mapping)): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
43 raise Exception( |
901 | 44 "Template data for '%s' contains an incompatible mix " |
45 "of data: %s" % ( | |
46 self._subp(name), | |
47 ', '.join([str(type(v)) for v in values]))) | |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
48 |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
49 return MergedMapping(values, self._subp(name)) |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
50 |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
51 def __iter__(self): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
52 keys = set() |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
53 for d in self._dicts: |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
54 keys |= set(d.keys()) |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
55 return iter(keys) |
3
f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
56 |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
57 def __len__(self): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
58 keys = set() |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
59 for d in self._dicts: |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
60 keys |= set(d.keys()) |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
61 return len(keys) |
12
30a42341cfa8
Define page slugs properly, avoid recursions with debug data.
Ludovic Chabant <ludovic@chabant.com>
parents:
6
diff
changeset
|
62 |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
63 def _subp(self, name): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
64 return '%s/%s' % (self._path, name) |
6
f5ca5c5bed85
More Python 3 fixes, modularization, and new unit tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
65 |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
66 def _prependMapping(self, d): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
67 self._dicts.insert(0, d) |
6
f5ca5c5bed85
More Python 3 fixes, modularization, and new unit tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
68 |
440
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
69 def _appendMapping(self, d): |
32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
Ludovic Chabant <ludovic@chabant.com>
parents:
433
diff
changeset
|
70 self._dicts.append(d) |
6
f5ca5c5bed85
More Python 3 fixes, modularization, and new unit tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
71 |