dv-flow-mgr 0.0.1.13335470340a1__py3-none-any.whl → 0.0.1.13478128278a1__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.
@@ -0,0 +1,50 @@
1
+
2
+ import dataclasses as dc
3
+ from typing import Any, Callable, Dict, List
4
+ from .expr_parser import ExprVisitor, Expr, ExprBin, ExprBinOp, ExprCall, ExprId, ExprString, ExprInt
5
+
6
+ @dc.dataclass
7
+ class ExprEval(ExprVisitor):
8
+ methods : Dict[str, Callable] = dc.field(default_factory=dict)
9
+ variables : Dict[str, object] = dc.field(default_factory=dict)
10
+ value : Any = None
11
+
12
+ def eval(self, e : Expr):
13
+ self.value = None
14
+ e.accept(self)
15
+ return self.value
16
+
17
+ def visitExprId(self, e : ExprId):
18
+ if e.id in self.variables:
19
+ self.value = self.variables[e.id]
20
+ else:
21
+ raise Exception("Variable %s not found" % e.id)
22
+
23
+ def visitExprString(self, e : ExprString):
24
+ self.value = e.value
25
+
26
+ def visitExprBin(self, e):
27
+ e.lhs.accept(self)
28
+
29
+ if e.op == ExprBinOp.Pipe:
30
+ # Value just goes over to the rhs
31
+ e.rhs.accept(self)
32
+ elif e.op == ExprBinOp.Plus:
33
+ pass
34
+
35
+ def visitExprCall(self, e : ExprCall):
36
+ if e.id in self.methods:
37
+ # Need to gather up argument values
38
+ in_value = self.value
39
+ args = []
40
+ for arg in e.args:
41
+ self.value = None
42
+ arg.accept(self)
43
+ args.append(self.value)
44
+
45
+ self.value = self.methods[e.id](in_value, args)
46
+ else:
47
+ raise Exception("Method %s not found" % e.id)
48
+
49
+ def visitExprInt(self, e : ExprInt):
50
+ self.value = e.value
@@ -1,38 +1,233 @@
1
1
  import dataclasses as dc
2
2
  import enum
3
-
4
- class TokenKind(enum.Enum):
5
- ID = enum.auto()
3
+ import ply.lex as lex
4
+ import ply.yacc as yacc
5
+ from typing import ClassVar, List
6
6
 
7
7
  @dc.dataclass
8
8
  class Expr(object):
9
- kind : TokenKind = TokenKind.ID
9
+ def accept(self, v):
10
+ raise NotImplementedError("Expr.accept for %s" % str(type(sepf)))
10
11
 
12
+ @dc.dataclass
11
13
  class ExprId(Expr):
12
14
  id : str
13
15
 
14
- def __post_init__(self):
15
- self.kind = TokenKind.ID
16
+ def accept(self, v):
17
+ v.visitExprId(self)
18
+
19
+ class ExprBinOp(enum.Enum):
20
+ Pipe = enum.auto()
21
+ Plus = enum.auto()
22
+ Minus = enum.auto()
23
+ Times = enum.auto()
24
+ Divide = enum.auto()
16
25
 
17
- class ExprPipe(Expr):
26
+ @dc.dataclass
27
+ class ExprBin(Expr):
28
+ op : ExprBinOp
18
29
  lhs : Expr
19
30
  rhs : Expr
20
31
 
21
- def __post_init__(self):
22
- self.kind = TokenKind.ID
32
+ def accept(self, v):
33
+ v.visitExprBin(self)
34
+
35
+ @dc.dataclass
36
+ class ExprCall(Expr):
37
+ id : str
38
+ args : List[Expr]
39
+
40
+ def accept(self, v):
41
+ v.visitExprCall(self)
42
+
43
+ @dc.dataclass
44
+ class ExprString(Expr):
45
+ value : str
46
+
47
+ def accept(self, v):
48
+ v.visitExprString(self)
23
49
 
50
+ @dc.dataclass
51
+ class ExprInt(Expr):
52
+ value : int
53
+
54
+ def accept(self, v):
55
+ v.visitExprInt(self)
56
+
57
+ class ExprVisitor(object):
58
+ def visitExprId(self, e : ExprId):
59
+ pass
60
+
61
+ def visitExprBin(self, e : ExprBin):
62
+ e.lhs.accept(self)
63
+ e.rhs.accept(self)
64
+
65
+ def visitExprCall(self, e : ExprCall):
66
+ for arg in e.args:
67
+ arg.accept(self)
68
+
69
+ def visitExprString(self, e : ExprString):
70
+ pass
71
+
72
+ def visitExprInt(self, e : ExprInt):
73
+ pass
74
+
75
+ @dc.dataclass
76
+ class ExprVisitor2String(ExprVisitor):
77
+ _ret : str = ""
78
+ _idx : int = 0
79
+
80
+ @staticmethod
81
+ def toString(e : Expr):
82
+ v = ExprVisitor2String()
83
+ e.accept(v)
84
+ return v._ret
85
+
86
+ def visitExprId(self, e : ExprId):
87
+ self._ret += e.id
88
+
89
+ def visitExprBin(self, e):
90
+ e.lhs.accept(self)
91
+ self._ret += " "
92
+ self._ret += "op%d" % self._idx
93
+ self._idx += 1
94
+ self._ret += " "
95
+ e.rhs.accept(self)
96
+
97
+ def visitExprCall(self, e):
98
+ self._ret += e.id
99
+ self._ret += "("
100
+ for i, arg in enumerate(e.args):
101
+ if i > 0:
102
+ self._ret += ", "
103
+ arg.accept(self)
104
+ self._ret += ")"
105
+
106
+ def visitExprString(self, e):
107
+ self._ret += e.value
108
+
109
+ def visitExprInt(self, e):
110
+ self._ret += str(e.value)
24
111
 
25
112
 
26
113
  class ExprParser(object):
27
114
 
