diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index be111a5e8..737a607df 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -65,6 +65,31 @@ jobs: pip install pylint pylint --disable=C0104,C0114,C0115,C0116,C0301,C0302,C0411,C0413,C1802,R0201,R0401,R0801,R0902,R0903,R0911,R0912,R0913,R0914,R0915,R1720,W0105,W0123,W0201,W0511,W0613,W1113,W1514,E0401,E1121,C0103,C0209,R0402,R1705,R1710,R1725,R1735,W0102,W0212,W0221,W0223,W0231,W0237,W0612,W0621,W0622,W0703,W1309,E1102,E1136 --const-rgx='[a-z_][a-z0-9_]{2,30}$' qlib --init-hook "import astroid; astroid.context.InferenceContext.max_inferred = 500" + # The following flake8 error codes were ignored: + # E501 line too long + # Description: We have used black to limit the length of each line to 120. + # F541 f-string is missing placeholders + # Description: The same thing is done when using pylint for detection. + # E266 too many leading '#' for block comment + # Description: To make the code more readable, a lot of "#" is used. + # This error code appears centrally in: + # qlib/backtest/executor.py + # qlib/data/ops.py + # qlib/utils/__init__.py + # E402 module level import not at top of file + # Description: There are times when module level import is not available at the top of the file. + # W503 line break before binary operator + # Description: Since black formats the length of each line of code, it has to perform a line break when a line of arithmetic is too long. + # E731 do not assign a lambda expression, use a def + # Description: Restricts the use of lambda expressions, but at some point lambda expressions are required. + # E203 whitespace before ':' + # Description: If there is whitespace before ":", it cannot pass the black check. + - name: Check Qlib with flake8 + run: | + pip install --upgrade pip + pip install flake8 + flake8 --ignore=E501,F541,E266,E402,W503,E731,E203 qlib + - name: Test data downloads run: | python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --interval 1d --region cn diff --git a/.github/workflows/test_macos.yml b/.github/workflows/test_macos.yml index e68411596..2dd375122 100644 --- a/.github/workflows/test_macos.yml +++ b/.github/workflows/test_macos.yml @@ -34,6 +34,13 @@ jobs: python -m black qlib -l 120 --check --diff # Test Qlib installed with pip + - name: Check Qlib with flake8 + run: | + pip install --upgrade pip + pip install flake8 + cd .. + flake8 --ignore=E501,F541,E266,E402,W503,E731,E203 qlib + - name: Install Qlib with pip run: | python -m pip install numpy==1.19.5 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 47b80d18e..18995241b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,3 +3,10 @@ repos: rev: 22.1.0 hooks: - id: black + args: ["qlib", "-l 120"] + +- repo: https://github.com/PyCQA/flake8 + rev: 4.0.1 + hooks: + - id: flake8 + args: ["--ignore=E501,F541,E266,E402,W503,E731,E203"] \ No newline at end of file diff --git a/docs/developer/code_standard.rst b/docs/developer/code_standard.rst index 7cdc3c792..95e887d72 100644 --- a/docs/developer/code_standard.rst +++ b/docs/developer/code_standard.rst @@ -17,7 +17,7 @@ When you submit a PR request, you can check whether your code passes the CI test 1. Qlib will check the code format with black. The PR will raise error if your code does not align to the standard of Qlib(e.g. a common error is the mixed use of space and tab). You can fix the bug by inputing the following code in the command line. -.. code-block:: python +.. code-block:: bash pip install black python -m black . -l 120 @@ -30,3 +30,19 @@ When you submit a PR request, you can check whether your code passes the CI test return -ICLoss()(pred, target, index) # pylint: disable=E1130 + +3. Qlib will check your code style flake8. The checking command is implemented in [github action workflow](https://github.com/microsoft/qlib/blob/0e8b94a552f1c457cfa6cd2c1bb3b87ebb3fb279/.github/workflows/test.yml#L73). + You can fix the bug by inputing the following code in the command line. + +.. code-block:: bash + + flake8 --ignore E501,F541,E402,F401,W503,E741,E266,E203,E302,E731,E262,F523,F821,F811,F841,E713,E265,W291,E712,E722,W293 qlib + + +4. Qlib has integrated pre-commit, which will make it easier for developers to format their code. + Just run the following two commands, and the code will be automatically formatted using black and flake8 when the git commit command is executed. + +.. code-block:: bash + + pip install -e .[dev] + pre-commit install \ No newline at end of file diff --git a/qlib/__init__.py b/qlib/__init__.py index 836ce7224..16bd5c20b 100644 --- a/qlib/__init__.py +++ b/qlib/__init__.py @@ -12,6 +12,7 @@ import platform import subprocess from .log import get_module_logger + # init qlib def init(default_conf="client", **kwargs): """ diff --git a/qlib/backtest/__init__.py b/qlib/backtest/__init__.py index 36f0961be..ab62b7d55 100644 --- a/qlib/backtest/__init__.py +++ b/qlib/backtest/__init__.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. + from __future__ import annotations import copy from typing import List, Tuple, Union, TYPE_CHECKING @@ -323,3 +324,6 @@ def format_decisions( last_dec_idx = i res[1].append((decisions[last_dec_idx], format_decisions(decisions[last_dec_idx + 1 :]))) return res + + +__all__ = ["Order"] diff --git a/qlib/backtest/executor.py b/qlib/backtest/executor.py index 821d36cc0..e1199667c 100644 --- a/qlib/backtest/executor.py +++ b/qlib/backtest/executor.py @@ -242,7 +242,7 @@ class BaseExecutor: if self.track_data: yield trade_decision - atomic = not issubclass(self.__class__, NestedExecutor) # issubclass(A, A) is True + atomic = not issubclass(self.__class__, NestedExecutor) # issubclass(A, A) is True if atomic and trade_decision.get_range_limit(default_value=None) is not None: raise ValueError("atomic executor doesn't support specify `range_limit`") diff --git a/qlib/contrib/data/utils/sepdf.py b/qlib/contrib/data/utils/sepdf.py index 7c3c8665b..90537471e 100644 --- a/qlib/contrib/data/utils/sepdf.py +++ b/qlib/contrib/data/utils/sepdf.py @@ -164,14 +164,14 @@ import builtins def _isinstance(instance, cls): - if isinstance_orig(instance, SepDataFrame): # pylint: disable=E0602 + if isinstance_orig(instance, SepDataFrame): # pylint: disable=E0602 # noqa: F821 if isinstance(cls, Iterable): for c in cls: if c is pd.DataFrame: return True elif cls is pd.DataFrame: return True - return isinstance_orig(instance, cls) # pylint: disable=E0602 + return isinstance_orig(instance, cls) # pylint: disable=E0602 # noqa: F821 builtins.isinstance_orig = builtins.isinstance diff --git a/qlib/contrib/meta/__init__.py b/qlib/contrib/meta/__init__.py index 1422cd4f9..2425c001e 100644 --- a/qlib/contrib/meta/__init__.py +++ b/qlib/contrib/meta/__init__.py @@ -2,3 +2,6 @@ # Licensed under the MIT License. from .data_selection import MetaTaskDS, MetaDatasetDS, MetaModelDS + + +__all__ = ["MetaTaskDS", "MetaDatasetDS", "MetaModelDS"] diff --git a/qlib/contrib/meta/data_selection/__init__.py b/qlib/contrib/meta/data_selection/__init__.py index cc533bc4a..969e77a93 100644 --- a/qlib/contrib/meta/data_selection/__init__.py +++ b/qlib/contrib/meta/data_selection/__init__.py @@ -3,3 +3,6 @@ from .dataset import MetaDatasetDS, MetaTaskDS from .model import MetaModelDS + + +__all__ = ["MetaDatasetDS", "MetaTaskDS", "MetaModelDS"] diff --git a/qlib/contrib/meta/data_selection/model.py b/qlib/contrib/meta/data_selection/model.py index 76f16a2ff..7b8b81101 100644 --- a/qlib/contrib/meta/data_selection/model.py +++ b/qlib/contrib/meta/data_selection/model.py @@ -10,7 +10,6 @@ from tqdm.auto import tqdm import copy from typing import Union, List -from ....data.dataset.weight import Reweighter from ....model.meta.dataset import MetaTaskDataset from ....model.meta.model import MetaTaskModel from ....workflow import R @@ -18,8 +17,8 @@ from .utils import ICLoss from .dataset import MetaDatasetDS from qlib.log import get_module_logger -from qlib.data.dataset.weight import Reweighter from qlib.model.meta.task import MetaTask +from qlib.data.dataset.weight import Reweighter from qlib.contrib.meta.data_selection.net import PredNet logger = get_module_logger("data selection") @@ -98,7 +97,6 @@ class MetaModelDS(MetaTaskModel): if phase == "train": opt.zero_grad() - norm_loss = nn.MSELoss() loss.backward() opt.step() elif phase == "test": diff --git a/qlib/contrib/model/double_ensemble.py b/qlib/contrib/model/double_ensemble.py index 228997ba8..ccdd88af7 100644 --- a/qlib/contrib/model/double_ensemble.py +++ b/qlib/contrib/model/double_ensemble.py @@ -249,7 +249,7 @@ class DEnsembleModel(Model, FeatureInt): return pred def predict_sub(self, submodel, df_data, features): - x_data, y_data = df_data["feature"].loc[:, features], df_data["label"] + x_data = df_data["feature"].loc[:, features] pred_sub = pd.Series(submodel.predict(x_data.values), index=x_data.index) return pred_sub diff --git a/qlib/contrib/model/pytorch_sfm.py b/qlib/contrib/model/pytorch_sfm.py index cebaeef96..29bae94a3 100644 --- a/qlib/contrib/model/pytorch_sfm.py +++ b/qlib/contrib/model/pytorch_sfm.py @@ -84,7 +84,7 @@ class SFM_Model(nn.Module): if len(self.states) == 0: # hasn't initialized yet self.init_states(x) self.get_constants(x) - p_tm1 = self.states[0] + p_tm1 = self.states[0] # noqa: F841 h_tm1 = self.states[1] S_re_tm1 = self.states[2] S_im_tm1 = self.states[3] diff --git a/qlib/contrib/model/pytorch_tabnet.py b/qlib/contrib/model/pytorch_tabnet.py index d50067639..68cc907bb 100644 --- a/qlib/contrib/model/pytorch_tabnet.py +++ b/qlib/contrib/model/pytorch_tabnet.py @@ -477,10 +477,10 @@ class TabNet(nn.Module): sparse_loss = [] out = torch.zeros(x.size(0), self.n_d).to(x.device) for step in self.steps: - x_te, l = step(x, x_a, priors) + x_te, loss = step(x, x_a, priors) out += F.relu(x_te[:, : self.n_d]) # split the feature from feat_transformer x_a = x_te[:, self.n_d :] - sparse_loss.append(l) + sparse_loss.append(loss) return self.fc(out), sum(sparse_loss) diff --git a/qlib/contrib/online/__init__.py b/qlib/contrib/online/__init__.py index 642cf8d3a..0da4c05e9 100644 --- a/qlib/contrib/online/__init__.py +++ b/qlib/contrib/online/__init__.py @@ -1,4 +1,5 @@ # pylint: skip-file +# flake8: noqa ''' TODO: diff --git a/qlib/contrib/online/manager.py b/qlib/contrib/online/manager.py index d0b82df43..d101bcd08 100644 --- a/qlib/contrib/online/manager.py +++ b/qlib/contrib/online/manager.py @@ -2,6 +2,7 @@ # Licensed under the MIT License. # pylint: skip-file +# flake8: noqa import yaml import pathlib diff --git a/qlib/contrib/online/online_model.py b/qlib/contrib/online/online_model.py index 1f7d455dd..2dc9533df 100644 --- a/qlib/contrib/online/online_model.py +++ b/qlib/contrib/online/online_model.py @@ -2,6 +2,7 @@ # Licensed under the MIT License. # pylint: skip-file +# flake8: noqa import random import pandas as pd diff --git a/qlib/contrib/online/operator.py b/qlib/contrib/online/operator.py index 082e5da50..d5c9edd62 100644 --- a/qlib/contrib/online/operator.py +++ b/qlib/contrib/online/operator.py @@ -2,6 +2,7 @@ # Licensed under the MIT License. # pylint: skip-file +# flake8: noqa import fire import pandas as pd diff --git a/qlib/contrib/online/user.py b/qlib/contrib/online/user.py index aade29596..fa74831ee 100644 --- a/qlib/contrib/online/user.py +++ b/qlib/contrib/online/user.py @@ -2,6 +2,7 @@ # Licensed under the MIT License. # pylint: skip-file +# flake8: noqa import logging diff --git a/qlib/contrib/online/utils.py b/qlib/contrib/online/utils.py index 3b4ec8c5d..5f2cbcf75 100644 --- a/qlib/contrib/online/utils.py +++ b/qlib/contrib/online/utils.py @@ -2,6 +2,7 @@ # Licensed under the MIT License. # pylint: skip-file +# flake8: noqa import pathlib import pickle diff --git a/qlib/contrib/report/analysis_model/__init__.py b/qlib/contrib/report/analysis_model/__init__.py index 496805d67..a53a74b4e 100644 --- a/qlib/contrib/report/analysis_model/__init__.py +++ b/qlib/contrib/report/analysis_model/__init__.py @@ -2,3 +2,6 @@ # Licensed under the MIT License. from .analysis_model_performance import model_performance_graph + + +__all__ = ["model_performance_graph"] diff --git a/qlib/contrib/report/analysis_position/__init__.py b/qlib/contrib/report/analysis_position/__init__.py index 86d8803dd..cfe51a224 100644 --- a/qlib/contrib/report/analysis_position/__init__.py +++ b/qlib/contrib/report/analysis_position/__init__.py @@ -6,3 +6,6 @@ from .score_ic import score_ic_graph from .report import report_graph from .rank_label import rank_label_graph from .risk_analysis import risk_analysis_graph + + +__all__ = ["cumulative_return_graph", "score_ic_graph", "report_graph", "rank_label_graph", "risk_analysis_graph"] diff --git a/qlib/contrib/strategy/__init__.py b/qlib/contrib/strategy/__init__.py index 672d24058..b7051f575 100644 --- a/qlib/contrib/strategy/__init__.py +++ b/qlib/contrib/strategy/__init__.py @@ -15,3 +15,14 @@ from .rule_strategy import ( ) from .cost_control import SoftTopkStrategy + + +__all__ = [ + "TopkDropoutStrategy", + "WeightStrategyBase", + "EnhancedIndexingStrategy", + "TWAPStrategy", + "SBBStrategyBase", + "SBBStrategyEMA", + "SoftTopkStrategy", +] diff --git a/qlib/contrib/strategy/optimizer/__init__.py b/qlib/contrib/strategy/optimizer/__init__.py index 5080b9a46..18b2aacdf 100644 --- a/qlib/contrib/strategy/optimizer/__init__.py +++ b/qlib/contrib/strategy/optimizer/__init__.py @@ -4,3 +4,6 @@ from .base import BaseOptimizer from .optimizer import PortfolioOptimizer from .enhanced_indexing import EnhancedIndexingOptimizer + + +__all__ = ["BaseOptimizer", "PortfolioOptimizer", "EnhancedIndexingOptimizer"] diff --git a/qlib/contrib/strategy/signal_strategy.py b/qlib/contrib/strategy/signal_strategy.py index 9d2b8124f..20b051cc7 100644 --- a/qlib/contrib/strategy/signal_strategy.py +++ b/qlib/contrib/strategy/signal_strategy.py @@ -131,10 +131,10 @@ class TopkDropoutStrategy(BaseSignalStrategy): if self.only_tradable: # If The strategy only consider tradable stock when make decision # It needs following actions to filter stocks - def get_first_n(l, n, reverse=False): + def get_first_n(li, n, reverse=False): cur_n = 0 res = [] - for si in reversed(l) if reverse else l: + for si in reversed(li) if reverse else li: if self.trade_exchange.is_stock_tradable( stock_id=si, start_time=trade_start_time, end_time=trade_end_time ): @@ -144,13 +144,13 @@ class TopkDropoutStrategy(BaseSignalStrategy): break return res[::-1] if reverse else res - def get_last_n(l, n): - return get_first_n(l, n, reverse=True) + def get_last_n(li, n): + return get_first_n(li, n, reverse=True) - def filter_stock(l): + def filter_stock(li): return [ si - for si in l + for si in li if self.trade_exchange.is_stock_tradable( stock_id=si, start_time=trade_start_time, end_time=trade_end_time ) @@ -158,14 +158,14 @@ class TopkDropoutStrategy(BaseSignalStrategy): else: # Otherwise, the stock will make decision with out the stock tradable info - def get_first_n(l, n): - return list(l)[:n] + def get_first_n(li, n): + return list(li)[:n] - def get_last_n(l, n): - return list(l)[-n:] + def get_last_n(li, n): + return list(li)[-n:] - def filter_stock(l): - return l + def filter_stock(li): + return li current_temp = copy.deepcopy(self.trade_position) # generate order list for this adjust date @@ -203,7 +203,7 @@ class TopkDropoutStrategy(BaseSignalStrategy): candi = filter_stock(last) try: sell = pd.Index(np.random.choice(candi, self.n_drop, replace=False) if len(last) else []) - except ValueError: # No enough candidates + except ValueError: # No enough candidates sell = candi else: raise NotImplementedError(f"This type of input is not supported") diff --git a/qlib/contrib/tuner/__init__.py b/qlib/contrib/tuner/__init__.py index 388083ed9..987899415 100644 --- a/qlib/contrib/tuner/__init__.py +++ b/qlib/contrib/tuner/__init__.py @@ -1 +1,2 @@ # pylint: skip-file +# flake8: noqa diff --git a/qlib/contrib/tuner/config.py b/qlib/contrib/tuner/config.py index 3a6ba4345..6e37f0097 100644 --- a/qlib/contrib/tuner/config.py +++ b/qlib/contrib/tuner/config.py @@ -2,6 +2,7 @@ # Licensed under the MIT License. # pylint: skip-file +# flake8: noqa import yaml import copy diff --git a/qlib/contrib/tuner/launcher.py b/qlib/contrib/tuner/launcher.py index 36828e443..352d2ca48 100644 --- a/qlib/contrib/tuner/launcher.py +++ b/qlib/contrib/tuner/launcher.py @@ -2,6 +2,7 @@ # Licensed under the MIT License. # pylint: skip-file +# flake8: noqa # coding=utf-8 diff --git a/qlib/contrib/tuner/pipeline.py b/qlib/contrib/tuner/pipeline.py index 7b651276d..db48c46cf 100644 --- a/qlib/contrib/tuner/pipeline.py +++ b/qlib/contrib/tuner/pipeline.py @@ -2,6 +2,7 @@ # Licensed under the MIT License. # pylint: skip-file +# flake8: noqa import os import json diff --git a/qlib/contrib/tuner/space.py b/qlib/contrib/tuner/space.py index 67cc8a7f5..4959d8dc9 100644 --- a/qlib/contrib/tuner/space.py +++ b/qlib/contrib/tuner/space.py @@ -2,6 +2,7 @@ # Licensed under the MIT License. # pylint: skip-file +# flake8: noqa from hyperopt import hp diff --git a/qlib/contrib/tuner/tuner.py b/qlib/contrib/tuner/tuner.py index 9c0db6494..c183b28ae 100644 --- a/qlib/contrib/tuner/tuner.py +++ b/qlib/contrib/tuner/tuner.py @@ -2,6 +2,7 @@ # Licensed under the MIT License. # pylint: skip-file +# flake8: noqa import os import yaml diff --git a/qlib/contrib/workflow/__init__.py b/qlib/contrib/workflow/__init__.py index 9945e179c..0faf4e5f9 100644 --- a/qlib/contrib/workflow/__init__.py +++ b/qlib/contrib/workflow/__init__.py @@ -2,3 +2,6 @@ # Licensed under the MIT License. from .record_temp import MultiSegRecord from .record_temp import SignalMseRecord + + +__all__ = ["MultiSegRecord", "SignalMseRecord"] diff --git a/qlib/data/__init__.py b/qlib/data/__init__.py index 4baf6c72a..a6bc6df88 100644 --- a/qlib/data/__init__.py +++ b/qlib/data/__init__.py @@ -35,3 +35,32 @@ from .cache import ( DatasetURICache, MemoryCalendarCache, ) + + +__all__ = [ + "D", + "CalendarProvider", + "InstrumentProvider", + "FeatureProvider", + "ExpressionProvider", + "DatasetProvider", + "LocalCalendarProvider", + "LocalInstrumentProvider", + "LocalFeatureProvider", + "LocalPITProvider", + "LocalExpressionProvider", + "LocalDatasetProvider", + "ClientCalendarProvider", + "ClientInstrumentProvider", + "ClientDatasetProvider", + "BaseProvider", + "LocalProvider", + "ClientProvider", + "ExpressionCache", + "DatasetCache", + "DiskExpressionCache", + "DiskDatasetCache", + "SimpleDatasetCache", + "DatasetURICache", + "MemoryCalendarCache", +] diff --git a/qlib/data/cache.py b/qlib/data/cache.py index fc6518de5..fc53aab3d 100644 --- a/qlib/data/cache.py +++ b/qlib/data/cache.py @@ -33,7 +33,7 @@ from ..utils import ( from ..log import get_module_logger from .base import Feature -from .ops import Operators # pylint: disable=W0611 +from .ops import Operators # pylint: disable=W0611 # noqa: F401 class QlibCacheException(RuntimeError): @@ -528,7 +528,7 @@ class DiskExpressionCache(ExpressionCache): CacheUtils.visit(cache_path) series = read_bin(cache_path, start_index, end_index) return series - except Exception as e: + except Exception: series = None self.logger.error("reading %s file error : %s" % (cache_path, traceback.format_exc())) return series @@ -1068,7 +1068,7 @@ class SimpleDatasetCache(DatasetCache): super(SimpleDatasetCache, self).__init__(provider) try: self.local_cache_path: Path = Path(C["local_cache_path"]).expanduser().resolve() - except (KeyError, TypeError) as e: + except (KeyError, TypeError): self.logger.error("Assign a local_cache_path in config if you want to use this cache mechanism") raise self.logger.info( diff --git a/qlib/data/data.py b/qlib/data/data.py index ee82a2e2e..7e602a17e 100644 --- a/qlib/data/data.py +++ b/qlib/data/data.py @@ -38,7 +38,7 @@ from ..utils import ( get_period_list, ) from ..utils.paral import ParallelExt -from .ops import Operators # pylint: disable=W0611 +from .ops import Operators # pylint: disable=W0611 # noqa: F401 class ProviderBackendMixin: diff --git a/qlib/data/dataset/__init__.py b/qlib/data/dataset/__init__.py index 3f8b7dcf0..b1ec7383d 100644 --- a/qlib/data/dataset/__init__.py +++ b/qlib/data/dataset/__init__.py @@ -609,3 +609,6 @@ class TSDatasetH(DatasetH): tsds = TSDataSampler(data=data, start=start, end=end, step_len=self.step_len, dtype=dtype, flt_data=flt_data) return tsds + + +__all__ = ["Optional"] diff --git a/qlib/data/ops.py b/qlib/data/ops.py index 2b742bebe..4fc18e4e5 100644 --- a/qlib/data/ops.py +++ b/qlib/data/ops.py @@ -22,7 +22,7 @@ except ImportError: "#### Do not import qlib package in the repository directory in case of importing qlib from . without compiling #####" ) raise -except ValueError as e: +except ValueError: print("!!!!!!!! A error occurs when importing operators implemented based on Cython.!!!!!!!!") print("!!!!!!!! They will be disabled. Please Upgrade your numpy to enable them !!!!!!!!") # We catch this error because some platform can't upgrade there package (e.g. Kaggle) diff --git a/qlib/data/storage/__init__.py b/qlib/data/storage/__init__.py index 552e1e3e8..a77fb0e3e 100644 --- a/qlib/data/storage/__init__.py +++ b/qlib/data/storage/__init__.py @@ -2,3 +2,6 @@ # Licensed under the MIT License. from .storage import CalendarStorage, InstrumentStorage, FeatureStorage, CalVT, InstVT, InstKT + + +__all__ = ["CalendarStorage", "InstrumentStorage", "FeatureStorage", "CalVT", "InstVT", "InstKT"] diff --git a/qlib/model/__init__.py b/qlib/model/__init__.py index c639b57f5..35fb5c43a 100644 --- a/qlib/model/__init__.py +++ b/qlib/model/__init__.py @@ -4,3 +4,6 @@ import warnings from .base import Model + + +__all__ = ["Model", "warnings"] diff --git a/qlib/model/meta/__init__.py b/qlib/model/meta/__init__.py index 4421c8d19..1290014a7 100644 --- a/qlib/model/meta/__init__.py +++ b/qlib/model/meta/__init__.py @@ -3,3 +3,6 @@ from .task import MetaTask from .dataset import MetaTaskDataset + + +__all__ = ["MetaTask", "MetaTaskDataset"] diff --git a/qlib/model/riskmodel/__init__.py b/qlib/model/riskmodel/__init__.py index 05af6b7d3..f9459d905 100644 --- a/qlib/model/riskmodel/__init__.py +++ b/qlib/model/riskmodel/__init__.py @@ -5,3 +5,11 @@ from .base import RiskModel from .poet import POETCovEstimator from .shrink import ShrinkCovEstimator from .structured import StructuredCovEstimator + + +__all__ = [ + "RiskModel", + "POETCovEstimator", + "ShrinkCovEstimator", + "StructuredCovEstimator", +] diff --git a/qlib/utils/__init__.py b/qlib/utils/__init__.py index de60b18b7..50fb785d8 100644 --- a/qlib/utils/__init__.py +++ b/qlib/utils/__init__.py @@ -14,22 +14,19 @@ import json import yaml import redis import bisect -import shutil import struct import difflib import inspect import hashlib -import warnings import datetime import requests -import tempfile import importlib import contextlib import collections import numpy as np import pandas as pd from pathlib import Path -from typing import List, Dict, Union, Tuple, Any, Text, Optional, Callable +from typing import List, Dict, Union, Tuple, Any, Optional, Callable from types import ModuleType from urllib.parse import urlparse from packaging import version @@ -1047,3 +1044,12 @@ def fname_to_code(fname: str): if fname.startswith(prefix): fname = fname.lstrip(prefix) return fname + + +__all__ = [ + "get_or_create_path", + "save_multiple_parts_file", + "unpack_archive_with_buffer", + "get_tmp_file_with_buffer", + "set_log_with_config", +] diff --git a/qlib/utils/time.py b/qlib/utils/time.py index fbd582fa8..e6d2a9a17 100644 --- a/qlib/utils/time.py +++ b/qlib/utils/time.py @@ -199,10 +199,8 @@ class Freq: """ base_freq = Freq(base_freq) # use the nearest freq greater than 0 - _freq_minutes = [] min_freq = None for _freq in freq_list: - freq = Freq(_freq) _min_delta = Freq.get_min_delta(base_freq, _freq) if _min_delta < 0: continue diff --git a/qlib/workflow/expm.py b/qlib/workflow/expm.py index 5d9896e5c..96509b344 100644 --- a/qlib/workflow/expm.py +++ b/qlib/workflow/expm.py @@ -170,12 +170,9 @@ class ExpManager: experiment_name = self._default_exp_name if create: - exp, is_new = self._get_or_create_exp(experiment_id=experiment_id, experiment_name=experiment_name) + exp, _ = self._get_or_create_exp(experiment_id=experiment_id, experiment_name=experiment_name) else: - exp, is_new = ( - self._get_exp(experiment_id=experiment_id, experiment_name=experiment_name), - False, - ) + exp = self._get_exp(experiment_id=experiment_id, experiment_name=experiment_name) if self.active_experiment is None and start: self.active_experiment = exp # start the recorder @@ -201,7 +198,7 @@ class ExpManager: # So we supported it in the interface wrapper pr = urlparse(self.uri) if pr.scheme == "file": - with FileLock(os.path.join(pr.netloc, pr.path, "filelock")) as f: # pylint: disable=E0110 + with FileLock(os.path.join(pr.netloc, pr.path, "filelock")): # pylint: disable=E0110 return self.create_exp(experiment_name), True # NOTE: for other schemes like http, we double check to avoid create exp conflicts try: diff --git a/qlib/workflow/record_temp.py b/qlib/workflow/record_temp.py index 161da1bb6..55ede19b9 100644 --- a/qlib/workflow/record_temp.py +++ b/qlib/workflow/record_temp.py @@ -146,7 +146,7 @@ class RecordTemp: for item in self.list(): ps = self.get_path(item).split("/") - dirn, fn = "/".join(ps[:-1]), ps[-1] + dirn = "/".join(ps[:-1]) if self.get_path(item) not in _get_arts(dirn): raise FileNotFoundError if parents: