deepfos 1.1.60__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- deepfos/__init__.py +6 -0
- deepfos/_version.py +21 -0
- deepfos/algo/__init__.py +0 -0
- deepfos/algo/graph.py +171 -0
- deepfos/algo/segtree.py +31 -0
- deepfos/api/V1_1/__init__.py +0 -0
- deepfos/api/V1_1/business_model.py +119 -0
- deepfos/api/V1_1/dimension.py +599 -0
- deepfos/api/V1_1/models/__init__.py +0 -0
- deepfos/api/V1_1/models/business_model.py +1033 -0
- deepfos/api/V1_1/models/dimension.py +2768 -0
- deepfos/api/V1_2/__init__.py +0 -0
- deepfos/api/V1_2/dimension.py +285 -0
- deepfos/api/V1_2/models/__init__.py +0 -0
- deepfos/api/V1_2/models/dimension.py +2923 -0
- deepfos/api/__init__.py +0 -0
- deepfos/api/account.py +167 -0
- deepfos/api/accounting_engines.py +147 -0
- deepfos/api/app.py +626 -0
- deepfos/api/approval_process.py +198 -0
- deepfos/api/base.py +983 -0
- deepfos/api/business_model.py +160 -0
- deepfos/api/consolidation.py +129 -0
- deepfos/api/consolidation_process.py +106 -0
- deepfos/api/datatable.py +341 -0
- deepfos/api/deep_pipeline.py +61 -0
- deepfos/api/deepconnector.py +36 -0
- deepfos/api/deepfos_task.py +92 -0
- deepfos/api/deepmodel.py +188 -0
- deepfos/api/dimension.py +486 -0
- deepfos/api/financial_model.py +319 -0
- deepfos/api/journal_model.py +119 -0
- deepfos/api/journal_template.py +132 -0
- deepfos/api/memory_financial_model.py +98 -0
- deepfos/api/models/__init__.py +3 -0
- deepfos/api/models/account.py +483 -0
- deepfos/api/models/accounting_engines.py +756 -0
- deepfos/api/models/app.py +1338 -0
- deepfos/api/models/approval_process.py +1043 -0
- deepfos/api/models/base.py +234 -0
- deepfos/api/models/business_model.py +805 -0
- deepfos/api/models/consolidation.py +711 -0
- deepfos/api/models/consolidation_process.py +248 -0
- deepfos/api/models/datatable_mysql.py +427 -0
- deepfos/api/models/deep_pipeline.py +55 -0
- deepfos/api/models/deepconnector.py +28 -0
- deepfos/api/models/deepfos_task.py +386 -0
- deepfos/api/models/deepmodel.py +308 -0
- deepfos/api/models/dimension.py +1576 -0
- deepfos/api/models/financial_model.py +1796 -0
- deepfos/api/models/journal_model.py +341 -0
- deepfos/api/models/journal_template.py +854 -0
- deepfos/api/models/memory_financial_model.py +478 -0
- deepfos/api/models/platform.py +178 -0
- deepfos/api/models/python.py +221 -0
- deepfos/api/models/reconciliation_engine.py +411 -0
- deepfos/api/models/reconciliation_report.py +161 -0
- deepfos/api/models/role_strategy.py +884 -0
- deepfos/api/models/smartlist.py +237 -0
- deepfos/api/models/space.py +1137 -0
- deepfos/api/models/system.py +1065 -0
- deepfos/api/models/variable.py +463 -0
- deepfos/api/models/workflow.py +946 -0
- deepfos/api/platform.py +199 -0
- deepfos/api/python.py +90 -0
- deepfos/api/reconciliation_engine.py +181 -0
- deepfos/api/reconciliation_report.py +64 -0
- deepfos/api/role_strategy.py +234 -0
- deepfos/api/smartlist.py +69 -0
- deepfos/api/space.py +582 -0
- deepfos/api/system.py +372 -0
- deepfos/api/variable.py +154 -0
- deepfos/api/workflow.py +264 -0
- deepfos/boost/__init__.py +6 -0
- deepfos/boost/py_jstream.py +89 -0
- deepfos/boost/py_pandas.py +20 -0
- deepfos/cache.py +121 -0
- deepfos/config.py +6 -0
- deepfos/core/__init__.py +27 -0
- deepfos/core/cube/__init__.py +10 -0
- deepfos/core/cube/_base.py +462 -0
- deepfos/core/cube/constants.py +21 -0
- deepfos/core/cube/cube.py +408 -0
- deepfos/core/cube/formula.py +707 -0
- deepfos/core/cube/syscube.py +532 -0
- deepfos/core/cube/typing.py +7 -0
- deepfos/core/cube/utils.py +238 -0
- deepfos/core/dimension/__init__.py +11 -0
- deepfos/core/dimension/_base.py +506 -0
- deepfos/core/dimension/dimcreator.py +184 -0
- deepfos/core/dimension/dimension.py +472 -0
- deepfos/core/dimension/dimexpr.py +271 -0
- deepfos/core/dimension/dimmember.py +155 -0
- deepfos/core/dimension/eledimension.py +22 -0
- deepfos/core/dimension/filters.py +99 -0
- deepfos/core/dimension/sysdimension.py +168 -0
- deepfos/core/logictable/__init__.py +5 -0
- deepfos/core/logictable/_cache.py +141 -0
- deepfos/core/logictable/_operator.py +663 -0
- deepfos/core/logictable/nodemixin.py +673 -0
- deepfos/core/logictable/sqlcondition.py +609 -0
- deepfos/core/logictable/tablemodel.py +497 -0
- deepfos/db/__init__.py +36 -0
- deepfos/db/cipher.py +660 -0
- deepfos/db/clickhouse.py +191 -0
- deepfos/db/connector.py +195 -0
- deepfos/db/daclickhouse.py +171 -0
- deepfos/db/dameng.py +101 -0
- deepfos/db/damysql.py +189 -0
- deepfos/db/dbkits.py +358 -0
- deepfos/db/deepengine.py +99 -0
- deepfos/db/deepmodel.py +82 -0
- deepfos/db/deepmodel_kingbase.py +83 -0
- deepfos/db/edb.py +214 -0
- deepfos/db/gauss.py +83 -0
- deepfos/db/kingbase.py +83 -0
- deepfos/db/mysql.py +184 -0
- deepfos/db/oracle.py +131 -0
- deepfos/db/postgresql.py +192 -0
- deepfos/db/sqlserver.py +99 -0
- deepfos/db/utils.py +135 -0
- deepfos/element/__init__.py +89 -0
- deepfos/element/accounting.py +348 -0
- deepfos/element/apvlprocess.py +215 -0
- deepfos/element/base.py +398 -0
- deepfos/element/bizmodel.py +1269 -0
- deepfos/element/datatable.py +2467 -0
- deepfos/element/deep_pipeline.py +186 -0
- deepfos/element/deepconnector.py +59 -0
- deepfos/element/deepmodel.py +1806 -0
- deepfos/element/dimension.py +1254 -0
- deepfos/element/fact_table.py +427 -0
- deepfos/element/finmodel.py +1485 -0
- deepfos/element/journal.py +840 -0
- deepfos/element/journal_template.py +943 -0
- deepfos/element/pyscript.py +412 -0
- deepfos/element/reconciliation.py +553 -0
- deepfos/element/rolestrategy.py +243 -0
- deepfos/element/smartlist.py +457 -0
- deepfos/element/variable.py +756 -0
- deepfos/element/workflow.py +560 -0
- deepfos/exceptions/__init__.py +239 -0
- deepfos/exceptions/hook.py +86 -0
- deepfos/lazy.py +104 -0
- deepfos/lazy_import.py +84 -0
- deepfos/lib/__init__.py +0 -0
- deepfos/lib/_javaobj.py +366 -0
- deepfos/lib/asynchronous.py +879 -0
- deepfos/lib/concurrency.py +107 -0
- deepfos/lib/constant.py +39 -0
- deepfos/lib/decorator.py +310 -0
- deepfos/lib/deepchart.py +778 -0
- deepfos/lib/deepux.py +477 -0
- deepfos/lib/discovery.py +273 -0
- deepfos/lib/edb_lexer.py +789 -0
- deepfos/lib/eureka.py +156 -0
- deepfos/lib/filterparser.py +751 -0
- deepfos/lib/httpcli.py +106 -0
- deepfos/lib/jsonstreamer.py +80 -0
- deepfos/lib/msg.py +394 -0
- deepfos/lib/nacos.py +225 -0
- deepfos/lib/patch.py +92 -0
- deepfos/lib/redis.py +241 -0
- deepfos/lib/serutils.py +181 -0
- deepfos/lib/stopwatch.py +99 -0
- deepfos/lib/subtask.py +572 -0
- deepfos/lib/sysutils.py +703 -0
- deepfos/lib/utils.py +1003 -0
- deepfos/local.py +160 -0
- deepfos/options.py +670 -0
- deepfos/translation.py +237 -0
- deepfos-1.1.60.dist-info/METADATA +33 -0
- deepfos-1.1.60.dist-info/RECORD +175 -0
- deepfos-1.1.60.dist-info/WHEEL +5 -0
- deepfos-1.1.60.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
from .hook import eliminate_from_traceback
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class DeepfosBaseException(Exception):
|
|
5
|
+
"""deepfos自定义异常基类"""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# -----------------------------------------------------------------------------
|
|
9
|
+
# Option Error
|
|
10
|
+
class BaseOptionError(DeepfosBaseException):
|
|
11
|
+
"""配置项异常基类"""
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class OptionNotSetError(BaseOptionError):
|
|
15
|
+
"""配置项未设置"""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class OptionTypeError(BaseOptionError):
|
|
19
|
+
"""配置项类型错误"""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class OptionValueError(BaseOptionError):
|
|
23
|
+
"""配置项值错误"""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# -----------------------------------------------------------------------------
|
|
27
|
+
# API Error
|
|
28
|
+
class APIError(DeepfosBaseException, OSError):
|
|
29
|
+
"""API相关异常"""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class APIRequestError(APIError):
|
|
33
|
+
"""调用API时请求异常"""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class APIResponseError(APIError):
|
|
37
|
+
"""调用API返回异常"""
|
|
38
|
+
def __init__(self, msg, code=None):
|
|
39
|
+
super().__init__(msg)
|
|
40
|
+
self.code = code
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# -----------------------------------------------------------------------------
|
|
44
|
+
# Element Error
|
|
45
|
+
|
|
46
|
+
class ElementError(DeepfosBaseException):
|
|
47
|
+
"""元素相关异常"""
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ElementTypeMissingError(ElementError):
|
|
51
|
+
"""无法获取元素类型"""
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class ElementNotFoundError(ElementError):
|
|
55
|
+
"""元素不存在"""
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class ElementAmbiguousError(ElementError):
|
|
59
|
+
"""无法锁定唯一元素"""
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class ElementVersionIncompatibleError(ElementError):
|
|
63
|
+
"""元素版本不兼容"""
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class DimensionSaveError(ElementError):
|
|
67
|
+
"""无法保存维度"""
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class MemberNotFoundError(ElementError):
|
|
71
|
+
"""维度成员不存在"""
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class VariableUpdateError(ElementError):
|
|
75
|
+
"""无法更新变量"""
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class VariableCreateError(ElementError):
|
|
79
|
+
"""无法新建变量"""
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# -----------------------------------------------------------------------------
|
|
83
|
+
# RedisLock Error
|
|
84
|
+
|
|
85
|
+
class LockAcquireFailed(DeepfosBaseException):
|
|
86
|
+
"""无法获取Redis锁"""
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class BadFutureError(DeepfosBaseException):
|
|
90
|
+
"""获取future property返回值过程出现错误"""
|
|
91
|
+
def __init__(self, msg, obj):
|
|
92
|
+
super().__init__(msg)
|
|
93
|
+
self.obj = obj
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# -----------------------------------------------------------------------------
|
|
97
|
+
# Pyscript Error
|
|
98
|
+
class PyTaskError(DeepfosBaseException):
|
|
99
|
+
"""执行脚本报错基类"""
|
|
100
|
+
base_msg = ''
|
|
101
|
+
|
|
102
|
+
def __init__(self, *reasons):
|
|
103
|
+
self.reasons = reasons
|
|
104
|
+
|
|
105
|
+
def __str__(self):
|
|
106
|
+
if self.base_msg and self.reasons:
|
|
107
|
+
return self.base_msg.format(*self.reasons)
|
|
108
|
+
return self.__class__.__doc__
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class ResultTimeOutError(PyTaskError):
|
|
112
|
+
"""等待python执行结果超时"""
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class PyTaskInvalidError(PyTaskError):
|
|
116
|
+
"""无效的python任务ID"""
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class PyTaskRevokedError(PyTaskError):
|
|
120
|
+
"""python脚本被中断执行"""
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class PyTaskRunTimeError(PyTaskError):
|
|
124
|
+
"""执行脚本出错"""
|
|
125
|
+
base_msg = 'python脚本执行时发生错误,错误信息:\n{}'
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class PyTaskConcurrencyExceed(PyTaskError):
|
|
129
|
+
"""任务并发数过高"""
|
|
130
|
+
base_msg = '当前节点[{}]尝试获取结果的python任务并发数[{}]过高,请稍后尝试获取结果'
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class PyTaskTimeLimitExceed(PyTaskError):
|
|
134
|
+
"""python脚本运行时间超过最大限制"""
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# -----------------------------------------------------------------------------
|
|
138
|
+
# FinancialCube Error
|
|
139
|
+
class MDXExecuteTimeout(DeepfosBaseException):
|
|
140
|
+
"""执行MDX任务超时"""
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class MDXExecuteFail(DeepfosBaseException):
|
|
144
|
+
"""执行MDX任务失败"""
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
# -----------------------------------------------------------------------------
|
|
148
|
+
# DeepModel Error
|
|
149
|
+
class DeepModelError(DeepfosBaseException):
|
|
150
|
+
"""DeepModel相关报错基类"""
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class ObjectNotExist(DeepModelError):
|
|
154
|
+
"""DeepModel对象不存在"""
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class RequiredFieldUnfilled(DeepModelError):
|
|
158
|
+
"""缺少必填字段"""
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class ExternalObjectReadOnly(DeepModelError):
|
|
162
|
+
"""外部对象只可读"""
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class RelationRequired(DeepModelError):
|
|
166
|
+
"""multi link字段缺少relation信息"""
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class SingleLinkInRelation(DeepModelError):
|
|
170
|
+
"""single link字段出现在relation中"""
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class MultiLinkTargetNotUnique(DeepModelError):
|
|
174
|
+
"""relation信息source的target不唯一"""
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
# -----------------------------------------------------------------------------
|
|
178
|
+
# JournalModel Error
|
|
179
|
+
class JournalModelError(DeepfosBaseException):
|
|
180
|
+
"""JournalModel相关报错基类"""
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class JournalModelSaveError(JournalModelError, ValueError):
|
|
184
|
+
"""JournalModel保存失败"""
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class JournalModelCheckError(JournalModelError):
|
|
188
|
+
"""JournalModel校验失败"""
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class JournalModelPostingError(JournalModelError):
|
|
192
|
+
"""JournalModel过账/取消过账失败"""
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
# -----------------------------------------------------------------------------
|
|
196
|
+
# MsgCenter Error
|
|
197
|
+
class MsgCenterError(DeepfosBaseException):
|
|
198
|
+
"""消息中心推送失败"""
|
|
199
|
+
def __init__(self, *reasons):
|
|
200
|
+
self.reasons = reasons
|
|
201
|
+
|
|
202
|
+
def __str__(self):
|
|
203
|
+
return '推送失败,报错信息:' + '\n'.join([r.errorMsg for r in self.reasons])
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
# -----------------------------------------------------------------------------
|
|
207
|
+
# DeepPipeline Error
|
|
208
|
+
class DeepPipelineRunError(DeepfosBaseException):
|
|
209
|
+
"""执行脚本报错基类"""
|
|
210
|
+
base_msg = ''
|
|
211
|
+
|
|
212
|
+
def __init__(self, *reasons):
|
|
213
|
+
self.reasons = reasons
|
|
214
|
+
|
|
215
|
+
def __str__(self):
|
|
216
|
+
if self.base_msg and self.reasons:
|
|
217
|
+
return self.base_msg.format(*self.reasons)
|
|
218
|
+
return self.__class__.__doc__
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class RunIdInvalid(DeepPipelineRunError):
|
|
222
|
+
"""执行ID无效"""
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class RunTerminated(DeepPipelineRunError):
|
|
226
|
+
"""数据流执行被取消"""
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class ReleaseFlowTimeout(DeepPipelineRunError):
|
|
230
|
+
"""获取结果等待超时"""
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class RunFailedError(DeepPipelineRunError):
|
|
234
|
+
"""数据流执行失败"""
|
|
235
|
+
base_msg = '数据流执行失败,报错信息:{}'
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class ReleaseFlowNotExists(DeepPipelineRunError):
|
|
239
|
+
"""暂无启用中状态的数据流版本"""
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import inspect
|
|
3
|
+
|
|
4
|
+
from collections import defaultdict
|
|
5
|
+
from types import TracebackType
|
|
6
|
+
from typing import Type, NamedTuple, Dict, Set, Union, Optional
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
_builtin_exp_hook = sys.excepthook
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CodeSpot(NamedTuple):
|
|
13
|
+
filename: str
|
|
14
|
+
first_lineno: int
|
|
15
|
+
last_lineno: Union[int, float]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CodeLocator:
|
|
19
|
+
spots: Dict[str, Set[CodeSpot]] = defaultdict(set)
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def add_spot(cls, spot: CodeSpot):
|
|
23
|
+
cls.spots[spot.filename].add(spot)
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def contains_tb(cls, tb: TracebackType):
|
|
27
|
+
frame = inspect.getframeinfo(tb.tb_frame)
|
|
28
|
+
if frame.filename not in cls.spots:
|
|
29
|
+
return False
|
|
30
|
+
|
|
31
|
+
return any(
|
|
32
|
+
spot.first_lineno <= frame.lineno < spot.last_lineno
|
|
33
|
+
for spot in cls.spots[frame.filename]
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def eliminate_from_traceback(obj):
|
|
38
|
+
"""将对象从错误栈中移除(可作为装饰器)
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
obj: 需要排除的对象,可以是文件名,函数(方法),类
|
|
42
|
+
|
|
43
|
+
Notes:
|
|
44
|
+
|
|
45
|
+
- 由于技术原因,第一个错误栈无法移除。
|
|
46
|
+
- 出于可读性考虑,最后一个错误栈也不会移除
|
|
47
|
+
|
|
48
|
+
"""
|
|
49
|
+
if isinstance(obj, str):
|
|
50
|
+
filename = obj
|
|
51
|
+
first_lineno = 0
|
|
52
|
+
last_lineno = float('inf')
|
|
53
|
+
else:
|
|
54
|
+
code, first_lineno = inspect.getsourcelines(obj)
|
|
55
|
+
last_lineno = first_lineno + len(code)
|
|
56
|
+
filename = inspect.getfile(obj)
|
|
57
|
+
CodeLocator.add_spot(CodeSpot(
|
|
58
|
+
filename=filename,
|
|
59
|
+
first_lineno=first_lineno,
|
|
60
|
+
last_lineno=last_lineno
|
|
61
|
+
))
|
|
62
|
+
return obj
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def exception_hook(
|
|
66
|
+
exc_type: Type[BaseException],
|
|
67
|
+
exc_value: BaseException,
|
|
68
|
+
tb: Optional[TracebackType]
|
|
69
|
+
):
|
|
70
|
+
if tb is not None:
|
|
71
|
+
contains_tb = CodeLocator.contains_tb
|
|
72
|
+
tb_last = tb
|
|
73
|
+
|
|
74
|
+
while (tb_next := tb_last.tb_next) is not None:
|
|
75
|
+
if (
|
|
76
|
+
contains_tb(tb_next)
|
|
77
|
+
and (next_tb := tb_next.tb_next) is not None
|
|
78
|
+
):
|
|
79
|
+
tb_last.tb_next = next_tb
|
|
80
|
+
else:
|
|
81
|
+
tb_last = tb_next
|
|
82
|
+
|
|
83
|
+
return _builtin_exp_hook(exc_type, exc_value, tb)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
sys.excepthook = exception_hook
|
deepfos/lazy.py
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from importlib import import_module
|
|
3
|
+
from types import ModuleType
|
|
4
|
+
from typing import Dict, Sequence, Any
|
|
5
|
+
|
|
6
|
+
from deepfos.lib.constant import UNSET
|
|
7
|
+
from deepfos.local import Proxy
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class LazyModule(ModuleType):
|
|
11
|
+
|
|
12
|
+
def __init__(self, module_name, parent_module_globals):
|
|
13
|
+
self._module_name = module_name
|
|
14
|
+
self._parent_module_globals = parent_module_globals
|
|
15
|
+
|
|
16
|
+
super(LazyModule, self).__init__(module_name)
|
|
17
|
+
|
|
18
|
+
def _load(self):
|
|
19
|
+
"""Load the module and insert it into the parent's globals."""
|
|
20
|
+
# Import the target module and insert it into the parent's namespace
|
|
21
|
+
module = import_module(self.__name__)
|
|
22
|
+
self._parent_module_globals[self._module_name] = module
|
|
23
|
+
|
|
24
|
+
# Update this object's dict so that if someone keeps a reference to the
|
|
25
|
+
# LazyLoader, lookups are efficient
|
|
26
|
+
# (__getattr__ is only called on lookups that fail).
|
|
27
|
+
self.__dict__.update(module.__dict__)
|
|
28
|
+
|
|
29
|
+
return module
|
|
30
|
+
|
|
31
|
+
def __getattr__(self, attr):
|
|
32
|
+
module = self._load()
|
|
33
|
+
return getattr(module, attr)
|
|
34
|
+
|
|
35
|
+
def __dir__(self):
|
|
36
|
+
module = self._load()
|
|
37
|
+
return dir(module)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class LazyCallable(Proxy):
|
|
41
|
+
def __init__(self, module, local_name):
|
|
42
|
+
object.__setattr__(self, '_LazyCallable__module', module)
|
|
43
|
+
object.__setattr__(self, '_LazyCallable__local_name', local_name)
|
|
44
|
+
object.__setattr__(self, '_LazyCallable__callable', UNSET)
|
|
45
|
+
|
|
46
|
+
__module__ = Proxy.__module__
|
|
47
|
+
|
|
48
|
+
def _get_current_object(self):
|
|
49
|
+
if self.__callable is not UNSET:
|
|
50
|
+
return self.__callable
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
mod = sys.modules[self.__module]
|
|
54
|
+
except KeyError:
|
|
55
|
+
mod = lazy_module(self.__module)
|
|
56
|
+
|
|
57
|
+
object.__setattr__(
|
|
58
|
+
self, '_LazyCallable__callable',
|
|
59
|
+
getattr(mod, self.__local_name)
|
|
60
|
+
)
|
|
61
|
+
return self.__callable
|
|
62
|
+
|
|
63
|
+
def __await__(self):
|
|
64
|
+
return self._get_current_object().__await__()
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def lazy_module(modname):
|
|
68
|
+
"""获得懒加载模块
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
modname: 模块名,形如aaa.bbb.ccc,将得到等效于from aaa.bbb import ccc的懒加载模块
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
return LazyModule(modname, globals())
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def lazy_callable(modname, *names):
|
|
79
|
+
"""获得对应模块里的若干方法/函数的懒加载代理
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
modname : 模块名,形如aaa.bbb.ccc
|
|
83
|
+
names : 方法/函数名
|
|
84
|
+
|
|
85
|
+
"""
|
|
86
|
+
return tuple(LazyCallable(modname, cname) for cname in names)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def lazify(
|
|
90
|
+
target: Dict[str, Sequence[str]],
|
|
91
|
+
_globals: Dict[str, Any]
|
|
92
|
+
):
|
|
93
|
+
"""懒加载模块成员
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
target: module to module members
|
|
97
|
+
_globals: globals in caller scope
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
for modname, mbrs in target.items():
|
|
101
|
+
_globals.update(zip(
|
|
102
|
+
mbrs,
|
|
103
|
+
lazy_callable(modname, *mbrs)
|
|
104
|
+
))
|
deepfos/lazy_import.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from importlib import import_module
|
|
3
|
+
from types import ModuleType
|
|
4
|
+
|
|
5
|
+
from deepfos.lib.constant import UNSET
|
|
6
|
+
from deepfos.local import Proxy
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class LazyModule(ModuleType):
|
|
10
|
+
|
|
11
|
+
def __init__(self, module_name, parent_module_globals):
|
|
12
|
+
self._module_name = module_name
|
|
13
|
+
self._parent_module_globals = parent_module_globals
|
|
14
|
+
|
|
15
|
+
super(LazyModule, self).__init__(module_name)
|
|
16
|
+
|
|
17
|
+
def _load(self):
|
|
18
|
+
"""Load the module and insert it into the parent's globals."""
|
|
19
|
+
# Import the target module and insert it into the parent's namespace
|
|
20
|
+
module = import_module(self.__name__)
|
|
21
|
+
self._parent_module_globals[self._module_name] = module
|
|
22
|
+
|
|
23
|
+
# Update this object's dict so that if someone keeps a reference to the
|
|
24
|
+
# LazyLoader, lookups are efficient
|
|
25
|
+
# (__getattr__ is only called on lookups that fail).
|
|
26
|
+
self.__dict__.update(module.__dict__)
|
|
27
|
+
|
|
28
|
+
return module
|
|
29
|
+
|
|
30
|
+
def __getattr__(self, attr):
|
|
31
|
+
module = self._load()
|
|
32
|
+
return getattr(module, attr)
|
|
33
|
+
|
|
34
|
+
def __dir__(self):
|
|
35
|
+
module = self._load()
|
|
36
|
+
return dir(module)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class LazyCallable(Proxy):
|
|
40
|
+
def __init__(self, module, local_name):
|
|
41
|
+
object.__setattr__(self, '_LazyCallable__module', module)
|
|
42
|
+
object.__setattr__(self, '_LazyCallable__local_name', local_name)
|
|
43
|
+
object.__setattr__(self, '_LazyCallable__callable', UNSET)
|
|
44
|
+
|
|
45
|
+
__module__ = Proxy.__module__
|
|
46
|
+
|
|
47
|
+
def _get_current_object(self):
|
|
48
|
+
if self.__callable is not UNSET:
|
|
49
|
+
return self.__callable
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
mod = sys.modules[self.__module]
|
|
53
|
+
except KeyError:
|
|
54
|
+
mod = lazy_module(self.__module)
|
|
55
|
+
|
|
56
|
+
object.__setattr__(self, '_LazyCallable__callable', getattr(mod, self.__local_name))
|
|
57
|
+
return self.__callable
|
|
58
|
+
|
|
59
|
+
def __await__(self):
|
|
60
|
+
return self._get_current_object().__await__()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def lazy_module(modname):
|
|
64
|
+
"""获得懒加载模块
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
modname: 模块名,形如aaa.bbb.ccc,将得到等效于from aaa.bbb import ccc的懒加载模块
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
"""
|
|
71
|
+
class _LazyModule(LazyModule):
|
|
72
|
+
pass
|
|
73
|
+
return _LazyModule(modname, globals())
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def lazy_callable(modname, *names):
|
|
77
|
+
"""获得对应模块里的若干方法/函数的懒加载代理
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
modname : 模块名,形如aaa.bbb.ccc
|
|
81
|
+
names : 方法/函数名
|
|
82
|
+
|
|
83
|
+
"""
|
|
84
|
+
return tuple(LazyCallable(modname, cname) for cname in names)
|
deepfos/lib/__init__.py
ADDED
|
File without changes
|