28
- def __init__(self, input):
29
- self.input = input
115
+ _inst : ClassVar['ExprParser'] = None
116
+
117
+ def __init__(self):
118
+
119
+ # Build the lexer
120
+ self.lexer = lex.lex(module=self)
121
+ self.parser = yacc.yacc(module=self)
122
+
123
+ @classmethod
124
+ def inst(cls):
125
+ if cls._inst is None:
126
+ cls._inst = ExprParser()
127
+ return cls._inst
128
+
129
+ tokens = (
130
+ 'ID','NUMBER','COMMA',
131
+ 'PLUS','MINUS','TIMES','DIVIDE',
132
+ 'LPAREN','RPAREN','PIPE','STRING1','STRING2'
133
+ )
134
+
135
+ # Tokens
136
+
137
+ t_COMMA = r','
138
+ t_PLUS = r'\+'
139
+ t_MINUS = r'-'
140
+ t_TIMES = r'\*'
141
+ t_DIVIDE = r'/'
142
+ t_LPAREN = r'\('
143
+ t_RPAREN = r'\)'
144
+ t_ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
145
+ t_PIPE = r'\|'
146
+ t_STRING2 = r'\'.*\''
147
+
148
+ def t_NUMBER(self, t):
149
+ r'\d+'
150
+ try:
151
+ t.value = ExprInt(int(t.value))
152
+ except ValueError:
153
+ print("Integer value too large %d", t.value)
154
+ t.value = ExprInt(0)
155
+ return t
156
+
157
+ def t_STRING1(self, t):
158
+ r'(\'|\")([^\\\n]|(\\.))*?(\'|\")'
159
+ t.value = t.value[1:-1].replace('\\"', '"').replace("\\'", "'").replace('\\n', '\n').replace('\\t', '\t').replace('\\\\', '\\')
160
+ return t
161
+
162
+ # Ignored characters
163
+ t_ignore = " \t"
164
+
165
+ def t_newline(self, t):
166
+ r'\n+'
167
+ t.lexer.lineno += t.value.count("\n")
168
+
169
+ def t_error(self, t):
170
+ print("Illegal character '%s'" % t.value[0])
171
+ t.lexer.skip(1)
172
+
173
+ precedence = (
174
+ ('left','PLUS','MINUS','PIPE'),
175
+ ('left','TIMES','DIVIDE'),
176
+ # ('right','UMINUS'),
177
+ )
178
+
179
+ def p_call(self, t):
180
+ """expression : ID LPAREN RPAREN
181
+ | ID LPAREN args RPAREN"""
182
+ t[0] = ExprCall(t[1], t[3] if len(t) == 5 else [])
183
+
184
+ def p_args(self, t):
185
+ """args : expression
186
+ | args COMMA expression"""
187
+ if len(t) == 2:
188
+ t[0] = [t[1]]
189
+ else:
190
+ t[0] = t[1]
191
+ t[0].append(t[3])
192
+
193
+ def p_expression_binop(self, t):
194
+ '''expression : expression PLUS expression
195
+ | expression MINUS expression
196
+ | expression TIMES expression
197
+ | expression PIPE expression
198
+ | expression DIVIDE expression'''
199
+ op_m = {
200
+ '+' : ExprBinOp.Plus,
201
+ '-' : ExprBinOp.Minus,
202
+ '*' : ExprBinOp.Times,
203
+ '|' : ExprBinOp.Pipe,
204
+ '/' : ExprBinOp.Divide
205
+ }
206
+ t[0] = ExprBin(op_m[t[2]], t[1], t[3])
207
+
208
+ def p_expression_group(self, t):
209
+ 'expression : LPAREN expression RPAREN'
210
+ t[0] = t[2]
211
+
212
+ def p_expression_number(self, t):
213
+ 'expression : NUMBER'
214
+ t[0] = t[1]
215
+
216
+ def p_expression_name(self, t):
217
+ 'expression : ID'
218
+ t[0] = ExprId(t[1])
219
+
220
+ def p_expression_string1(self, t):
221
+ 'expression : STRING1'
222
+ t[0] = ExprString(t[1])
30
223
 
31
- def __iter__(self):
32
- return self
224
+ def p_expression_string2(self, t):
225
+ 'expression : STRING2'
226
+ t[0] = ExprString(t[1])
33
227
 
34
- def __next__(self):
228
+ def p_error(self, t):
229
+ print("Syntax error at '%s'" % t.value)
35
230
 
36
- self.expr = expr
37
- self.tokens = []
38
- self.pos = 0
231
+ def parse(self, input):
232
+ return self.parser.parse(input, lexer=self.lexer)
233
+
dv_flow/mgr/package.py CHANGED
@@ -22,7 +22,7 @@
22
22
  import dataclasses as dc
23
23
  import logging
24
24
  from typing import Any, ClassVar, Dict
25
- from .task import TaskCtor
25
+ from .task_ctor import TaskCtor
26
26
 
27
27
  @dc.dataclass
28
28
  class Package(object):
@@ -33,7 +33,8 @@ from typing import Any, Dict, List, Callable, Tuple, ClassVar
33
33
  from .fragment_def import FragmentDef
34
34
  from .package import Package
35
35
  from .package_import_spec import PackageImportSpec, PackageSpec
36
- from .task import TaskCtor, TaskCtorProxy, TaskCtorCls, TaskCtorParam, TaskCtorParamCls
36
+ #from .task import TaskCtorCls, TaskCtorParam, TaskCtorParamCls
37
+ from .task_ctor import TaskCtor
37
38
  from .task_def import TaskDef, TaskSpec
38
39
  from .std.task_null import TaskNull
39
40
  from .type_def import TypeDef
