forked from freelawproject/juriscraper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDeferringList.py
62 lines (48 loc) · 2.2 KB
/
DeferringList.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
from juriscraper.AbstractSite import logger
class DeferringList(object):
"""This object can be used to do deferred loading of meta data in the case
that a piece of meta data requires some special work to obtain.
Note that since this inherits from object (rather than list), it won't be
sorted by the _date_sort function. As a result, it's vital that the code
using this object provide the seed data in sorted order. Failure to do so
will result in mixed up data being sent to the caller -- a bad fate.
For an example of how this can be used, see
juriscraper.opinions.united_states.state.tex
"""
def __init__(self, *args, **kwargs):
logger.warn("Using DeferringList object which cannot be sorted until "
"fetched. Note that in usual processing, the fetching "
"happens before the sorting, so this is OK.")
logger.info("DeferringList has %s entries to fetch." %
len(kwargs['seed']))
self._data = kwargs['seed']
self._fetched_items = [False] * len(kwargs['seed'])
self._fetching_function = kwargs['fetcher']
def __iter__(self):
for item in range(0, len(self._data)):
if self._fetched_items[item]:
yield self._data[item]
else:
yield self.__getitem__(item)
def __getitem__(self, item):
if self._fetched_items[item]:
return self._data[item]
else:
# Go get the item using the fetching function
logger.info("Getting deferred value from seed: %s" % self._data[item])
new_val = self._fetching_function(self._data[item])
self._data[item] = new_val
self._fetched_items[item] = True
return new_val
def __setitem__(self, key, value):
if self._fetched_items[key]:
self._data[key] = value
else:
raise AttributeError('Cannot set item that has not yet been fetched.')
def __delitem__(self, item):
del self._data[item]
del self._fetched_items[item]
def __len__(self):
return len(self._data)
def __str__(self):
return "<DeferringList %s>" % self.__dict__