Skip to content

Commit 452c77a

Browse files
committed
Rewrite datafiles pool
1 parent 4480fe7 commit 452c77a

File tree

1 file changed

+55
-21
lines changed

1 file changed

+55
-21
lines changed

demosys/resources/data.py

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class Data:
1313
Generic data file.
1414
This can be extended with cusomtized loading functions.
1515
"""
16-
def __init__(self, path, mode='binary'):
16+
def __init__(self, path, mode='binary', **kwargs):
1717
"""
1818
:param path: file with relative path
1919
:param mode: What mode the file should be read ('b': binary, 't': text)
@@ -33,6 +33,9 @@ def __init__(self, path, mode='binary'):
3333
def load(self, path):
3434
self.func(path)
3535

36+
def destroy(self):
37+
self.data = None
38+
3639
def load_binary(self, path):
3740
with open(path, 'rb') as fd:
3841
self.data = fd.read()
@@ -48,16 +51,23 @@ def _get_load_funcs(self):
4851
if attr.startswith("load_")}
4952

5053

54+
class DataFileMeta:
55+
56+
def __init__(self, path, cls, mode, **kwargs):
57+
self.path = path
58+
self.cls = cls
59+
self.mode = mode
60+
self.kwargs = kwargs
61+
62+
5163
class DataFiles(BaseRegistry):
5264
"""Registry for requested data files"""
5365
def __init__(self):
5466
super().__init__()
55-
self.files = []
56-
self.file_map = {}
5767

58-
def get(self, path: str, create=False, cls=Data) -> Data:
68+
def load(self, path: str, cls=Data, mode='binary', **kwargs) -> Data:
5969
"""
60-
Get or create a Data object.
70+
Load Data object or get existing
6171
6272
:param path: data file with path (pathlib.Path)
6373
:param crate: (bool) register a new resource (or fetch existing)
@@ -66,32 +76,56 @@ def get(self, path: str, create=False, cls=Data) -> Data:
6676
"""
6777
path = Path(path)
6878

79+
data_file = self.file_map.get(path)
80+
if data_file:
81+
return data_file
82+
83+
if not data_file:
84+
meta = self.load_deferred(path, cls=cls, mode=mode, **kwargs)
85+
data_file = self._load(meta)
86+
self.file_map[meta.path] = data_file
87+
88+
return data_file
89+
90+
def load_deferred(self, path: str, cls=Data, mode='binary', **kwargs):
91+
"""
92+
Register a resource to be loaded in the loading stage
93+
94+
:returns: DateFileMeta object
95+
"""
6996
if not hasattr(cls, 'load'):
7097
raise ImproperlyConfigured("{} must have a load(path) method".format(cls.__class__))
7198

72-
data_file = self.file_map.get(path)
73-
if not data_file and create:
74-
data_file = cls(path)
75-
self.files.append(data_file)
76-
self.file_map[path] = data_file
99+
meta = DataFileMeta(path, cls, mode, **kwargs)
100+
101+
self.file_map[path] = None
102+
self.file_meta[path] = meta
103+
104+
return meta
105+
106+
def _load(self, meta) -> Data:
107+
"""Internal loader"""
108+
found_path = self._find_last_of(meta.path, list(get_finders()))
109+
110+
if not found_path:
111+
raise ImproperlyConfigured("Cannot find data file {}".format(meta.path))
112+
113+
print(" - {}".format(meta.path))
114+
data_file = meta.cls(meta.path, mode=meta.mode, **meta.kwargs)
115+
data_file.load(found_path)
77116

78117
return data_file
79118

80-
def load(self):
119+
def _destroy(self, obj):
120+
obj.destroy()
121+
122+
def load_pool(self):
81123
"""
82124
Loads all the data files using the configured finders.
83125
"""
84-
finders = list(get_finders())
85126
print("Loading data files:")
86-
for name, data_file in self.file_map.items():
87-
for finder in finders:
88-
path = finder.find(name)
89-
if path:
90-
print(" - {}".format(path))
91-
data_file.load(path)
92-
break
93-
else:
94-
raise ImproperlyConfigured("Cannot find data file {}".format(name))
127+
for path, data_file in self.file_map.items():
128+
self._load(self.file_meta[path])
95129

96130
self._on_loaded()
97131

0 commit comments

Comments
 (0)