@@ -0,0 +1,44 @@
1
+
2
+ # parsetab.py
3
+ # This file is automatically generated. Do not edit.
4
+ # pylint: disable=W,C,R
5
+ _tabversion = '3.10'
6
+
7
+ _lr_method = 'LALR'
8
+
9
+ _lr_signature = 'leftPLUSMINUSPIPEleftTIMESDIVIDECOMMA DIVIDE ID LPAREN MINUS NUMBER PIPE PLUS RPAREN STRING1 STRING2 TIMESexpression : ID LPAREN RPAREN \n | ID LPAREN args RPARENargs : expression \n | args COMMA expressionexpression : expression PLUS expression\n | expression MINUS expression\n | expression TIMES expression\n | expression PIPE expression\n | expression DIVIDE expressionexpression : LPAREN expression RPARENexpression : NUMBERexpression : IDexpression : STRING1expression : STRING2'
10
+
11
+ _lr_action_items = {'ID':([0,3,7,8,9,10,11,12,24,],[2,2,2,2,2,2,2,2,2,]),'LPAREN':([0,2,3,7,8,9,10,11,12,24,],[3,12,3,3,3,3,3,3,3,3,]),'NUMBER':([0,3,7,8,9,10,11,12,24,],[4,4,4,4,4,4,4,4,4,]),'STRING1':([0,3,7,8,9,10,11,12,24,],[5,5,5,5,5,5,5,5,5,]),'STRING2':([0,3,7,8,9,10,11,12,24,],[6,6,6,6,6,6,6,6,6,]),'$end':([1,2,4,5,6,14,15,16,17,18,19,22,23,],[0,-12,-11,-13,-14,-5,-6,-7,-8,-9,-1,-10,-2,]),'PLUS':([1,2,4,5,6,13,14,15,16,17,18,19,21,22,23,25,],[7,-12,-11,-13,-14,7,-5,-6,-7,-8,-9,-1,7,-10,-2,7,]),'MINUS':([1,2,4,5,6,13,14,15,16,17,18,19,21,22,23,25,],[8,-12,-11,-13,-14,8,-5,-6,-7,-8,-9,-1,8,-10,-2,8,]),'TIMES':([1,2,4,5,6,13,14,15,16,17,18,19,21,22,23,25,],[9,-12,-11,-13,-14,9,9,9,-7,9,-9,-1,9,-10,-2,9,]),'PIPE':([1,2,4,5,6,13,14,15,16,17,18,19,21,22,23,25,],[10,-12,-11,-13,-14,10,-5,-6,-7,-8,-9,-1,10,-10,-2,10,]),'DIVIDE':([1,2,4,5,6,13,14,15,16,17,18,19,21,22,23,25,],[11,-12,-11,-13,-14,11,11,11,-7,11,-9,-1,11,-10,-2,11,]),'RPAREN':([2,4,5,6,12,13,14,15,16,17,18,19,20,21,22,23,25,],[-12,-11,-13,-14,19,22,-5,-6,-7,-8,-9,-1,23,-3,-10,-2,-4,]),'COMMA':([2,4,5,6,14,15,16,17,18,19,20,21,22,23,25,],[-12,-11,-13,-14,-5,-6,-7,-8,-9,-1,24,-3,-10,-2,-4,]),}
12
+
13
+ _lr_action = {}
14
+ for _k, _v in _lr_action_items.items():
15
+ for _x,_y in zip(_v[0],_v[1]):
16
+ if not _x in _lr_action: _lr_action[_x] = {}
17
+ _lr_action[_x][_k] = _y
18
+ del _lr_action_items
19
+
20
+ _lr_goto_items = {'expression':([0,3,7,8,9,10,11,12,24,],[1,13,14,15,16,17,18,21,25,]),'args':([12,],[20,]),}
21
+
22
+ _lr_goto = {}
23
+ for _k, _v in _lr_goto_items.items():
24
+ for _x, _y in zip(_v[0], _v[1]):
25
+ if not _x in _lr_goto: _lr_goto[_x] = {}
26
+ _lr_goto[_x][_k] = _y
27
+ del _lr_goto_items
28
+ _lr_productions = [
29
+ ("S' -> expression","S'",1,None,None,None),
30
+ ('expression -> ID LPAREN RPAREN','expression',3,'p_call','expr_parser.py',160),
31
+ ('expression -> ID LPAREN args RPAREN','expression',4,'p_call','expr_parser.py',161),
32
+ ('args -> expression','args',1,'p_args','expr_parser.py',165),
33
+ ('args -> args COMMA expression','args',3,'p_args','expr_parser.py',166),
34
+ ('expression -> expression PLUS expression','expression',3,'p_expression_binop','expr_parser.py',174),
35
+ ('expression -> expression MINUS expression','expression',3,'p_expression_binop','expr_parser.py',175),
36
+ ('expression -> expression TIMES expression','expression',3,'p_expression_binop','expr_parser.py',176),
37
+ ('expression -> expression PIPE expression','expression',3,'p_expression_binop','expr_parser.py',177),
38
+ ('expression -> expression DIVIDE expression','expression',3,'p_expression_binop','expr_parser.py',178),
39
+ ('expression -> LPAREN expression RPAREN','expression',3,'p_expression_group','expr_parser.py',189),
40
+ ('expression -> NUMBER','expression',1,'p_expression_number','expr_parser.py',193),
41
+ ('expression -> ID','expression',1,'p_expression_name','expr_parser.py',197),
42
+ ('expression -> STRING1','expression',1,'p_expression_string1','expr_parser.py',201),
43
+ ('expression -> STRING2','expression',1,'p_expression_string2','expr_parser.py',205),
44
+ ]
dv_flow/mgr/task.py CHANGED
@@ -25,267 +25,158 @@ import dataclasses as dc
25
25
  import logging
26
26
  from pydantic import BaseModel
27
27
  from typing import Any, Callable, ClassVar, Dict, List, Tuple
28
- from .task_data import TaskData
28
+ from .task_data import TaskData, TaskDataInput, TaskDataOutput, TaskDataResult
29
29
  from .task_memento import TaskMemento
30
+ from .task_ctor import TaskParamsCtor
31
+ from .task_params_ctor import TaskParamsCtor
32
+ from .task_runner import TaskRunner
30
33
 
31
- @dc.dataclass
32
- class TaskSpec(object):
33
- name : str
34
+ # @dc.dataclass
35
+ # class TaskSpec(object):
36
+ # name : str
34
37
 
35
- class TaskParams(BaseModel):
36
- pass
38
+ # class TaskParams(BaseModel):
39
+ # pass
37
40
 
38
41
 
39
- @dc.dataclass
40
- class TaskCtor(object):
41
- name : str
42
- uses : 'TaskCtor' = None
43
- srcdir : str = None
44
- depends : List[TaskSpec] = dc.field(default_factory=list)
45
-
46
- _log : ClassVar = logging.getLogger("TaskCtor")
47
-
48
- def mkTask(self, name : str, depends, rundir, srcdir=None, params=None):
49
- if srcdir is None:
50
- srcdir = self.srcdir
51
- if params is None:
52
- params = self.mkParams()
53
-
54
- if self.uses is not None:
55
- return self.uses.mkTask(name, depends, rundir, srcdir, params)
56
- else:
57
- raise NotImplementedError("TaskCtor.mkTask() not implemented for %s" % str(type(self)))
58
-
59
- def mkParams(self):
60
- self._log.debug("--> %s::mkParams" % self.name)
61
- if self.uses is not None:
62
- params = self.uses.mkParams()
63
- else:
64
- params = TaskParams()
65
- self._log.debug("<-- %s::mkParams: %s" % (self.name, str(params)))
42
+ # @dc.dataclass
43
+ # class TaskCtorParam(TaskCtor):
44
+ # params : Dict[str,Any] = dc.field(default_factory=dict)
66
45
 
67
- return params
46
+ # _log : ClassVar = logging.getLogger("TaskCtorParam")
68
47
 
