1
0
mirror of https://github.com/microsoft/qlib.git synced 2026-06-06 05:51:17 +08:00

modify exception message hint for storage.py && fix FileFeatureStorage[:] bug

This commit is contained in:
zhupr
2021-05-22 02:03:50 +08:00
parent b887d2ec32
commit 669f6bd6f5
4 changed files with 33 additions and 27 deletions

View File

@@ -663,7 +663,7 @@ class LocalFeatureProvider(FeatureProvider):
data = self.backend_obj(instrument=instrument, field=field, freq=freq)[start_index : end_index + 1]
except Exception as e:
get_module_logger("data").warning(
f"WARN: data not found for {instrument}.{field}\n\tException info: {str(e)}"
f"WARN: data not found for {instrument}.{field}\n\tFeature exception info: {str(e)}"
)
data = pd.Series(dtype=np.float32)
return data

View File

@@ -230,20 +230,19 @@ class FileFeatureStorage(FileStorage, FeatureStorage):
raise TypeError(f"type(i) = {type(i)}")
with open(self.uri, "rb") as fp:
ref_start_index = int(np.frombuffer(fp.read(4), dtype="<f")[0])
if isinstance(i, int):
if ref_start_index > i:
raise IndexError(f"{i}: start index is {ref_start_index}")
fp.seek(4 * (i - ref_start_index) + 4)
if self.start_index > i:
raise IndexError(f"{i}: start index is {self.start_index}")
fp.seek(4 * (i - self.start_index) + 4)
return i, struct.unpack("f", fp.read(4))[0]
elif isinstance(i, slice):
start_index = i.start
end_index = i.stop - 1
si = max(ref_start_index, start_index)
start_index = self.start_index if i.start is None else i.start
end_index = self.end_index if i.stop is None else i.stop - 1
si = max(self.start_index, start_index)
if si > end_index:
return pd.Series()
fp.seek(4 * (si - ref_start_index) + 4)
fp.seek(4 * (si - self.start_index) + 4)
# read n bytes
count = end_index - si + 1
data = np.frombuffer(fp.read(4 * count), dtype="<f")

View File

@@ -53,10 +53,12 @@ class StorageMeta(type):
_getitem_func = getattr(class_obj, "__getitem__")
def _getitem(obj, item):
_check_func = getattr(obj, "_check")
if callable(_check_func):
_check_func()
return _getitem_func(obj, item)
getattr(obj, "_check")()
try:
res = _getitem_func(obj, item)
except Exception as e:
raise ValueError(f"{obj.raise_info}\n\tStorage exception info: {str(e)}")
return res
setattr(class_obj, "__getitem__", _getitem)
return class_obj
@@ -65,7 +67,16 @@ class StorageMeta(type):
class BaseStorage(metaclass=StorageMeta):
@property
def storage_name(self) -> str:
return re.findall("[A-Z][^A-Z]*", self.__class__.__name__)[-2]
return re.findall("[A-Z][^A-Z]*", self.__class__.__name__)[-2].lower()
@property
def raise_info(self):
parameters_info = [
f"{_k}={_v}"
for _k, _v in self.__dict__.items()
if not isinstance(_v, (dict,)) or (hasattr(_v, "__len__") and len(_v) < 3)
]
return f"{self.storage_name.lower()} not exists, storage parameters: {parameters_info}"
def check_exists(self) -> bool:
"""check if storage(uri) exists, if not exists: return False"""
@@ -84,15 +95,17 @@ class BaseStorage(metaclass=StorageMeta):
)
def _check(self):
# check storage(uri)
if not self.check_exists():
parameters_info = [f"{_k}={_v}" for _k, _v in self.__dict__.items()]
raise ValueError(f"{self.storage_name.lower()} not exists, storage parameters: {parameters_info}")
raise ValueError(self.raise_info)
def __getattribute__(self, item):
if item == "data":
self._check()
return super(BaseStorage, self).__getattribute__(item)
try:
res = super(BaseStorage, self).__getattribute__(item)
except Exception as e:
raise ValueError(f"{self.raise_info}\n\tStorage exception info: {str(e)}")
return res
class CalendarStorage(BaseStorage):

View File

@@ -135,18 +135,12 @@ class TestStorage(TestAutoData):
feature = FeatureStorage(instrument="SH600004", field="close", freq="day", uri=self.provider_uri)
with pytest.raises(IndexError):
with pytest.raises(ValueError):
print(feature[0])
assert isinstance(
feature[815][1], (float, np.float32)
), f"{feature.__class__.__name__}.__getitem__(i: int) error"
assert len(feature[815:818]) == 3, f"{feature.__class__.__name__}.__getitem__(s: slice) error"
print(f"feature[815: 818]: {feature[815: 818]}")
print(f"feature[815: 818]: \n{feature[815: 818]}")
for _item in feature:
assert (
isinstance(_item, tuple) and len(_item) == 2
), f"{feature.__class__.__name__}.__iter__ item type error"
assert isinstance(_item[0], int) and isinstance(
_item[1], (float, np.float32)
), f"{feature.__class__.__name__}.__iter__ value type error"
print(f"feature[:].tail(): \n{feature[:].tail()}")