synapse 2.192.0__py311-none-any.whl → 2.194.0__py311-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.
Potentially problematic release.
This version of synapse might be problematic. Click here for more details.
- synapse/common.py +15 -0
- synapse/cortex.py +19 -25
- synapse/datamodel.py +6 -3
- synapse/exc.py +6 -1
- synapse/lib/agenda.py +17 -6
- synapse/lib/ast.py +242 -97
- synapse/lib/auth.py +1 -0
- synapse/lib/cell.py +31 -85
- synapse/lib/cli.py +20 -11
- synapse/lib/parser.py +5 -1
- synapse/lib/snap.py +44 -15
- synapse/lib/storm.lark +16 -1
- synapse/lib/storm.py +40 -21
- synapse/lib/storm_format.py +1 -0
- synapse/lib/stormctrl.py +88 -6
- synapse/lib/stormlib/cache.py +6 -2
- synapse/lib/stormlib/json.py +5 -2
- synapse/lib/stormlib/scrape.py +1 -1
- synapse/lib/stormlib/stix.py +8 -8
- synapse/lib/stormtypes.py +32 -5
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +20 -3
- synapse/models/geopol.py +1 -0
- synapse/models/geospace.py +1 -0
- synapse/models/inet.py +20 -1
- synapse/models/infotech.py +24 -6
- synapse/models/orgs.py +7 -2
- synapse/models/person.py +15 -4
- synapse/models/risk.py +19 -2
- synapse/models/telco.py +10 -3
- synapse/tests/test_axon.py +6 -6
- synapse/tests/test_cortex.py +133 -14
- synapse/tests/test_exc.py +4 -0
- synapse/tests/test_lib_agenda.py +282 -2
- synapse/tests/test_lib_aha.py +13 -6
- synapse/tests/test_lib_ast.py +301 -10
- synapse/tests/test_lib_auth.py +6 -7
- synapse/tests/test_lib_cell.py +71 -1
- synapse/tests/test_lib_grammar.py +14 -0
- synapse/tests/test_lib_layer.py +1 -1
- synapse/tests/test_lib_lmdbslab.py +3 -3
- synapse/tests/test_lib_storm.py +273 -55
- synapse/tests/test_lib_stormctrl.py +65 -0
- synapse/tests/test_lib_stormhttp.py +5 -5
- synapse/tests/test_lib_stormlib_auth.py +5 -5
- synapse/tests/test_lib_stormlib_cache.py +38 -6
- synapse/tests/test_lib_stormlib_json.py +20 -0
- synapse/tests/test_lib_stormlib_modelext.py +3 -3
- synapse/tests/test_lib_stormlib_scrape.py +6 -6
- synapse/tests/test_lib_stormlib_spooled.py +1 -1
- synapse/tests/test_lib_stormlib_xml.py +5 -5
- synapse/tests/test_lib_stormtypes.py +54 -57
- synapse/tests/test_lib_view.py +1 -1
- synapse/tests/test_model_base.py +1 -2
- synapse/tests/test_model_geopol.py +4 -0
- synapse/tests/test_model_geospace.py +6 -0
- synapse/tests/test_model_inet.py +43 -5
- synapse/tests/test_model_infotech.py +10 -1
- synapse/tests/test_model_orgs.py +17 -2
- synapse/tests/test_model_person.py +23 -1
- synapse/tests/test_model_risk.py +13 -0
- synapse/tests/test_tools_healthcheck.py +4 -4
- synapse/tests/test_tools_storm.py +95 -0
- synapse/tests/test_utils.py +17 -18
- synapse/tests/test_utils_getrefs.py +1 -1
- synapse/tests/utils.py +0 -35
- synapse/tools/changelog.py +6 -4
- synapse/tools/storm.py +1 -1
- synapse/utils/getrefs.py +14 -3
- synapse/vendor/cpython/lib/http/__init__.py +0 -0
- synapse/vendor/cpython/lib/http/cookies.py +59 -0
- synapse/vendor/cpython/lib/test/test_http_cookies.py +49 -0
- {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/METADATA +6 -6
- {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/RECORD +77 -73
- {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/WHEEL +1 -1
- {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/LICENSE +0 -0
- {synapse-2.192.0.dist-info → synapse-2.194.0.dist-info}/top_level.txt +0 -0
synapse/lib/ast.py
CHANGED
|
@@ -28,6 +28,16 @@ import synapse.lib.stormtypes as s_stormtypes
|
|
|
28
28
|
|
|
29
29
|
from synapse.lib.stormtypes import tobool, toint, toprim, tostr, tonumber, tocmprvalu, undef
|
|
30
30
|
|
|
31
|
+
SET_ALWAYS = 0
|
|
32
|
+
SET_UNSET = 1
|
|
33
|
+
SET_NEVER = 2
|
|
34
|
+
|
|
35
|
+
COND_EDIT_SET = {
|
|
36
|
+
'always': SET_ALWAYS,
|
|
37
|
+
'unset': SET_UNSET,
|
|
38
|
+
'never': SET_NEVER,
|
|
39
|
+
}
|
|
40
|
+
|
|
31
41
|
logger = logging.getLogger(__name__)
|
|
32
42
|
|
|
33
43
|
def parseNumber(x):
|
|
@@ -60,7 +70,7 @@ class AstNode:
|
|
|
60
70
|
|
|
61
71
|
def addExcInfo(self, exc):
|
|
62
72
|
if 'highlight' not in exc.errinfo:
|
|
63
|
-
exc.
|
|
73
|
+
exc.set('highlight', self.getPosInfo())
|
|
64
74
|
return exc
|
|
65
75
|
|
|
66
76
|
def repr(self):
|
|
@@ -124,27 +134,27 @@ class AstNode:
|
|
|
124
134
|
pass
|
|
125
135
|
|
|
126
136
|
def hasAstClass(self, clss):
|
|
127
|
-
hasast
|
|
128
|
-
if hasast is not None:
|
|
137
|
+
if (hasast := self.hasast.get(clss)) is not None:
|
|
129
138
|
return hasast
|
|
130
139
|
|
|
131
|
-
retn =
|
|
140
|
+
retn = self._hasAstClass(clss)
|
|
141
|
+
self.hasast[clss] = retn
|
|
142
|
+
return retn
|
|
143
|
+
|
|
144
|
+
def _hasAstClass(self, clss):
|
|
132
145
|
|
|
133
146
|
for kid in self.kids:
|
|
134
147
|
|
|
135
148
|
if isinstance(kid, clss):
|
|
136
|
-
|
|
137
|
-
break
|
|
149
|
+
return True
|
|
138
150
|
|
|
139
|
-
if isinstance(kid, (
|
|
151
|
+
if isinstance(kid, (Edit, Function, CmdOper, SetVarOper, SetItemOper, VarListSetOper, Value, N1Walk, LiftOper)):
|
|
140
152
|
continue
|
|
141
153
|
|
|
142
154
|
if kid.hasAstClass(clss):
|
|
143
|
-
|
|
144
|
-
break
|
|
155
|
+
return True
|
|
145
156
|
|
|
146
|
-
|
|
147
|
-
return retn
|
|
157
|
+
return False
|
|
148
158
|
|
|
149
159
|
def optimize(self):
|
|
150
160
|
[k.optimize() for k in self.kids]
|
|
@@ -179,6 +189,12 @@ class AstNode:
|
|
|
179
189
|
|
|
180
190
|
todo.extend(nkid.kids)
|
|
181
191
|
|
|
192
|
+
def reqNotReadOnly(self, runt, mesg=None):
|
|
193
|
+
if runt.readonly:
|
|
194
|
+
if mesg is None:
|
|
195
|
+
mesg = 'Storm runtime is in readonly mode, cannot create or edit nodes and other graph data.'
|
|
196
|
+
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
197
|
+
|
|
182
198
|
def hasVarName(self, name):
|
|
183
199
|
return any(k.hasVarName(name) for k in self.kids)
|
|
184
200
|
|
|
@@ -238,9 +254,8 @@ class Lookup(Query):
|
|
|
238
254
|
|
|
239
255
|
async def run(self, runt, genr):
|
|
240
256
|
|
|
241
|
-
if
|
|
242
|
-
|
|
243
|
-
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
257
|
+
if self.autoadd:
|
|
258
|
+
self.reqNotReadOnly(runt)
|
|
244
259
|
|
|
245
260
|
async def getnode(form, valu):
|
|
246
261
|
try:
|
|
@@ -915,6 +930,9 @@ class TryCatch(AstNode):
|
|
|
915
930
|
|
|
916
931
|
class CatchBlock(AstNode):
|
|
917
932
|
|
|
933
|
+
def _hasAstClass(self, clss):
|
|
934
|
+
return self.kids[1].hasAstClass(clss)
|
|
935
|
+
|
|
918
936
|
async def run(self, runt, genr):
|
|
919
937
|
async for item in self.kids[2].run(runt, genr):
|
|
920
938
|
yield item
|
|
@@ -948,6 +966,9 @@ class CatchBlock(AstNode):
|
|
|
948
966
|
|
|
949
967
|
class ForLoop(Oper):
|
|
950
968
|
|
|
969
|
+
def _hasAstClass(self, clss):
|
|
970
|
+
return self.kids[2].hasAstClass(clss)
|
|
971
|
+
|
|
951
972
|
def getRuntVars(self, runt):
|
|
952
973
|
|
|
953
974
|
runtsafe = self.kids[1].isRuntSafe(runt)
|
|
@@ -983,6 +1004,14 @@ class ForLoop(Oper):
|
|
|
983
1004
|
valu = ()
|
|
984
1005
|
|
|
985
1006
|
async with contextlib.aclosing(s_coro.agen(valu)) as agen:
|
|
1007
|
+
|
|
1008
|
+
try:
|
|
1009
|
+
agen, _ = await pullone(agen)
|
|
1010
|
+
except TypeError:
|
|
1011
|
+
styp = await s_stormtypes.totype(valu, basetypes=True)
|
|
1012
|
+
mesg = f"'{styp}' object is not iterable: {s_common.trimText(repr(valu))}"
|
|
1013
|
+
raise self.kids[1].addExcInfo(s_exc.StormRuntimeError(mesg=mesg, type=styp)) from None
|
|
1014
|
+
|
|
986
1015
|
async for item in agen:
|
|
987
1016
|
|
|
988
1017
|
if isinstance(name, (list, tuple)):
|
|
@@ -1020,13 +1049,13 @@ class ForLoop(Oper):
|
|
|
1020
1049
|
yield item
|
|
1021
1050
|
|
|
1022
1051
|
except s_stormctrl.StormBreak as e:
|
|
1023
|
-
if e.item is not None:
|
|
1024
|
-
yield
|
|
1052
|
+
if (eitem := e.get('item')) is not None:
|
|
1053
|
+
yield eitem
|
|
1025
1054
|
break
|
|
1026
1055
|
|
|
1027
1056
|
except s_stormctrl.StormContinue as e:
|
|
1028
|
-
if e.item is not None:
|
|
1029
|
-
yield
|
|
1057
|
+
if (eitem := e.get('item')) is not None:
|
|
1058
|
+
yield eitem
|
|
1030
1059
|
continue
|
|
1031
1060
|
|
|
1032
1061
|
finally:
|
|
@@ -1049,6 +1078,13 @@ class ForLoop(Oper):
|
|
|
1049
1078
|
valu = ()
|
|
1050
1079
|
|
|
1051
1080
|
async with contextlib.aclosing(s_coro.agen(valu)) as agen:
|
|
1081
|
+
try:
|
|
1082
|
+
agen, _ = await pullone(agen)
|
|
1083
|
+
except TypeError:
|
|
1084
|
+
styp = await s_stormtypes.totype(valu, basetypes=True)
|
|
1085
|
+
mesg = f"'{styp}' object is not iterable: {s_common.trimText(repr(valu))}"
|
|
1086
|
+
raise self.kids[1].addExcInfo(s_exc.StormRuntimeError(mesg=mesg, type=styp)) from None
|
|
1087
|
+
|
|
1052
1088
|
async for item in agen:
|
|
1053
1089
|
|
|
1054
1090
|
if isinstance(name, (list, tuple)):
|
|
@@ -1079,13 +1115,13 @@ class ForLoop(Oper):
|
|
|
1079
1115
|
yield jtem
|
|
1080
1116
|
|
|
1081
1117
|
except s_stormctrl.StormBreak as e:
|
|
1082
|
-
if e.item is not None:
|
|
1083
|
-
yield
|
|
1118
|
+
if (eitem := e.get('item')) is not None:
|
|
1119
|
+
yield eitem
|
|
1084
1120
|
break
|
|
1085
1121
|
|
|
1086
1122
|
except s_stormctrl.StormContinue as e:
|
|
1087
|
-
if e.item is not None:
|
|
1088
|
-
yield
|
|
1123
|
+
if (eitem := e.get('item')) is not None:
|
|
1124
|
+
yield eitem
|
|
1089
1125
|
continue
|
|
1090
1126
|
|
|
1091
1127
|
finally:
|
|
@@ -1094,6 +1130,9 @@ class ForLoop(Oper):
|
|
|
1094
1130
|
|
|
1095
1131
|
class WhileLoop(Oper):
|
|
1096
1132
|
|
|
1133
|
+
def _hasAstClass(self, clss):
|
|
1134
|
+
return self.kids[1].hasAstClass(clss)
|
|
1135
|
+
|
|
1097
1136
|
async def run(self, runt, genr):
|
|
1098
1137
|
subq = self.kids[1]
|
|
1099
1138
|
node = None
|
|
@@ -1109,13 +1148,13 @@ class WhileLoop(Oper):
|
|
|
1109
1148
|
await asyncio.sleep(0)
|
|
1110
1149
|
|
|
1111
1150
|
except s_stormctrl.StormBreak as e:
|
|
1112
|
-
if e.item is not None:
|
|
1113
|
-
yield
|
|
1151
|
+
if (eitem := e.get('item')) is not None:
|
|
1152
|
+
yield eitem
|
|
1114
1153
|
break
|
|
1115
1154
|
|
|
1116
1155
|
except s_stormctrl.StormContinue as e:
|
|
1117
|
-
if e.item is not None:
|
|
1118
|
-
yield
|
|
1156
|
+
if (eitem := e.get('item')) is not None:
|
|
1157
|
+
yield eitem
|
|
1119
1158
|
continue
|
|
1120
1159
|
|
|
1121
1160
|
finally:
|
|
@@ -1133,13 +1172,13 @@ class WhileLoop(Oper):
|
|
|
1133
1172
|
await asyncio.sleep(0)
|
|
1134
1173
|
|
|
1135
1174
|
except s_stormctrl.StormBreak as e:
|
|
1136
|
-
if e.item is not None:
|
|
1137
|
-
yield
|
|
1175
|
+
if (eitem := e.get('item')) is not None:
|
|
1176
|
+
yield eitem
|
|
1138
1177
|
break
|
|
1139
1178
|
|
|
1140
1179
|
except s_stormctrl.StormContinue as e:
|
|
1141
|
-
if e.item is not None:
|
|
1142
|
-
yield
|
|
1180
|
+
if (eitem := e.get('item')) is not None:
|
|
1181
|
+
yield eitem
|
|
1143
1182
|
continue
|
|
1144
1183
|
|
|
1145
1184
|
finally:
|
|
@@ -1147,20 +1186,21 @@ class WhileLoop(Oper):
|
|
|
1147
1186
|
await asyncio.sleep(0)
|
|
1148
1187
|
|
|
1149
1188
|
async def pullone(genr):
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1189
|
+
empty = False
|
|
1190
|
+
try:
|
|
1191
|
+
gotone = await genr.__anext__()
|
|
1192
|
+
except StopAsyncIteration:
|
|
1193
|
+
empty = True
|
|
1153
1194
|
|
|
1154
1195
|
async def pullgenr():
|
|
1155
|
-
|
|
1156
|
-
if gotone is None:
|
|
1196
|
+
if empty:
|
|
1157
1197
|
return
|
|
1158
1198
|
|
|
1159
1199
|
yield gotone
|
|
1160
1200
|
async for item in genr:
|
|
1161
1201
|
yield item
|
|
1162
1202
|
|
|
1163
|
-
return pullgenr(),
|
|
1203
|
+
return pullgenr(), empty
|
|
1164
1204
|
|
|
1165
1205
|
class CmdOper(Oper):
|
|
1166
1206
|
|
|
@@ -1269,15 +1309,17 @@ class SetItemOper(Oper):
|
|
|
1269
1309
|
item = s_stormtypes.fromprim(await self.kids[0].compute(runt, path), basetypes=False)
|
|
1270
1310
|
|
|
1271
1311
|
if runt.readonly and not getattr(item.setitem, '_storm_readonly', False):
|
|
1272
|
-
|
|
1273
|
-
raise self.kids[0].addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
1312
|
+
self.kids[0].reqNotReadOnly(runt)
|
|
1274
1313
|
|
|
1275
1314
|
name = await self.kids[1].compute(runt, path)
|
|
1276
1315
|
valu = await self.kids[2].compute(runt, path)
|
|
1277
1316
|
|
|
1278
1317
|
# TODO: ditch this when storm goes full heavy object
|
|
1279
1318
|
with s_scope.enter({'runt': runt}):
|
|
1280
|
-
|
|
1319
|
+
try:
|
|
1320
|
+
await item.setitem(name, valu)
|
|
1321
|
+
except s_exc.SynErr as e:
|
|
1322
|
+
raise self.kids[0].addExcInfo(e)
|
|
1281
1323
|
|
|
1282
1324
|
yield node, path
|
|
1283
1325
|
|
|
@@ -1289,12 +1331,14 @@ class SetItemOper(Oper):
|
|
|
1289
1331
|
valu = await self.kids[2].compute(runt, None)
|
|
1290
1332
|
|
|
1291
1333
|
if runt.readonly and not getattr(item.setitem, '_storm_readonly', False):
|
|
1292
|
-
|
|
1293
|
-
raise self.kids[0].addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
1334
|
+
self.kids[0].reqNotReadOnly(runt)
|
|
1294
1335
|
|
|
1295
1336
|
# TODO: ditch this when storm goes full heavy object
|
|
1296
1337
|
with s_scope.enter({'runt': runt}):
|
|
1297
|
-
|
|
1338
|
+
try:
|
|
1339
|
+
await item.setitem(name, valu)
|
|
1340
|
+
except s_exc.SynErr as e:
|
|
1341
|
+
raise self.kids[0].addExcInfo(e)
|
|
1298
1342
|
|
|
1299
1343
|
class VarListSetOper(Oper):
|
|
1300
1344
|
|
|
@@ -1366,6 +1410,14 @@ class VarEvalOper(Oper):
|
|
|
1366
1410
|
|
|
1367
1411
|
class SwitchCase(Oper):
|
|
1368
1412
|
|
|
1413
|
+
def _hasAstClass(self, clss):
|
|
1414
|
+
|
|
1415
|
+
for kid in self.kids[1:]:
|
|
1416
|
+
if kid.hasAstClass(clss):
|
|
1417
|
+
return True
|
|
1418
|
+
|
|
1419
|
+
return False
|
|
1420
|
+
|
|
1369
1421
|
def prepare(self):
|
|
1370
1422
|
self.cases = {}
|
|
1371
1423
|
self.defcase = None
|
|
@@ -3572,17 +3624,31 @@ class FuncCall(Value):
|
|
|
3572
3624
|
raise self.addExcInfo(s_exc.StormRuntimeError(mesg=mesg))
|
|
3573
3625
|
|
|
3574
3626
|
if runt.readonly and not getattr(func, '_storm_readonly', False):
|
|
3575
|
-
|
|
3627
|
+
funcname = getattr(func, '_storm_funcpath', func.__name__)
|
|
3628
|
+
mesg = f'{funcname}() is not marked readonly safe.'
|
|
3576
3629
|
raise self.kids[0].addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
3577
3630
|
|
|
3578
3631
|
argv = await self.kids[1].compute(runt, path)
|
|
3579
3632
|
kwargs = {k: v for (k, v) in await self.kids[2].compute(runt, path)}
|
|
3580
3633
|
|
|
3581
3634
|
with s_scope.enter({'runt': runt}):
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3635
|
+
try:
|
|
3636
|
+
retn = func(*argv, **kwargs)
|
|
3637
|
+
if s_coro.iscoro(retn):
|
|
3638
|
+
return await retn
|
|
3639
|
+
return retn
|
|
3640
|
+
|
|
3641
|
+
except TypeError as e:
|
|
3642
|
+
mesg = str(e)
|
|
3643
|
+
if (funcpath := getattr(func, '_storm_funcpath', None)) is not None:
|
|
3644
|
+
mesg = f"{funcpath}(){mesg.split(')', 1)[1]}"
|
|
3645
|
+
|
|
3646
|
+
raise self.addExcInfo(s_exc.StormRuntimeError(mesg=mesg))
|
|
3647
|
+
|
|
3648
|
+
except s_exc.SynErr as e:
|
|
3649
|
+
if getattr(func, '_storm_runtime_lib_func', None) is not None:
|
|
3650
|
+
e.errinfo.pop('highlight', None)
|
|
3651
|
+
raise self.addExcInfo(e)
|
|
3586
3652
|
|
|
3587
3653
|
class DollarExpr(Value):
|
|
3588
3654
|
'''
|
|
@@ -3985,9 +4051,7 @@ class EditParens(Edit):
|
|
|
3985
4051
|
|
|
3986
4052
|
async def run(self, runt, genr):
|
|
3987
4053
|
|
|
3988
|
-
|
|
3989
|
-
mesg = 'Storm runtime is in readonly mode, cannot create or edit nodes and other graph data.'
|
|
3990
|
-
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
4054
|
+
self.reqNotReadOnly(runt)
|
|
3991
4055
|
|
|
3992
4056
|
nodeadd = self.kids[0]
|
|
3993
4057
|
assert isinstance(nodeadd, EditNodeAdd)
|
|
@@ -4080,9 +4144,7 @@ class EditNodeAdd(Edit):
|
|
|
4080
4144
|
# case 2: <query> [ foo:bar=($node, 20) ]
|
|
4081
4145
|
# case 2: <query> $blah=:baz [ foo:bar=($blah, 20) ]
|
|
4082
4146
|
|
|
4083
|
-
|
|
4084
|
-
mesg = 'Storm runtime is in readonly mode, cannot create or edit nodes and other graph data.'
|
|
4085
|
-
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
4147
|
+
self.reqNotReadOnly(runt)
|
|
4086
4148
|
|
|
4087
4149
|
runtsafe = self.isRuntSafe(runt)
|
|
4088
4150
|
|
|
@@ -4090,7 +4152,6 @@ class EditNodeAdd(Edit):
|
|
|
4090
4152
|
|
|
4091
4153
|
if not runtsafe:
|
|
4092
4154
|
|
|
4093
|
-
first = True
|
|
4094
4155
|
async for node, path in genr:
|
|
4095
4156
|
|
|
4096
4157
|
# must reach back first to trigger sudo / etc
|
|
@@ -4148,13 +4209,79 @@ class EditNodeAdd(Edit):
|
|
|
4148
4209
|
async for item in agen:
|
|
4149
4210
|
yield item
|
|
4150
4211
|
|
|
4212
|
+
class CondSetOper(Oper):
|
|
4213
|
+
def __init__(self, astinfo, kids, errok=False):
|
|
4214
|
+
Value.__init__(self, astinfo, kids=kids)
|
|
4215
|
+
self.errok = errok
|
|
4216
|
+
|
|
4217
|
+
def prepare(self):
|
|
4218
|
+
self.isconst = False
|
|
4219
|
+
if isinstance(self.kids[0], Const):
|
|
4220
|
+
self.isconst = True
|
|
4221
|
+
self.valu = COND_EDIT_SET.get(self.kids[0].value())
|
|
4222
|
+
|
|
4223
|
+
async def compute(self, runt, path):
|
|
4224
|
+
if self.isconst:
|
|
4225
|
+
return self.valu
|
|
4226
|
+
|
|
4227
|
+
valu = await self.kids[0].compute(runt, path)
|
|
4228
|
+
if (retn := COND_EDIT_SET.get(valu)) is not None:
|
|
4229
|
+
return retn
|
|
4230
|
+
|
|
4231
|
+
mesg = f'Invalid conditional set operator ({valu}).'
|
|
4232
|
+
exc = s_exc.StormRuntimeError(mesg=mesg)
|
|
4233
|
+
raise self.addExcInfo(exc)
|
|
4234
|
+
|
|
4235
|
+
class EditCondPropSet(Edit):
|
|
4236
|
+
|
|
4237
|
+
async def run(self, runt, genr):
|
|
4238
|
+
|
|
4239
|
+
self.reqNotReadOnly(runt)
|
|
4240
|
+
|
|
4241
|
+
excignore = (s_exc.BadTypeValu,) if self.kids[1].errok else ()
|
|
4242
|
+
rval = self.kids[2]
|
|
4243
|
+
|
|
4244
|
+
async for node, path in genr:
|
|
4245
|
+
|
|
4246
|
+
propname = await self.kids[0].compute(runt, path)
|
|
4247
|
+
name = await tostr(propname)
|
|
4248
|
+
|
|
4249
|
+
prop = node.form.reqProp(name, extra=self.kids[0].addExcInfo)
|
|
4250
|
+
|
|
4251
|
+
oper = await self.kids[1].compute(runt, path)
|
|
4252
|
+
if oper == SET_NEVER or (oper == SET_UNSET and (oldv := node.get(name)) is not None):
|
|
4253
|
+
yield node, path
|
|
4254
|
+
await asyncio.sleep(0)
|
|
4255
|
+
continue
|
|
4256
|
+
|
|
4257
|
+
if not node.form.isrunt:
|
|
4258
|
+
# runt node property permissions are enforced by the callback
|
|
4259
|
+
runt.confirmPropSet(prop)
|
|
4260
|
+
|
|
4261
|
+
isndef = isinstance(prop.type, s_types.Ndef)
|
|
4262
|
+
|
|
4263
|
+
try:
|
|
4264
|
+
valu = await rval.compute(runt, path)
|
|
4265
|
+
valu = await s_stormtypes.tostor(valu, isndef=isndef)
|
|
4266
|
+
|
|
4267
|
+
if isinstance(prop.type, s_types.Ival) and oldv is not None:
|
|
4268
|
+
valu, _ = prop.type.norm(valu)
|
|
4269
|
+
valu = prop.type.merge(oldv, valu)
|
|
4270
|
+
|
|
4271
|
+
await node.set(name, valu)
|
|
4272
|
+
|
|
4273
|
+
except excignore:
|
|
4274
|
+
pass
|
|
4275
|
+
|
|
4276
|
+
yield node, path
|
|
4277
|
+
|
|
4278
|
+
await asyncio.sleep(0)
|
|
4279
|
+
|
|
4151
4280
|
class EditPropSet(Edit):
|
|
4152
4281
|
|
|
4153
4282
|
async def run(self, runt, genr):
|
|
4154
4283
|
|
|
4155
|
-
|
|
4156
|
-
mesg = 'Storm runtime is in readonly mode, cannot create or edit nodes and other graph data.'
|
|
4157
|
-
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
4284
|
+
self.reqNotReadOnly(runt)
|
|
4158
4285
|
|
|
4159
4286
|
oper = await self.kids[1].compute(runt, None)
|
|
4160
4287
|
excignore = (s_exc.BadTypeValu,) if oper in ('?=', '?+=', '?-=') else ()
|
|
@@ -4199,7 +4326,7 @@ class EditPropSet(Edit):
|
|
|
4199
4326
|
|
|
4200
4327
|
if not isarray:
|
|
4201
4328
|
mesg = f'Property set using ({oper}) is only valid on arrays.'
|
|
4202
|
-
exc = s_exc.StormRuntimeError(mesg)
|
|
4329
|
+
exc = s_exc.StormRuntimeError(mesg=mesg)
|
|
4203
4330
|
raise self.kids[0].addExcInfo(exc)
|
|
4204
4331
|
|
|
4205
4332
|
arry = node.get(name)
|
|
@@ -4247,9 +4374,7 @@ class EditPropDel(Edit):
|
|
|
4247
4374
|
|
|
4248
4375
|
async def run(self, runt, genr):
|
|
4249
4376
|
|
|
4250
|
-
|
|
4251
|
-
mesg = 'Storm runtime is in readonly mode, cannot create or edit nodes and other graph data.'
|
|
4252
|
-
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
4377
|
+
self.reqNotReadOnly(runt)
|
|
4253
4378
|
|
|
4254
4379
|
async for node, path in genr:
|
|
4255
4380
|
propname = await self.kids[0].compute(runt, path)
|
|
@@ -4275,9 +4400,7 @@ class EditUnivDel(Edit):
|
|
|
4275
4400
|
|
|
4276
4401
|
async def run(self, runt, genr):
|
|
4277
4402
|
|
|
4278
|
-
|
|
4279
|
-
mesg = 'Storm runtime is in readonly mode, cannot create or edit nodes and other graph data.'
|
|
4280
|
-
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
4403
|
+
self.reqNotReadOnly(runt)
|
|
4281
4404
|
|
|
4282
4405
|
univprop = self.kids[0]
|
|
4283
4406
|
assert isinstance(univprop, UnivProp)
|
|
@@ -4453,9 +4576,7 @@ class EditEdgeAdd(Edit):
|
|
|
4453
4576
|
|
|
4454
4577
|
async def run(self, runt, genr):
|
|
4455
4578
|
|
|
4456
|
-
|
|
4457
|
-
mesg = 'Storm runtime is in readonly mode, cannot create or edit nodes and other graph data.'
|
|
4458
|
-
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
4579
|
+
self.reqNotReadOnly(runt)
|
|
4459
4580
|
|
|
4460
4581
|
# SubQuery -> Query
|
|
4461
4582
|
query = self.kids[1].kids[0]
|
|
@@ -4518,9 +4639,7 @@ class EditEdgeDel(Edit):
|
|
|
4518
4639
|
|
|
4519
4640
|
async def run(self, runt, genr):
|
|
4520
4641
|
|
|
4521
|
-
|
|
4522
|
-
mesg = 'Storm runtime is in readonly mode, cannot create or edit nodes and other graph data.'
|
|
4523
|
-
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
4642
|
+
self.reqNotReadOnly(runt)
|
|
4524
4643
|
|
|
4525
4644
|
query = self.kids[1].kids[0]
|
|
4526
4645
|
|
|
@@ -4576,9 +4695,7 @@ class EditTagAdd(Edit):
|
|
|
4576
4695
|
|
|
4577
4696
|
async def run(self, runt, genr):
|
|
4578
4697
|
|
|
4579
|
-
|
|
4580
|
-
mesg = 'Storm runtime is in readonly mode, cannot create or edit nodes and other graph data.'
|
|
4581
|
-
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
4698
|
+
self.reqNotReadOnly(runt)
|
|
4582
4699
|
|
|
4583
4700
|
if len(self.kids) > 1 and isinstance(self.kids[0], Const) and (await self.kids[0].compute(runt, None)) == '?':
|
|
4584
4701
|
oper_offset = 1
|
|
@@ -4622,9 +4739,7 @@ class EditTagDel(Edit):
|
|
|
4622
4739
|
|
|
4623
4740
|
async def run(self, runt, genr):
|
|
4624
4741
|
|
|
4625
|
-
|
|
4626
|
-
mesg = 'Storm runtime is in readonly mode, cannot create or edit nodes and other graph data.'
|
|
4627
|
-
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
4742
|
+
self.reqNotReadOnly(runt)
|
|
4628
4743
|
|
|
4629
4744
|
async for node, path in genr:
|
|
4630
4745
|
|
|
@@ -4648,9 +4763,7 @@ class EditTagPropSet(Edit):
|
|
|
4648
4763
|
'''
|
|
4649
4764
|
async def run(self, runt, genr):
|
|
4650
4765
|
|
|
4651
|
-
|
|
4652
|
-
mesg = 'Storm runtime is in readonly mode, cannot create or edit nodes and other graph data.'
|
|
4653
|
-
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
4766
|
+
self.reqNotReadOnly(runt)
|
|
4654
4767
|
|
|
4655
4768
|
oper = await self.kids[1].compute(runt, None)
|
|
4656
4769
|
excignore = s_exc.BadTypeValu if oper == '?=' else ()
|
|
@@ -4684,9 +4797,7 @@ class EditTagPropDel(Edit):
|
|
|
4684
4797
|
'''
|
|
4685
4798
|
async def run(self, runt, genr):
|
|
4686
4799
|
|
|
4687
|
-
|
|
4688
|
-
mesg = 'Storm runtime is in readonly mode, cannot create or edit nodes and other graph data.'
|
|
4689
|
-
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
4800
|
+
self.reqNotReadOnly(runt)
|
|
4690
4801
|
|
|
4691
4802
|
async for node, path in genr:
|
|
4692
4803
|
|
|
@@ -4711,9 +4822,9 @@ class BreakOper(AstNode):
|
|
|
4711
4822
|
yield _
|
|
4712
4823
|
|
|
4713
4824
|
async for node, path in genr:
|
|
4714
|
-
raise s_stormctrl.StormBreak(item=(node, path))
|
|
4825
|
+
raise self.addExcInfo(s_stormctrl.StormBreak(item=(node, path)))
|
|
4715
4826
|
|
|
4716
|
-
raise s_stormctrl.StormBreak()
|
|
4827
|
+
raise self.addExcInfo(s_stormctrl.StormBreak())
|
|
4717
4828
|
|
|
4718
4829
|
class ContinueOper(AstNode):
|
|
4719
4830
|
|
|
@@ -4724,15 +4835,31 @@ class ContinueOper(AstNode):
|
|
|
4724
4835
|
yield _
|
|
4725
4836
|
|
|
4726
4837
|
async for node, path in genr:
|
|
4727
|
-
raise s_stormctrl.StormContinue(item=(node, path))
|
|
4838
|
+
raise self.addExcInfo(s_stormctrl.StormContinue(item=(node, path)))
|
|
4728
4839
|
|
|
4729
|
-
raise s_stormctrl.StormContinue()
|
|
4840
|
+
raise self.addExcInfo(s_stormctrl.StormContinue())
|
|
4730
4841
|
|
|
4731
4842
|
class IfClause(AstNode):
|
|
4732
4843
|
pass
|
|
4733
4844
|
|
|
4734
4845
|
class IfStmt(Oper):
|
|
4735
4846
|
|
|
4847
|
+
def _hasAstClass(self, clss):
|
|
4848
|
+
|
|
4849
|
+
clauses = self.kids
|
|
4850
|
+
|
|
4851
|
+
if not isinstance(clauses[-1], IfClause):
|
|
4852
|
+
if clauses[-1].hasAstClass(clss):
|
|
4853
|
+
return True
|
|
4854
|
+
|
|
4855
|
+
clauses = clauses[:-1]
|
|
4856
|
+
|
|
4857
|
+
for clause in clauses:
|
|
4858
|
+
if clause.kids[1].hasAstClass(clss):
|
|
4859
|
+
return True
|
|
4860
|
+
|
|
4861
|
+
return False
|
|
4862
|
+
|
|
4736
4863
|
def prepare(self):
|
|
4737
4864
|
if isinstance(self.kids[-1], IfClause):
|
|
4738
4865
|
self.elsequery = None
|
|
@@ -4817,20 +4944,26 @@ class Emit(Oper):
|
|
|
4817
4944
|
count = 0
|
|
4818
4945
|
async for node, path in genr:
|
|
4819
4946
|
count += 1
|
|
4820
|
-
|
|
4947
|
+
try:
|
|
4948
|
+
await runt.emit(await self.kids[0].compute(runt, path))
|
|
4949
|
+
except s_exc.StormRuntimeError as e:
|
|
4950
|
+
raise self.addExcInfo(e)
|
|
4821
4951
|
yield node, path
|
|
4822
4952
|
|
|
4823
4953
|
# no items in pipeline and runtsafe. execute once.
|
|
4824
4954
|
if count == 0 and self.isRuntSafe(runt):
|
|
4825
|
-
|
|
4955
|
+
try:
|
|
4956
|
+
await runt.emit(await self.kids[0].compute(runt, None))
|
|
4957
|
+
except s_exc.StormRuntimeError as e:
|
|
4958
|
+
raise self.addExcInfo(e)
|
|
4826
4959
|
|
|
4827
4960
|
class Stop(Oper):
|
|
4828
4961
|
|
|
4829
4962
|
async def run(self, runt, genr):
|
|
4830
4963
|
for _ in (): yield _
|
|
4831
4964
|
async for node, path in genr:
|
|
4832
|
-
raise s_stormctrl.StormStop()
|
|
4833
|
-
raise s_stormctrl.StormStop()
|
|
4965
|
+
raise self.addExcInfo(s_stormctrl.StormStop())
|
|
4966
|
+
raise self.addExcInfo(s_stormctrl.StormStop())
|
|
4834
4967
|
|
|
4835
4968
|
class FuncArgs(AstNode):
|
|
4836
4969
|
'''
|
|
@@ -4891,8 +5024,9 @@ class Function(AstNode):
|
|
|
4891
5024
|
|
|
4892
5025
|
@s_stormtypes.stormfunc(readonly=True)
|
|
4893
5026
|
async def realfunc(*args, **kwargs):
|
|
4894
|
-
return await self.callfunc(runt, argdefs, args, kwargs)
|
|
5027
|
+
return await self.callfunc(runt, argdefs, args, kwargs, realfunc._storm_funcpath)
|
|
4895
5028
|
|
|
5029
|
+
realfunc._storm_funcpath = self.name
|
|
4896
5030
|
await runt.setVar(self.name, realfunc)
|
|
4897
5031
|
|
|
4898
5032
|
count = 0
|
|
@@ -4914,7 +5048,7 @@ class Function(AstNode):
|
|
|
4914
5048
|
# var scope validation occurs in the sub-runtime
|
|
4915
5049
|
pass
|
|
4916
5050
|
|
|
4917
|
-
async def callfunc(self, runt, argdefs, args, kwargs):
|
|
5051
|
+
async def callfunc(self, runt, argdefs, args, kwargs, funcpath):
|
|
4918
5052
|
'''
|
|
4919
5053
|
Execute a function call using the given runtime.
|
|
4920
5054
|
|
|
@@ -4925,7 +5059,7 @@ class Function(AstNode):
|
|
|
4925
5059
|
|
|
4926
5060
|
argcount = len(args) + len(kwargs)
|
|
4927
5061
|
if argcount > len(argdefs):
|
|
4928
|
-
mesg = f'{
|
|
5062
|
+
mesg = f'{funcpath}() takes {len(argdefs)} arguments but {argcount} were provided'
|
|
4929
5063
|
raise self.kids[1].addExcInfo(s_exc.StormRuntimeError(mesg=mesg))
|
|
4930
5064
|
|
|
4931
5065
|
# Fill in the positional arguments
|
|
@@ -4939,7 +5073,7 @@ class Function(AstNode):
|
|
|
4939
5073
|
valu = kwargs.pop(name, s_common.novalu)
|
|
4940
5074
|
if valu is s_common.novalu:
|
|
4941
5075
|
if defv is s_common.novalu:
|
|
4942
|
-
mesg = f'{
|
|
5076
|
+
mesg = f'{funcpath}() missing required argument {name}'
|
|
4943
5077
|
raise self.kids[1].addExcInfo(s_exc.StormRuntimeError(mesg=mesg))
|
|
4944
5078
|
valu = defv
|
|
4945
5079
|
|
|
@@ -4950,11 +5084,11 @@ class Function(AstNode):
|
|
|
4950
5084
|
# used a kwarg not defined.
|
|
4951
5085
|
kwkeys = list(kwargs.keys())
|
|
4952
5086
|
if kwkeys[0] in posnames:
|
|
4953
|
-
mesg = f'{
|
|
5087
|
+
mesg = f'{funcpath}() got multiple values for parameter {kwkeys[0]}'
|
|
4954
5088
|
raise self.kids[1].addExcInfo(s_exc.StormRuntimeError(mesg=mesg))
|
|
4955
5089
|
|
|
4956
5090
|
plural = 's' if len(kwargs) > 1 else ''
|
|
4957
|
-
mesg = f'{
|
|
5091
|
+
mesg = f'{funcpath}() got unexpected keyword argument{plural}: {",".join(kwkeys)}'
|
|
4958
5092
|
raise self.kids[1].addExcInfo(s_exc.StormRuntimeError(mesg=mesg))
|
|
4959
5093
|
|
|
4960
5094
|
assert len(mergargs) == len(argdefs)
|
|
@@ -4973,9 +5107,16 @@ class Function(AstNode):
|
|
|
4973
5107
|
await asyncio.sleep(0)
|
|
4974
5108
|
|
|
4975
5109
|
return None
|
|
4976
|
-
|
|
4977
5110
|
except s_stormctrl.StormReturn as e:
|
|
4978
5111
|
return e.item
|
|
5112
|
+
except s_stormctrl.StormLoopCtrl as e:
|
|
5113
|
+
mesg = f'function {self.name} - Loop control statement "{e.statement}" used outside of a loop.'
|
|
5114
|
+
raise self.addExcInfo(s_exc.StormRuntimeError(mesg=mesg, function=self.name,
|
|
5115
|
+
statement=e.statement)) from e
|
|
5116
|
+
except s_stormctrl.StormGenrCtrl as e:
|
|
5117
|
+
mesg = f'function {self.name} - Generator control statement "{e.statement}" used outside of a generator function.'
|
|
5118
|
+
raise self.addExcInfo(s_exc.StormRuntimeError(mesg=mesg, function=self.name,
|
|
5119
|
+
statement=e.statement)) from e
|
|
4979
5120
|
|
|
4980
5121
|
async def genr():
|
|
4981
5122
|
async with runt.getSubRuntime(self.kids[2], opts=opts) as subr:
|
|
@@ -4995,5 +5136,9 @@ class Function(AstNode):
|
|
|
4995
5136
|
yield node, path
|
|
4996
5137
|
except s_stormctrl.StormStop:
|
|
4997
5138
|
return
|
|
5139
|
+
except s_stormctrl.StormLoopCtrl as e:
|
|
5140
|
+
mesg = f'function {self.name} - Loop control statement "{e.statement}" used outside of a loop.'
|
|
5141
|
+
raise self.addExcInfo(s_exc.StormRuntimeError(mesg=mesg, function=self.name,
|
|
5142
|
+
statement=e.statement)) from e
|
|
4998
5143
|
|
|
4999
5144
|
return genr()
|