69
- def applyParams(self, params):
70
- if self.uses is not None:
71
- self.uses.applyParams(params)
48
+ # def mkTask(self, name : str, depends, rundir, srcdir=None, params=None):
49
+ # self._log.debug("--> %s::mkTask" % self.name)
50
+ # if params is None:
51
+ # params = self.mkParams()
52
+ # if srcdir is None:
53
+ # srcdir = self.srcdir
72
54
 
55
+ # ret = self.uses.mkTask(name, depends, rundir, srcdir, params)
73
56
 
74
- @dc.dataclass
75
- class TaskCtorParam(TaskCtor):
76
- params : Dict[str,Any] = dc.field(default_factory=dict)
77
-
78
- _log : ClassVar = logging.getLogger("TaskCtorParam")
79
-
80
- def mkTask(self, name : str, depends, rundir, srcdir=None, params=None):
81
- self._log.debug("--> %s::mkTask" % self.name)
82
- if params is None:
83
- params = self.mkParams()
84
- if srcdir is None:
85
- srcdir = self.srcdir
86
-
87
- ret = self.uses.mkTask(name, depends, rundir, srcdir, params)
88
-
89
- self.applyParams(ret.params)
90
- self._log.debug("<-- %s::mkTask" % self.name)
91
-
92
- return ret
93
-
94
- def applyParams(self, params):
95
- self._log.debug("--> %s::applyParams: %s %s" % (self.name, str(type(self.params)), str(type(params))))
96
- if self.params is not None:
97
- for k,v in self.params.items():
98
- self._log.debug(" change %s %s=>%s" % (
99
- k,
100
- str(getattr(params, k)),
101
- str(v)))
102
- setattr(params, k, v)
103
- else:
104
- self._log.debug(" no params")
105
- self._log.debug("<-- %s::applyParams: %s" % (self.name, str(self.params)))
57
+ # self.applyParams(ret.params)
58
+ # self._log.debug("<-- %s::mkTask" % self.name)
106
59
 
107
- @dc.dataclass
108
- class TaskCtorParamCls(TaskCtor):
109
- params_ctor : Callable = None
60
+ # return ret
110
61
 
111
- _log : ClassVar = logging.getLogger("TaskCtorParamType")
62
+ # def applyParams(self, params):
63
+ # self._log.debug("--> %s::applyParams: %s %s" % (self.name, str(type(self.params)), str(type(params))))
64
+ # if self.params is not None:
65
+ # for k,v in self.params.items():
66
+ # self._log.debug(" change %s %s=>%s" % (
67
+ # k,
68
+ # str(getattr(params, k)),
69
+ # str(v)))
70
+ # setattr(params, k, v)
71
+ # else:
72
+ # self._log.debug(" no params")
73
+ # self._log.debug("<-- %s::applyParams: %s" % (self.name, str(self.params)))
112
74
 
113
- def mkParams(self):
114
- self._log.debug("--> %s::mkParams" % str(self.name))
115
- params = self.params_ctor()
116
- self._log.debug("<-- %s::mkParams: %s" % (str(self.name), str(type(params))))
117
- return params
75
+ # @dc.dataclass
76
+ # class TaskCtorParamCls(TaskCtor):
77
+ # params_ctor : Callable = None
118
78
 
119
- @dc.dataclass
120
- class TaskCtorCls(TaskCtor):
121
- task_ctor : Callable = None
79
+ # _log : ClassVar = logging.getLogger("TaskCtorParamType")
122
80
 
123
- _log : ClassVar = logging.getLogger("TaskCtorCls")
81
+ # def mkParams(self):
82
+ # self._log.debug("--> %s::mkParams" % str(self.name))
83
+ # params = self.params_ctor()
84
+ # self._log.debug("<-- %s::mkParams: %s" % (str(self.name), str(type(params))))
85
+ # return params
124
86
 
125
- def mkTask(self, name : str, depends, rundir, srcdir=None, params=None):
126
- self._log.debug("--> %s::mkTask (%s) srcdir=%s" % (self.name, str(self.task_ctor), srcdir))
87
+ # @dc.dataclass
88
+ # class TaskCtorCls(TaskCtor):
89
+ # task_ctor : Callable = None
127
90
 
128
- if srcdir is None:
129
- srcdir = self.srcdir
91
+ # _log : ClassVar = logging.getLogger("TaskCtorCls")
130
92
 
131
- if params is None:
132
- params = self.mkParams()
93
+ # def mkTask(self, name : str, depends, rundir, srcdir=None, params=None):
94
+ # self._log.debug("--> %s::mkTask (%s) srcdir=%s" % (self.name, str(self.task_ctor), srcdir))
133
95
 
134
- ret = self.task_ctor(
135
- name=name,
136
- depends=depends,
137
- rundir=rundir,
138
- srcdir=srcdir,
139
- params=params)
96
+ # if srcdir is None:
97
+ # srcdir = self.srcdir
140
98
 
141
- # Update parameters on the way back
142
- self.applyParams(ret.params)
99
+ # if params is None:
100
+ # params = self.mkParams()
143
101
 
144
- self._log.debug("<-- %s::mkTask" % self.name)
145
- return ret
102
+ # ret = self.task_ctor(
103
+ # name=name,
104
+ # depends=depends,
105
+ # rundir=rundir,
106
+ # srcdir=srcdir,
107
+ # params=params)
146
108
 
147
- @dc.dataclass
148
- class TaskCtorProxy(TaskCtor):
149
- task_ctor : TaskCtor = None
150
- param_ctor : Callable = None
109
+ # # Update parameters on the way back
110
+ # self.applyParams(ret.params)
111
+
112
+ # self._log.debug("<-- %s::mkTask" % self.name)
113
+ # return ret
151
114
 
152
- _log : ClassVar = logging.getLogger("TaskCtorProxy")
115
+ # @dc.dataclass
116
+ # class TaskCtorProxy(TaskCtor):
117
+ # task_ctor : TaskCtor = None
118
+ # param_ctor : Callable = None
153
119
 
154
- def mkTask(self, *args, **kwargs):
155
- self._log.debug("--> %s::mkTask" % self.name)
156
- ret = self.task_ctor.mkTask(*args, **kwargs)
157
- self._log.debug("<-- %s::mkTask" % self.name)
158
- return ret
120
+ # _log : ClassVar = logging.getLogger("TaskCtorProxy")
159
121
 
