1
0
mirror of https://github.com/microsoft/qlib.git synced 2026-07-15 16:56:54 +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] data = self.backend_obj(instrument=instrument, field=field, freq=freq)[start_index : end_index + 1]
except Exception as e: except Exception as e:
get_module_logger("data").warning( 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) data = pd.Series(dtype=np.float32)
return data return data

View File

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

View File

@@ -53,10 +53,12 @@ class StorageMeta(type):
_getitem_func = getattr(class_obj, "__getitem__") _getitem_func = getattr(class_obj, "__getitem__")
def _getitem(obj, item): def _getitem(obj, item):
_check_func = getattr(obj, "_check") getattr(obj, "_check")()
if callable(_check_func): try:
_check_func() res = _getitem_func(obj, item)
return _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) setattr(class_obj, "__getitem__", _getitem)
return class_obj return class_obj
@@ -65,7 +67,16 @@ class StorageMeta(type):
class BaseStorage(metaclass=StorageMeta): class BaseStorage(metaclass=StorageMeta):
@property @property
def storage_name(self) -> str: 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: def check_exists(self) -> bool:
"""check if storage(uri) exists, if not exists: return False""" """check if storage(uri) exists, if not exists: return False"""
@@ -84,15 +95,17 @@ class BaseStorage(metaclass=StorageMeta):
) )
def _check(self): def _check(self):
# check storage(uri)
if not self.check_exists(): if not self.check_exists():
parameters_info = [f"{_k}={_v}" for _k, _v in self.__dict__.items()] raise ValueError(self.raise_info)
raise ValueError(f"{self.storage_name.lower()} not exists, storage parameters: {parameters_info}")
def __getattribute__(self, item): def __getattribute__(self, item):
if item == "data": if item == "data":
self._check() 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): class CalendarStorage(BaseStorage):

View File

@@ -135,18 +135,12 @@ class TestStorage(TestAutoData):
feature = FeatureStorage(instrument="SH600004", field="close", freq="day", uri=self.provider_uri) feature = FeatureStorage(instrument="SH600004", field="close", freq="day", uri=self.provider_uri)
with pytest.raises(IndexError): with pytest.raises(ValueError):
print(feature[0]) print(feature[0])
assert isinstance( assert isinstance(
feature[815][1], (float, np.float32) feature[815][1], (float, np.float32)
), f"{feature.__class__.__name__}.__getitem__(i: int) error" ), f"{feature.__class__.__name__}.__getitem__(i: int) error"
assert len(feature[815:818]) == 3, f"{feature.__class__.__name__}.__getitem__(s: slice) 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: print(f"feature[:].tail(): \n{feature[:].tail()}")
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"