160
- def mkParams(self, params=None):
161
- self._log.debug("--> %s::mkParams: %s" % (self.name, str(self.params)))
122
+ # def mkTask(self, *args, **kwargs):
123
+ # self._log.debug("--> %s::mkTask" % self.name)
124
+ # ret = self.task_ctor.mkTask(*args, **kwargs)
125
+ # self._log.debug("<-- %s::mkTask" % self.name)
126
+ # return ret
162
127
 
163
- if params is None and self.param_ctor is not None:
164
- params = self.param_ctor()
128
+ # def mkParams(self, params=None):
129
+ # self._log.debug("--> %s::mkParams: %s" % (self.name, str(self.params)))
165
130
 
166
- params = self.task_ctor.mkParams(params)
131
+ # if params is None and self.param_ctor is not None:
132
+ # params = self.param_ctor()
167
133
 
168
- if self.params is not None:
169
- for k,v in self.params.items():
170
- self._log.debug(" change %s %s=>%s" % (
171
- k,
172
- str(getattr(params, k)),
173
- str(v)))
174
- setattr(params, k, v)
175
- self._log.debug("<-- %s::mkParams: %s" % (self.name, str(self.params)))
176
- return params
134
+ # params = self.task_ctor.mkParams(params)
135
+
136
+ # if self.params is not None:
137
+ # for k,v in self.params.items():
138
+ # self._log.debug(" change %s %s=>%s" % (
139
+ # k,
140
+ # str(getattr(params, k)),
141
+ # str(v)))
142
+ # setattr(params, k, v)
143
+ # self._log.debug("<-- %s::mkParams: %s" % (self.name, str(self.params)))
144
+ # return params
177
145
 
178
146
 
179
147
  @dc.dataclass
180
148
  class Task(object):
181
149
  """Executable view of a task"""
150
+ # Ctor fields -- must specify on construction
182
151
  name : str
183
- params : TaskParams
184
- srcdir : str = None
185
- session : 'TaskGraphRunner' = None
186
- basedir : str = None
187
- memento : TaskMemento = None
188
- depends : List['Task'] = dc.field(default_factory=list)
189
- output : Any = None
190
-
191
- # Implementation data below
192
- basedir : str = dc.field(default=None)
152
+ srcdir : str
153
+ params : TaskParamsCtor
154
+
155
+ # Runtime fields -- these get populated during execution
156
+ changed : bool = False
157
+ needs : List['Task'] = dc.field(default_factory=list)
158
+ dependents : List['Task'] = dc.field(default_factory=list)
193
159
  rundir : str = dc.field(default=None)
194
- impl : str = None
195
- body: Dict[str,Any] = dc.field(default_factory=dict)
196
- impl_t : Any = None
160
+ output : TaskDataOutput = dc.field(default=None)
197
161
 
198
162
  _log : ClassVar = logging.getLogger("Task")
199
163
 
200
- def init(self, runner, basedir):
201
- self.session = runner
202
- self.basedir = basedir
203
-
204
- def getMemento(self, T) -> TaskMemento:
205
- if os.path.isfile(os.path.join(self.rundir, "memento.json")):
206
- with open(os.path.join(self.rundir, "memento.json"), "r") as fp:
207
- try:
208
- data = json.load(fp)
209
- self.memento = T(**data)
210
- except Exception as e:
211
- self._log.critical("Failed to load memento %s: %s" % (
212
- os.path.join(self.rundir, "memento.json"), str(e)))
213
- os.unlink(os.path.join(self.rundir, "memento.json"))
214
- return self.memento
215
-
216
- def setMemento(self, memento : TaskMemento):
217
- self.memento = memento
218
-
219
- async def isUpToDate(self, memento) -> bool:
220
- return False
221
-
222
- async def do_run(self, session) -> TaskData:
223
- self._log.info("--> %s (%s) do_run - %d depends" % (
224
- self.name,
225
- str(type(self)),
226
- len(self.depends)))
227
-
228
- self.session = session
229
-
230
- if len(self.depends) > 0:
231
- deps_o = []
232
- for d in self.depends:
233
- dep_o = d.getOutput()
234
- if dep_o is None:
235
- raise Exception("Null output for %s" % d.name)
236
- deps_o.append(dep_o)
237
-
238
- input = TaskData.merge(deps_o)
239
- input.src = self.name
240
- input.deps[self.name] = list(inp.name for inp in self.depends)
241
- else:
242
- input = TaskData()
243
-
244
-
245
- # Mark the source of this data as being this task
246
- input.src = self.name
247
-
248
- self.init_rundir()
249
-
250
- self.output = await self.run(input)
251
-
252
- if self.output is None:
253
- raise Exception("No output produced by %s" % self.name)
254
- result = TaskData()
255
-
256
- # Write-back the memento, if specified
257
- self.save_memento()
258
-
259
- # Combine data from the deps to produce a result
260
- self._log.info("<-- %s (%s) do_run - %d depends" % (
261
- self.name,
262
- str(type(self)),
263
- len(self.depends)))
264
- return self.output
265
-
266
- async def run(self, input : TaskData) -> TaskData:
164
+ async def run(self,
165
+ runner : 'TaskRunner',
166
+ input : TaskDataInput) -> TaskDataResult:
267
167
  raise NotImplementedError("TaskImpl.run() not implemented")
268
168
 
269
- def init_rundir(self):
270
- if not os.path.isdir(self.rundir):
271
- os.makedirs(self.rundir)
272
-
273
- def save_memento(self):
274
- if self.memento is not None:
275
- with open(os.path.join(self.rundir, "memento.json"), "w") as fp:
276
- fp.write(self.memento.model_dump_json(indent=2))
277
-
278
- def getOutput(self) -> TaskData:
279
- return self.output
280
-
281
- def getField(self, name : str) -> Any:
282
- if name in self.__dict__.keys():
283
- return self.__dict__[name]
284
- elif name in self.__pydantic_extra__.keys():
285
- return self.__pydantic_extra__[name]
286
- else:
287
- raise Exception("No such field %s" % name)
288
-
289
-
290
-
169
+ @staticmethod
170
+ def ctor(paramT):
171
+ def wrapper(T):
172
+ def mk_task(name, srcdir, params):
173
+ return T(name, srcdir, params)
174
+ def mk_params(**params):
175
+ ctor = TaskParamsCtor(paramT)
176
+ ctor.values.append(paramT(**params))
177
+ return ctor
178
+ T.mkTask = mk_task
179
+ T.mkParams = mk_params
180
+ return T
181
+ return wrapper
291
182
 
@@ -0,0 +1,43 @@
1
+ import os
2
+ import json
3
+ import dataclasses as dc
4
+ import logging
5
+ from pydantic import BaseModel
6
+ from typing import Any, Callable, ClassVar, Dict, List, Tuple
7
+ from .task_data import TaskDataOutput, TaskDataResult
8
+
9
+ # TaskParamsCtor accepts an evaluation context and returns a task parameter object
10
+ TaskParamsCtor = Callable[[object], Any]
11
+
12
+ @dc.dataclass
13
+ class TaskCtor(object):
14
+ name : str
15
+ uses : 'TaskCtor' = None
16
+ srcdir : str = None
17
+
18
+ _log : ClassVar = logging.getLogger("TaskCtor")
19
+
20
+ def mkTask(self, name : str, srcdir=None) -> 'Task':
21
+ """Creates a task object"""
22
+ if srcdir is None:
23
+ srcdir = self.srcdir
24
+
25
+ if self.uses is not None:
26
+ return self.uses.mkTask(name, srcdir)
27
+ else:
28
+ raise NotImplementedError("TaskCtor.mkTask() not implemented for %s" % str(type(self)))
29
+
30
+ def mkParams(self, params=None) -> TaskParamsCtor:
31
+ """Creates a list of task-parameter objects used produce the params object"""
32
+ self._log.debug("--> %s::mkParams" % self.name)
33
+ if self.uses is not None:
34
+ params = self.uses.mkParams()
35
+ else:
36
+ params = TaskParams()
37
+ self._log.debug("<-- %s::mkParams: %s" % (self.name, str(params)))
38
+
39
+ return params
40
+
41
+ def applyParams(self, params):
42
+ if self.uses is not None:
43
+ self.uses.applyParams(params)
dv_flow/mgr/task_data.py CHANGED
@@ -27,6 +27,34 @@ from typing import Any, ClassVar, Dict, Set, List, Tuple
27
27
  from .fileset import FileSet
28
28
  from toposort import toposort
29
29
 
30
+ class TaskMarkerLoc(BaseModel):
31
+ path : str
32
+ line : int = dc.Field(default=-1)
33
+ pos : int = dc.Field(default=-1)
34
+
35
+ class TaskMarker(BaseModel):
36
+ msg : str
37
+ severity : str
38
+ loc : TaskMarkerLoc = dc.Field(default=None)
39
+
40
+ class TaskDataInput(BaseModel):
41
+ changed : bool
42
+ srcdir : str
43
+ rundir : str
44
+ params : Any
45
+ memento : Any
46
+
47
+ class TaskDataResult(BaseModel):
48
+ changed : bool = dc.Field(default=True)
49
+ output : List[Any] = dc.Field(default_factory=list)
50
+ memento : Any = dc.Field(default=None)
51
+ markers : List[TaskMarker] = dc.Field(default_factory=list)
52
+ status : int = dc.Field(default=0)
53
+
54
+ class TaskDataOutput(BaseModel):
55
+ changed : bool
56
+ output : List[Any]
57
+
30
58
  class TaskDataParamOpE(enum.Enum):
31
59
  Set = enum.auto()
32
60
  Append = enum.auto()
dv_flow/mgr/task_def.py CHANGED
@@ -40,7 +40,7 @@ class TaskDef(BaseModel):
40
40
  doc : str = dc.Field(default="")
41
41
  depends : List[Union[str,TaskSpec]] = dc.Field(default_factory=list, alias="needs")
42
42
  params: List[ParamDef] = dc.Field(default_factory=list, alias="with")
43
- out: List[TaskOutput] = dc.Field(default_factory=list)
43
+ # out: List[TaskOutput] = dc.Field(default_factory=list)
44
44
 
45
45
  def copy(self) -> 'TaskDef':
46
46
  ret = TaskDef(
@@ -0,0 +1,22 @@
1
+ import pydantic.dataclasses as dc
2
+ from pydantic import BaseModel
3
+ from typing import Any, Dict, List
4
+
5
+
6
+ class TaskExecData(BaseModel):
7
+ """Data from a single exection of a task"""
8
+ name : str
9
+ start : str
10
+ finish : str
11
+ status : int
12
+ memento : Any
13
+ markers : List[Any]
14
+
15
+ class FlowExecData(BaseModel):
16
+ """
17
+ Data from multiple tasks executions. 'info' holds information
18
+ across multiple flow invocations. 'tasks' holds the names of
19
+ tasks executed in the most-recent invocation.
20
+ """
21
+ info : Dict[str, TaskExecData] = dc.Field(default_factory=dict)
22
+ tasks : List[str] = dc.Field(default_factory=list)
@@ -25,7 +25,7 @@ import logging
25
25
  from .package import Package
26
26
  from .package_def import PackageDef, PackageSpec
27
27
  from .pkg_rgy import PkgRgy
28
- from .task import Task, TaskCtor, TaskSpec
28
+ from .task import Task
29
29
  from typing import Dict, List
30
30
 
31
31
  @dc.dataclass
@@ -37,7 +37,7 @@ class TaskGraphBuilder(object):
37
37
  _pkg_s : List[Package] = dc.field(default_factory=list)
38
38
  _pkg_m : Dict[PackageSpec,Package] = dc.field(default_factory=dict)
39
39
  _pkg_spec_s : List[PackageDef] = dc.field(default_factory=list)
40
- _task_m : Dict[TaskSpec,Task] = dc.field(default_factory=dict)
40
+ _task_m : Dict['TaskSpec',Task] = dc.field(default_factory=dict)
41
41
  _logger : logging.Logger = None
42
42
 
43
43
  def __post_init__(self):
@@ -173,7 +173,7 @@ class TaskGraphBuilder(object):
173
173
 
174
174
  return pkg
175
175
 
176
- def getTaskCtor(self, spec : TaskSpec, pkg : PackageDef = None) -> 'TaskCtor':
176
+ def getTaskCtor(self, spec : 'TaskSpec', pkg : PackageDef = None) -> 'TaskCtor':
177
177
  self._logger.debug("--> getTaskCtor %s" % spec.name)
178
178
  spec_e = spec.name.split(".")
179
179
  task_name = spec_e[-1]
@@ -21,20 +21,19 @@
21
21
  #****************************************************************************
22
22
  import asyncio
23
23
  import os
24
- import yaml
25
24
  import dataclasses as dc
26
- from typing import Any, Callable, ClassVar, Dict, List
25
+ from typing import Any, Callable, ClassVar, Dict, List, Tuple
27
26
  from .task import Task
28
27
  from .task_data import TaskData
28
+ from .task_runner import TaskRunner
29
29
 
30
30
  @dc.dataclass
31
- class TaskGraphRunner(object):
31
+ class TaskGraphRunner(TaskRunner):
32
32
  """Session manages execution of a task graph"""
33
33
 
34
- rundir : str
35
-
36
34
  _inst : ClassVar['TaskGraphRunner'] = None
37
35
 
36
+
38
37
  # Search path for .dfs files
39
38
  create_subprocess : Callable = asyncio.create_subprocess_exec
40
39
  _root_dir : str = None
@@ -30,7 +30,7 @@ from .fragment_def import FragmentDef
30
30
  from .package import Package
31
31
  from .pkg_rgy import PkgRgy
32
32
  from .package_def import PackageDef, PackageSpec
33
- from .task import Task, TaskSpec, TaskCtor
33
+ from .task import Task
34
34
  from .task_data import TaskData
35
35
  from .task_graph_runner import TaskGraphRunner
36
36
 
@@ -0,0 +1,31 @@
1
+ import dataclasses as dc
2
+ from typing import Any, List
3
+
4
+
5
+ @dc.dataclass
6
+ class TaskParamsCtor(object):
7
+
8
+ paramT : Any = None
9
+ # List of parameter-setting sets, starting with inner-most
10
+ values : List[Any] = dc.field(default_factory=list)
11
+
12
+ def mk(self, input) -> Any:
13
+ params = self.paramT()
14
+
15
+ # Now, process each field
16
+ for field in dc.fields(self.paramT):
17
+ # Find the outer-most setting of the value
18
+ last_value_i = -1
19
+ for i in range(len(self.values)-1, -1, -1):
20
+ if hasattr(self.values[i], field.name) and getattr(self.values[i], field.name) is not None:
21
+ val = getattr(self.values[i], field.name)
22
+ # TODO: check if 'val' is a set or mutator
23
+ last_value_i = i
24
+ break
25
+ for i in range(last_value_i, -1, -1):
26
+ if hasattr(self.values[i], field.name):
27
+ val = getattr(self.values[i], field.name)
28
+ setattr(params, field.name, val)
29
+
30
+ print("params: %s" % str(params))
31
+ return params
@@ -0,0 +1,46 @@
1
+ import dataclasses as dc
2
+ from .task_data import TaskDataInput, TaskDataResult
3
+ from typing import Any, Callable, List, Tuple
4
+
5
+ @dc.dataclass
6
+ class TaskRunner(object):
7
+ rundir : str
8
+
9
+ # List of [Listener:Callable[Task],Recurisve:bool]
10
+ listeners : List[Tuple[Callable['Task','Reason'], bool]] = dc.field(default_factory=list)
11
+
12
+ async def do_run(self,
13
+ task : 'Task',
14
+ memento : Any = None) -> 'TaskDataResult':
15
+ return await self.run(task, memento)
16
+
17
+ async def run(self,
18
+ task : 'Task',
19
+ memento : Any = None) -> 'TaskDataResult':
20
+ pass
21
+
22
+ @dc.dataclass
23
+ class SingleTaskRunner(TaskRunner):
24
+
25
+ async def run(self,
26
+ task : 'Task',
27
+ memento : Any = None) -> 'TaskDataResult':
28
+ changed = False
29
+ for dep in task.needs:
30
+ changed |= dep.changed
31
+
32
+ # TODO: create an evaluator for substituting param values
33
+ eval = None
34
+
35
+ params = task.params.mk(eval)
36
+
37
+ input = TaskDataInput(
38
+ changed=changed,
39
+ srcdir=task.srcdir,
40
+ rundir=self.rundir,
41
+ params=params,
42
+ memento=memento)
43
+
44
+ ret = await task.run(self, input)
45
+
46
+ return ret
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dv-flow-mgr
3
- Version: 0.0.1.13335470340a1
3
+ Version: 0.0.1.13478128278a1
4
4
  Summary: DV Flow Manager is a build system for silicon design
5
5
  Author-email: Matthew Ballance <matt.ballance@gmail.com>
6
6
  License: Apache License
@@ -1,23 +1,29 @@
1
1
  dv_flow/mgr/__init__.py,sha256=IZA7I1u7RH34DrJXSkETxWFpK5Jn_A2zXfnCAzJ8XxA,289
2
2
  dv_flow/mgr/__main__.py,sha256=uik6gDAvtZNG0yyDKYc4FTl6R1QHAR543jNG2lCAa6E,1771
3
- dv_flow/mgr/expr_parser.py,sha256=4gVpWvBWkI6KfTN2PAXhZtAgKIRLxfFs5Gc5IAa27Dg,605
3
+ dv_flow/mgr/expr_eval.py,sha256=pfnTDurXPTURgpdzlno5XtXlkoPfnJmAAq45G9T2D3k,1517
4
+ dv_flow/mgr/expr_parser.py,sha256=aR8n6hgk5xmFknIaSVC02K-So-eU4pkkFtwb7zWsSPs,5474
4
5
  dv_flow/mgr/fileset.py,sha256=FNvC5sU2ArxJ0OO3v8dXTv8zX-bZ5t0a0ljne0fQQ1o,1150
5
6
  dv_flow/mgr/fragment_def.py,sha256=cyzp1XeWtNOaagScmeS-BPsoXj9j2LTBbKq5ZUioz8I,1641
6
7
  dv_flow/mgr/out,sha256=d8GGBi3J43fhdLBlnsUbzBfRe0TD0QTP3nOTz54l2bI,200
7
- dv_flow/mgr/package.py,sha256=MDnt9q4pD_Aex_hSK_EUQ38IiaxOihgxbMmk5dH1deQ,1674
8
- dv_flow/mgr/package_def.py,sha256=Sv3KS5pDysUrtPBWElCvmWt2pnkTipZcZGYwKr5N7Mc,14967
8
+ dv_flow/mgr/package.py,sha256=878twhPD-E1pFlDNUtuyeFEgJ_Y89b560og4St-Iwrs,1679
9
+ dv_flow/mgr/package_def.py,sha256=dwvs-7kGEp7wFrBK2Fybysb-vSKwtWOtxTrg1VIaL14,14975
9
10
  dv_flow/mgr/package_import_spec.py,sha256=ah3r15v5Jdub2poc3sgi6Uar1L3oGoYsCPPNiOHV-a4,1760
10
11
  dv_flow/mgr/param_def.py,sha256=e2WvRCMArbgcsKC4TKQqZTscZmCdo3WvVR6w3LN0VK8,727
12
+ dv_flow/mgr/parsetab.py,sha256=enSOnMQ-woIsMEzHyeYiefvhAl8enxfX9Ct_o8-jkqs,3780
11
13
  dv_flow/mgr/pkg_rgy.py,sha256=2R_EaeBDJn5qUq9DzSnLc37wUP36MWSv-p0LgUjJRAg,4471
12
- dv_flow/mgr/task.py,sha256=giy5elwIS_fab6wGnA8JCeZIEeX0nG5zpcq5ifGYSOs,9087
13
- dv_flow/mgr/task_data.py,sha256=ZKoYUhXGyLXXm4GvpS-UDwJ_lZH72lgpzOdHm1XDObY,10386
14
- dv_flow/mgr/task_def.py,sha256=6qDDgge5RXssL5TAZR01dGb_Vjvbj72tJirg66O-Yt4,1818
15
- dv_flow/mgr/task_graph_builder.py,sha256=4dfy_T26MYI7ls2xiofr4V0ItZHDehU2iw6UBPt-SZQ,7074
16
- dv_flow/mgr/task_graph_runner.py,sha256=NwNYcOJ952lPMLwIIlYE9CoDdedqvcw2fWHYUsKFXuU,2164
17
- dv_flow/mgr/task_graph_runner_local.py,sha256=66JYJcu-W60LjfuT9UkbcKslNqDcD5q4UR7ZAWrSaGM,4707
14
+ dv_flow/mgr/task.py,sha256=kLQSvnVwj9ROIDtxq8lLu-4mJizTxOqvUeogmgN6QAA,5976
15
+ dv_flow/mgr/task_ctor.py,sha256=hlfl-UVvyjzLFN6D0Oel9eBs0xUQPqCX7gQ0uEHoL7o,1382
16
+ dv_flow/mgr/task_data.py,sha256=fkaVzQ81nJBXy4uPWPdnVCNoD9L7rvH5Abt8LXzvnJs,11098
17
+ dv_flow/mgr/task_def.py,sha256=WAW1fPXUfUiQcfmgCx0iCMddMBKATDa5RsRztJWRbUk,1819
18
+ dv_flow/mgr/task_exec_data.py,sha256=aT__kmVmNxqnS_GbTRS1vrYgKiv8cH-HUSmRb6YYKsI,640
19
+ dv_flow/mgr/task_graph_builder.py,sha256=-lRSjWU2UJf3euVIFtoVIU7Qdox7MI1sKERWg1k7U_g,7058
20
+ dv_flow/mgr/task_graph_runner.py,sha256=jUGI49QvxUCfQoKQDDk2psbeapIcCg72qNOW1JipHzM,2182
21
+ dv_flow/mgr/task_graph_runner_local.py,sha256=OrydPwtQ8E7hYWvSXx0h7lI3nfUNFyklULhsyMwz9dA,4687
18
22
  dv_flow/mgr/task_impl_data.py,sha256=bFPijoKrh9x7fZN2DsvRJp0UHo-gGM0VjtDQISyfhFk,321
19
23
  dv_flow/mgr/task_memento.py,sha256=C7VTQpBhDEoYuDmE6YTM-6TLMLnqHp6Y0Vat1aTgtCs,1096
20
24
  dv_flow/mgr/task_output.py,sha256=l-W-FvVo6YDah1RQS-I9N0KUtB3vp-kl7lxIdmNz0l4,178
25
+ dv_flow/mgr/task_params_ctor.py,sha256=aXgB8o9xFPjaEjGW_xYkEC0N0apzGzGUPDj7g2ZLvus,1112
26
+ dv_flow/mgr/task_runner.py,sha256=XrVYZ13qIbGDkLgDT-NAq_qd2plCqVjHKEe25MD-7xE,1272
21
27
  dv_flow/mgr/type.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
28
  dv_flow/mgr/type_def.py,sha256=KdhuNlfw-NKU-4VZFCnMPyj775yEB7cpr5tz73a9yuQ,259
23
29
  dv_flow/mgr/util.py,sha256=06eVyURF4ga-s8C9Sd3ZSDebwO4QS0XXaB8xADVbWRc,1437
@@ -27,9 +33,9 @@ dv_flow/mgr/std/fileset.py,sha256=uP7bGntRq-Tn5_GEFnt0_J_OAmfvep3GlCwCuE8by4o,27
27
33
  dv_flow/mgr/std/flow.dv,sha256=j9wLrF3Ghh1ZLbJxmk7WiNiRYUYEer-8CCUA5hsgtfk,1409
28
34
  dv_flow/mgr/std/message.py,sha256=BPTHnEMD4tBufQ9LvsS9Sa_0xjaJATbBpwqosWslvVA,193
29
35
  dv_flow/mgr/std/task_null.py,sha256=KObmjG_4D08GJ1k6neqKIQrFY72Sj0jLnwXxEkq5HA0,321
30
- dv_flow_mgr-0.0.1.13335470340a1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
31
- dv_flow_mgr-0.0.1.13335470340a1.dist-info/METADATA,sha256=NP0fraxF2IX1pTGM8-F-suzwkkbWU09BFex8ktZSVc8,13276
32
- dv_flow_mgr-0.0.1.13335470340a1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
33
- dv_flow_mgr-0.0.1.13335470340a1.dist-info/entry_points.txt,sha256=1roy8wAFM48LabOvr6jiOw0MUs-qE8X3Vf8YykPazxk,50
34
- dv_flow_mgr-0.0.1.13335470340a1.dist-info/top_level.txt,sha256=amfVTkggzYPtWwLqNmRukfz1Buu0pGS2SrYBBLhXm04,8
35
- dv_flow_mgr-0.0.1.13335470340a1.dist-info/RECORD,,
36
+ dv_flow_mgr-0.0.1.13478128278a1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
37
+ dv_flow_mgr-0.0.1.13478128278a1.dist-info/METADATA,sha256=HCQCME5rxfNs5HNZ0WmoQtIQMTWNtZzkGrfwhXoO09I,13276
38
+ dv_flow_mgr-0.0.1.13478128278a1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
39
+ dv_flow_mgr-0.0.1.13478128278a1.dist-info/entry_points.txt,sha256=1roy8wAFM48LabOvr6jiOw0MUs-qE8X3Vf8YykPazxk,50
40
+ dv_flow_mgr-0.0.1.13478128278a1.dist-info/top_level.txt,sha256=amfVTkggzYPtWwLqNmRukfz1Buu0pGS2SrYBBLhXm04,8
41
+ dv_flow_mgr-0.0.1.13478128278a1.dist-info/RECORD,,