synapse 2.168.0__py311-none-any.whl → 2.169.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/cortex.py CHANGED
@@ -573,14 +573,6 @@ class CoreApi(s_cell.CellApi):
573
573
  async def delStormDmon(self, iden):
574
574
  return await self.cell.delStormDmon(iden)
575
575
 
576
- @s_cell.adminapi(log=True)
577
- async def enableMigrationMode(self): # pragma: no cover
578
- s_common.deprdate('CoreApi.enableMigrationMode', '2024-05-05')
579
-
580
- @s_cell.adminapi(log=True)
581
- async def disableMigrationMode(self): # pragma: no cover
582
- s_common.deprdate('CoreApi.disableMigrationMode', '2024-05-05')
583
-
584
576
  @s_cell.adminapi()
585
577
  async def cloneLayer(self, iden, ldef=None):
586
578
 
@@ -1350,6 +1342,17 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
1350
1342
  'ex': 'node.prop.del.inet:ipv4.asn',
1351
1343
  'desc': 'Controls removing a specific property from a form of node in a layer.'},
1352
1344
 
1345
+ {'perm': ('node', 'data', 'set'), 'gate': 'layer',
1346
+ 'desc': 'Permits a user to set node data in a given layer.'},
1347
+ {'perm': ('node', 'data', 'set', '<key>'), 'gate': 'layer',
1348
+ 'ex': 'node.data.set.hehe',
1349
+ 'desc': 'Permits a user to set node data in a given layer for a specific key.'},
1350
+ {'perm': ('node', 'data', 'pop'), 'gate': 'layer',
1351
+ 'desc': 'Permits a user to remove node data in a given layer.'},
1352
+ {'perm': ('node', 'data', 'pop', '<key>'), 'gate': 'layer',
1353
+ 'ex': 'node.data.pop.hehe',
1354
+ 'desc': 'Permits a user to remove node data in a given layer for a specific key.'},
1355
+
1353
1356
  {'perm': ('pkg', 'add'), 'gate': 'cortex',
1354
1357
  'desc': 'Controls access to adding storm packages.'},
1355
1358
  {'perm': ('pkg', 'del'), 'gate': 'cortex',
synapse/lib/agenda.py CHANGED
@@ -831,6 +831,9 @@ class Agenda(s_base.Base):
831
831
  'view': appt.view,
832
832
  'mirror': appt.pool,
833
833
  'vars': {'auto': {'iden': appt.iden, 'type': 'cron'}},
834
+ '_loginfo': {
835
+ 'cron': appt.iden
836
+ }
834
837
  }
835
838
  opts = self.core._initStormOpts(opts)
836
839
 
synapse/lib/cell.py CHANGED
@@ -1295,14 +1295,20 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
1295
1295
 
1296
1296
  async def _onBootOptimize(self):
1297
1297
 
1298
+ bdir = s_common.genpath(self.dirn, 'backups')
1298
1299
  tdir = s_common.gendir(self.dirn, 'tmp')
1299
1300
  tdev = os.stat(tdir).st_dev
1300
1301
 
1302
+ logger.warning('Collecting LMDB files for onboot optimization.')
1303
+
1301
1304
  lmdbs = []
1302
1305
  for (root, dirs, files) in os.walk(self.dirn):
1303
1306
  for dirname in dirs:
1304
1307
  filepath = os.path.join(root, dirname, 'data.mdb')
1305
1308
  if os.path.isfile(filepath):
1309
+ if filepath.startswith(bdir):
1310
+ logger.debug(f'Skipping backup file {filepath}')
1311
+ continue
1306
1312
  if os.stat(filepath).st_dev != tdev:
1307
1313
  logger.warning(f'Unable to run onboot:optimize, {filepath} is not on the same volume as {tdir}')
1308
1314
  return
@@ -2891,24 +2897,10 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
2891
2897
  self.onfini(self.dmon.fini)
2892
2898
 
2893
2899
  async def _initCellHive(self):
2894
- isnew = not self.slab.dbexists('hive')
2895
-
2896
2900
  db = self.slab.initdb('hive')
2897
2901
  hive = await s_hive.SlabHive.anit(self.slab, db=db, nexsroot=self.getCellNexsRoot())
2898
2902
  self.onfini(hive)
2899
2903
 
2900
- if isnew:
2901
- path = os.path.join(self.dirn, 'hiveboot.yaml')
2902
- if os.path.isfile(path):
2903
- s_common.deprdate('Initial hive config from hiveboot.yaml', '2024-05-05')
2904
- logger.debug(f'Loading cell hive from {path}')
2905
- tree = s_common.yamlload(path)
2906
- if tree is not None:
2907
- # Pack and unpack the tree to avoid tuple/list issues
2908
- # for in-memory structures.
2909
- tree = s_common.tuplify(tree)
2910
- await hive.loadHiveTree(tree)
2911
-
2912
2904
  return hive
2913
2905
 
2914
2906
  async def _initCellSlab(self, readonly=False):
synapse/lib/httpapi.py CHANGED
@@ -1354,6 +1354,9 @@ class ExtApiHandler(StormHandler):
1354
1354
  'user': useriden,
1355
1355
  'vars': varz,
1356
1356
  'view': adef.get('view'),
1357
+ '_loginfo': {
1358
+ 'httpapi': iden
1359
+ }
1357
1360
  }
1358
1361
 
1359
1362
  query = '\n'.join((self.storm_prefix, storm))
synapse/lib/snap.py CHANGED
@@ -717,7 +717,9 @@ class Snap(s_base.Base):
717
717
 
718
718
  show_storage = False
719
719
 
720
- self.core._logStormQuery(text, user, info={'mode': opts.get('mode', 'storm'), 'view': self.view.iden})
720
+ info = opts.get('_loginfo', {})
721
+ info.update({'mode': opts.get('mode', 'storm'), 'view': self.view.iden})
722
+ self.core._logStormQuery(text, user, info=info)
721
723
 
722
724
  # { form: ( embedprop, ... ) }
723
725
  embeds = opts.get('embeds')
@@ -1,6 +1,7 @@
1
1
  import synapse.exc as s_exc
2
2
  import synapse.common as s_common
3
3
 
4
+ import synapse.lib.node as s_node
4
5
  import synapse.lib.cache as s_cache
5
6
  import synapse.lib.stormtypes as s_stormtypes
6
7
 
@@ -692,3 +693,122 @@ class LibModelDeprecated(s_stormtypes.Lib):
692
693
  todo = s_common.todo('setDeprLock', name, locked)
693
694
  gatekeys = ((self.runt.user.iden, ('model', 'deprecated', 'lock'), None),)
694
695
  await self.runt.dyncall('cortex', todo, gatekeys=gatekeys)
696
+
697
+ @s_stormtypes.registry.registerLib
698
+ class LibModelMigration(s_stormtypes.Lib):
699
+ '''
700
+ A Storm library containing migration tools.
701
+ '''
702
+ _storm_locals = (
703
+ {'name': 'copyData', 'desc': 'Copy node data from the src node to the dst node.',
704
+ 'type': {'type': 'function', '_funcname': '_methCopyData',
705
+ 'args': (
706
+ {'name': 'src', 'type': 'node', 'desc': 'The node to copy data from.', },
707
+ {'name': 'dst', 'type': 'node', 'desc': 'The node to copy data to.', },
708
+ {'name': 'overwrite', 'type': 'boolean', 'default': False,
709
+ 'desc': 'Copy data even if the key exists on the destination node.', },
710
+ ),
711
+ 'returns': {'type': 'null', }}},
712
+ {'name': 'copyEdges', 'desc': 'Copy edges from the src node to the dst node.',
713
+ 'type': {'type': 'function', '_funcname': '_methCopyEdges',
714
+ 'args': (
715
+ {'name': 'src', 'type': 'node', 'desc': 'The node to copy edges from.', },
716
+ {'name': 'dst', 'type': 'node', 'desc': 'The node to copy edges to.', },
717
+ ),
718
+ 'returns': {'type': 'null', }}},
719
+ {'name': 'copyTags', 'desc': 'Copy tags, tag timestamps, and tag props from the src node to the dst node.',
720
+ 'type': {'type': 'function', '_funcname': '_methCopyTags',
721
+ 'args': (
722
+ {'name': 'src', 'type': 'node', 'desc': 'The node to copy tags from.', },
723
+ {'name': 'dst', 'type': 'node', 'desc': 'The node to copy tags to.', },
724
+ {'name': 'overwrite', 'type': 'boolean', 'default': False,
725
+ 'desc': 'Copy tag property value even if the property exists on the destination node.', },
726
+ ),
727
+ 'returns': {'type': 'null', }}},
728
+ )
729
+ _storm_lib_path = ('model', 'migration')
730
+
731
+ def getObjLocals(self):
732
+ return {
733
+ 'copyData': self._methCopyData,
734
+ 'copyEdges': self._methCopyEdges,
735
+ 'copyTags': self._methCopyTags,
736
+ }
737
+
738
+ async def _methCopyData(self, src, dst, overwrite=False):
739
+
740
+ if not isinstance(src, s_node.Node):
741
+ raise s_exc.BadArg(mesg='$lib.model.migration.copyData() source argument must be a node.')
742
+ if not isinstance(dst, s_node.Node):
743
+ raise s_exc.BadArg(mesg='$lib.model.migration.copyData() dest argument must be a node.')
744
+
745
+ overwrite = await s_stormtypes.tobool(overwrite)
746
+
747
+ async with self.runt.snap.getEditor() as editor:
748
+
749
+ proto = editor.loadNode(dst)
750
+
751
+ async for name in src.iterDataKeys():
752
+ if overwrite or not await dst.hasData(name):
753
+ self.runt.layerConfirm(('node', 'data', 'set', name))
754
+ valu = await src.getData(name)
755
+ await proto.setData(name, valu)
756
+
757
+ async def _methCopyEdges(self, src, dst):
758
+
759
+ if not isinstance(src, s_node.Node):
760
+ raise s_exc.BadArg(mesg='$lib.model.migration.copyEdges() source argument must be a node.')
761
+ if not isinstance(dst, s_node.Node):
762
+ raise s_exc.BadArg(mesg='$lib.model.migration.copyEdges() dest argument must be a node.')
763
+
764
+ snap = self.runt.snap
765
+
766
+ async with snap.getEditor() as editor:
767
+
768
+ proto = editor.loadNode(dst)
769
+ verbs = set()
770
+
771
+ async for (verb, n2iden) in src.iterEdgesN1():
772
+
773
+ if verb not in verbs:
774
+ self.runt.layerConfirm(('node', 'edge', 'add', verb))
775
+ verbs.add(verb)
776
+
777
+ if await snap.getNodeByBuid(s_common.uhex(n2iden)) is not None:
778
+ await proto.addEdge(verb, n2iden)
779
+
780
+ dstiden = s_common.ehex(dst.buid)
781
+
782
+ async for (verb, n1iden) in src.iterEdgesN2():
783
+
784
+ if verb not in verbs:
785
+ self.runt.layerConfirm(('node', 'edge', 'add', verb))
786
+ verbs.add(verb)
787
+
788
+ n1proto = await editor.getNodeByBuid(s_common.uhex(n1iden))
789
+ if n1proto is not None:
790
+ await n1proto.addEdge(verb, dstiden)
791
+
792
+ async def _methCopyTags(self, src, dst, overwrite=False):
793
+
794
+ if not isinstance(src, s_node.Node):
795
+ raise s_exc.BadArg(mesg='$lib.model.migration.copyTags() source argument must be a node.')
796
+ if not isinstance(dst, s_node.Node):
797
+ raise s_exc.BadArg(mesg='$lib.model.migration.copyTags() dest argument must be a node.')
798
+
799
+ overwrite = await s_stormtypes.tobool(overwrite)
800
+
801
+ snap = self.runt.snap
802
+
803
+ async with snap.getEditor() as editor:
804
+
805
+ proto = editor.loadNode(dst)
806
+
807
+ for name, valu in src.tags.items():
808
+ self.runt.layerConfirm(('node', 'tag', 'add', *name.split('.')))
809
+ await proto.addTag(name, valu=valu)
810
+
811
+ for tagname, tagprops in src.tagprops.items():
812
+ for propname, valu in tagprops.items():
813
+ if overwrite or not dst.hasTagProp(tagname, propname):
814
+ await proto.setTagProp(tagname, propname, valu) # use tag perms
synapse/lib/stormtypes.py CHANGED
@@ -1604,8 +1604,12 @@ class LibBase(Lib):
1604
1604
  continue
1605
1605
  vals.append(arg)
1606
1606
 
1607
+ if len(vals) < 1:
1608
+ mesg = '$lib.min() must have at least one argument or a list containing at least one value.'
1609
+ raise s_exc.StormRuntimeError(mesg=mesg)
1610
+
1607
1611
  ints = [await toint(x) for x in vals]
1608
- return min(*ints)
1612
+ return min(ints)
1609
1613
 
1610
1614
  @stormfunc(readonly=True)
1611
1615
  async def _max(self, *args):
@@ -1618,8 +1622,12 @@ class LibBase(Lib):
1618
1622
  continue
1619
1623
  vals.append(arg)
1620
1624
 
1625
+ if len(vals) < 1:
1626
+ mesg = '$lib.max() must have at least one argument or a list containing at least one value.'
1627
+ raise s_exc.StormRuntimeError(mesg=mesg)
1628
+
1621
1629
  ints = [await toint(x) for x in vals]
1622
- return max(*ints)
1630
+ return max(ints)
1623
1631
 
1624
1632
  @staticmethod
1625
1633
  async def _get_mesg(mesg, **kwargs):
synapse/lib/version.py CHANGED
@@ -223,6 +223,6 @@ def reqVersion(valu, reqver,
223
223
  ##############################################################################
224
224
  # The following are touched during the release process by bumpversion.
225
225
  # Do not modify these directly.
226
- version = (2, 168, 0)
226
+ version = (2, 169, 0)
227
227
  verstring = '.'.join([str(x) for x in version])
228
- commit = 'd07eb2560a6e5e025ce9c20efaafe5571a55856c'
228
+ commit = '41421efcf40bb7655af3f90cb7d6d335247fc726'
synapse/lib/view.py CHANGED
@@ -868,20 +868,16 @@ class View(s_nexus.Pusher): # type: ignore
868
868
 
869
869
  self.layers.append(layr)
870
870
 
871
- async def eval(self, text, opts=None, log_info=None):
871
+ async def eval(self, text, opts=None):
872
872
  '''
873
873
  Evaluate a storm query and yield Nodes only.
874
874
  '''
875
875
  opts = self.core._initStormOpts(opts)
876
876
  user = self.core._userFromOpts(opts)
877
877
 
878
- if log_info is None:
879
- log_info = {}
880
-
881
- log_info['mode'] = opts.get('mode', 'storm')
882
- log_info['view'] = self.iden
883
-
884
- self.core._logStormQuery(text, user, info=log_info)
878
+ info = opts.get('_loginfo', {})
879
+ info.update({'mode': opts.get('mode', 'storm'), 'view': self.iden})
880
+ self.core._logStormQuery(text, user, info=info)
885
881
 
886
882
  taskiden = opts.get('task')
887
883
  taskinfo = {'query': text, 'view': self.iden}
@@ -997,8 +993,9 @@ class View(s_nexus.Pusher): # type: ignore
997
993
  count += 1
998
994
 
999
995
  else:
1000
- self.core._logStormQuery(text, user,
1001
- info={'mode': opts.get('mode', 'storm'), 'view': self.iden})
996
+ info = opts.get('_loginfo', {})
997
+ info.update({'mode': opts.get('mode', 'storm'), 'view': self.iden})
998
+ self.core._logStormQuery(text, user, info=info)
1002
999
  async for item in snap.storm(text, opts=opts, user=user):
1003
1000
  count += 1
1004
1001
 
@@ -1,3 +1,4 @@
1
+ import json
1
2
  import asyncio
2
3
  import hashlib
3
4
  import datetime
@@ -156,7 +157,7 @@ class AgendaTest(s_t_utils.SynTest):
156
157
  newts = ar.nexttime(now)
157
158
  self.eq(newts, datetime.datetime(year=2018, month=12, day=5, hour=7, minute=2, tzinfo=tz.utc).timestamp())
158
159
 
159
- async def test_agenda(self):
160
+ async def test_agenda_base(self):
160
161
  MONO_DELT = 1543827303.0
161
162
  unixtime = datetime.datetime(year=2018, month=12, day=5, hour=7, minute=0, tzinfo=tz.utc).timestamp()
162
163
 
@@ -382,8 +383,21 @@ class AgendaTest(s_t_utils.SynTest):
382
383
  self.true(appt.enabled)
383
384
  self.eq(0, appt.startcount)
384
385
 
385
- unixtime = datetime.datetime(year=2019, month=2, day=13, hour=10, minute=16, tzinfo=tz.utc).timestamp()
386
- self.eq((12, 'bar'), await asyncio.wait_for(core.callStorm('return($lib.queue.gen(visi).pop(wait=$lib.true))'), timeout=5))
386
+ # Ensure structured logging captures the cron iden value
387
+ core.stormlog = True
388
+ with self.getStructuredAsyncLoggerStream('synapse.storm') as stream:
389
+ unixtime = datetime.datetime(year=2019, month=2, day=13, hour=10, minute=16,
390
+ tzinfo=tz.utc).timestamp()
391
+ self.eq((12, 'bar'), await asyncio.wait_for(core.callStorm('return($lib.queue.gen(visi).pop(wait=$lib.true))'), timeout=5))
392
+ core.stormlog = False
393
+
394
+ data = stream.getvalue()
395
+ raw_mesgs = [m for m in data.split('\n') if m]
396
+ msgs = [json.loads(m) for m in raw_mesgs]
397
+ msgs = [m for m in msgs if m['text'] == '$lib.queue.gen(visi).put(bar)']
398
+ self.gt(len(msgs), 0)
399
+ for m in msgs:
400
+ self.eq(m.get('cron'), appt.iden)
387
401
 
388
402
  self.eq(1, appt.startcount)
389
403
 
@@ -496,52 +496,6 @@ class CellTest(s_t_utils.SynTest):
496
496
  with self.raises(s_exc.AuthDeny):
497
497
  await prox.setCellUser(visiiden)
498
498
 
499
- async def test_cell_hiveboot(self):
500
-
501
- with self.getTestDir() as dirn:
502
-
503
- tree = {
504
- 'kids': {
505
- 'hehe': {'value': 'haha'},
506
- }
507
- }
508
-
509
- bootpath = os.path.join(dirn, 'hiveboot.yaml')
510
-
511
- s_common.yamlsave(tree, bootpath)
512
-
513
- with warnings.catch_warnings(record=True) as warns:
514
- async with self.getTestCell(s_cell.Cell, dirn=dirn) as cell:
515
- self.eq('haha', await cell.hive.get(('hehe',)))
516
-
517
- self.isin('Initial hive config from hiveboot.yaml', str(warns[0].message))
518
-
519
- # test that the file does not load again
520
- tree['kids']['redballoons'] = {'value': 99}
521
- s_common.yamlsave(tree, bootpath)
522
-
523
- async with self.getTestCell(s_cell.Cell, dirn=dirn) as cell:
524
- self.none(await cell.hive.get(('redballoons',)))
525
-
526
- # Do a full hive dump/load
527
- with self.getTestDir() as dirn:
528
- dir0 = s_common.genpath(dirn, 'cell00')
529
- dir1 = s_common.genpath(dirn, 'cell01')
530
- async with self.getTestCell(s_cell.Cell, dirn=dir0, conf={'auth:passwd': 'root'}) as cell00:
531
- await cell00.hive.set(('beeps',), [1, 2, 'three'])
532
-
533
- tree = await cell00.saveHiveTree()
534
- s_common.yamlsave(tree, dir1, 'hiveboot.yaml')
535
- with s_common.genfile(dir1, 'cell.guid') as fd:
536
- _ = fd.write(cell00.iden.encode())
537
-
538
- async with self.getTestCell(s_cell.Cell, dirn=dir1) as cell01:
539
- resp = await cell01.hive.get(('beeps',))
540
- self.isinstance(resp, tuple)
541
- self.eq(resp, (1, 2, 'three'))
542
-
543
- self.eq(cell00.iden, cell01.iden)
544
-
545
499
  async def test_cell_getinfo(self):
546
500
  async with self.getTestCore() as cell:
547
501
  cell.COMMIT = 'mycommit'
@@ -2243,8 +2197,8 @@ class CellTest(s_t_utils.SynTest):
2243
2197
  async with self.getTestCore(dirn=dirn, conf=conf) as core:
2244
2198
  pass
2245
2199
 
2246
- stream.seek(0)
2247
- self.isin('onboot optimization complete!', stream.read())
2200
+ stream.seek(0)
2201
+ self.isin('onboot optimization complete!', stream.read())
2248
2202
 
2249
2203
  stat01 = os.stat(lmdbfile)
2250
2204
  self.ne(stat00.st_ino, stat01.st_ino)
@@ -2266,10 +2220,25 @@ class CellTest(s_t_utils.SynTest):
2266
2220
  async with self.getTestCore(dirn=dirn, conf=conf) as core:
2267
2221
  pass
2268
2222
 
2269
- stream.seek(0)
2270
- buf = stream.read()
2271
- self.notin('onboot optimization complete!', buf)
2272
- self.isin('not on the same volume', buf)
2223
+ stream.seek(0)
2224
+ buf = stream.read()
2225
+ self.notin('onboot optimization complete!', buf)
2226
+ self.isin('not on the same volume', buf)
2227
+
2228
+ # Local backup files are skipped
2229
+ async with self.getTestCore(dirn=dirn) as core:
2230
+ await core.runBackup()
2231
+
2232
+ with self.getAsyncLoggerStream('synapse.lib.cell') as stream:
2233
+
2234
+ conf = {'onboot:optimize': True}
2235
+ async with self.getTestCore(dirn=dirn, conf=conf) as core:
2236
+ pass
2237
+
2238
+ stream.seek(0)
2239
+ buf = stream.read()
2240
+ self.isin('Skipping backup file', buf)
2241
+ self.isin('onboot optimization complete!', buf)
2273
2242
 
2274
2243
  async def test_cell_gc(self):
2275
2244
  async with self.getTestCore() as core:
@@ -281,6 +281,18 @@ $request.reply(206, headers=$headers, body=({"no":"body"}))
281
281
  self.eq(data.get('json'), 'err')
282
282
  self.eq(data.get('path'), 'echo/words/wOw')
283
283
 
284
+ # Storm query logging includes the httpapi iden in structlog data
285
+ core.stormlog = True
286
+ with self.getStructuredAsyncLoggerStream('synapse.storm', 'Executing storm query') as stream:
287
+ resp = await sess.get(url)
288
+ self.eq(resp.status, 200)
289
+ self.true(await stream.wait(timeout=12))
290
+ data = stream.getvalue()
291
+ raw_mesgs = [m for m in data.split('\n') if m]
292
+ msgs = [json.loads(m) for m in raw_mesgs]
293
+ self.eq(msgs[0].get('httpapi'), echoiden)
294
+ core.stormlog = False
295
+
284
296
  # Sad paths on the $request methods
285
297
  q = '''$api = $lib.cortex.httpapi.add(testpath02)
286
298
  $api.methods.get = ${ $request.sendcode(200) $request.sendheaders('beep beep') }
@@ -1,4 +1,5 @@
1
1
  import synapse.exc as s_exc
2
+ import synapse.lib.time as s_time
2
3
  import synapse.lib.layer as s_layer
3
4
 
4
5
  import synapse.tests.utils as s_test
@@ -295,3 +296,107 @@ class StormlibModelTest(s_test.SynTest):
295
296
 
296
297
  self.stormIsInWarn('.pdep is not yet locked', mesgs)
297
298
  self.stormNotInWarn('test:dep:easy.pdep is not yet locked', mesgs)
299
+
300
+ async def test_stormlib_model_migration(self):
301
+
302
+ async with self.getTestCore() as core:
303
+
304
+ nodes = await core.nodes('[ test:str=src test:str=dst test:str=deny test:str=other ]')
305
+ otheriden = nodes[3].iden()
306
+
307
+ lowuser = await core.auth.addUser('lowuser')
308
+ aslow = {'user': lowuser.iden}
309
+
310
+ # copy node data
311
+
312
+ await self.asyncraises(s_exc.BadArg, core.nodes('test:str=src $lib.model.migration.copyData($node, newp)'))
313
+ await self.asyncraises(s_exc.BadArg, core.nodes('test:str=dst $lib.model.migration.copyData(newp, $node)'))
314
+
315
+ nodes = await core.nodes('''
316
+ test:str=src
317
+ $node.data.set(a, a-src)
318
+ $node.data.set(b, b-src)
319
+ $n=$node -> {
320
+ test:str=dst
321
+ $node.data.set(a, a-dst)
322
+ $lib.model.migration.copyData($n, $node)
323
+ }
324
+ ''')
325
+ self.len(1, nodes)
326
+ self.sorteq(
327
+ [('a', 'a-dst'), ('b', 'b-src')],
328
+ [data async for data in nodes[0].iterData()]
329
+ )
330
+
331
+ nodes = await core.nodes('''
332
+ test:str=src $n=$node -> {
333
+ test:str=dst
334
+ $lib.model.migration.copyData($n, $node, overwrite=$lib.true)
335
+ }
336
+ ''')
337
+ self.len(1, nodes)
338
+ self.sorteq(
339
+ [('a', 'a-src'), ('b', 'b-src')],
340
+ [data async for data in nodes[0].iterData()]
341
+ )
342
+
343
+ q = 'test:str=src $n=$node -> { test:str=deny $lib.model.migration.copyData($n, $node) }'
344
+ await self.asyncraises(s_exc.AuthDeny, core.nodes(q, opts=aslow))
345
+
346
+ # copy edges
347
+
348
+ await self.asyncraises(s_exc.BadArg, core.nodes('test:str=src $lib.model.migration.copyEdges($node, newp)'))
349
+ await self.asyncraises(s_exc.BadArg, core.nodes('test:str=dst $lib.model.migration.copyEdges(newp, $node)'))
350
+
351
+ nodes = await core.nodes('''
352
+ test:str=src
353
+ [ <(foo)+ { test:str=other } +(bar)> { test:str=other } ]
354
+ $n=$node -> {
355
+ test:str=dst
356
+ $lib.model.migration.copyEdges($n, $node)
357
+ }
358
+ ''')
359
+ self.len(1, nodes)
360
+ self.eq([('bar', otheriden)], [edge async for edge in nodes[0].iterEdgesN1()])
361
+ self.eq([('foo', otheriden)], [edge async for edge in nodes[0].iterEdgesN2()])
362
+
363
+ q = 'test:str=src $n=$node -> { test:str=deny $lib.model.migration.copyEdges($n, $node) }'
364
+ await self.asyncraises(s_exc.AuthDeny, core.nodes(q, opts=aslow))
365
+
366
+ # copy tags
367
+
368
+ await self.asyncraises(s_exc.BadArg, core.nodes('test:str=src $lib.model.migration.copyTags($node, newp)'))
369
+ await self.asyncraises(s_exc.BadArg, core.nodes('test:str=dst $lib.model.migration.copyTags(newp, $node)'))
370
+
371
+ await core.nodes('$lib.model.ext.addTagProp(test, (str, ({})), ({}))')
372
+
373
+ nodes = await core.nodes('''
374
+ test:str=src
375
+ [ +#foo=(2010, 2012) +#foo.bar +#baz:test=src ]
376
+ $n=$node -> {
377
+ test:str=dst
378
+ [ +#foo=(2010, 2011) +#baz:test=dst ]
379
+ $lib.model.migration.copyTags($n, $node)
380
+ }
381
+ ''')
382
+ self.len(1, nodes)
383
+ self.sorteq([
384
+ ('baz', (None, None)),
385
+ ('foo', (s_time.parse('2010'), s_time.parse('2012'))),
386
+ ('foo.bar', (None, None))
387
+ ], nodes[0].getTags())
388
+ self.eq([], nodes[0].getTagProps('foo'))
389
+ self.eq([], nodes[0].getTagProps('foo.bar'))
390
+ self.eq([('test', 'dst')], [(k, nodes[0].getTagProp('baz', k)) for k in nodes[0].getTagProps('baz')])
391
+
392
+ nodes = await core.nodes('''
393
+ test:str=src $n=$node -> {
394
+ test:str=dst
395
+ $lib.model.migration.copyTags($n, $node, overwrite=$lib.true)
396
+ }
397
+ ''')
398
+ self.len(1, nodes)
399
+ self.eq([('test', 'src')], [(k, nodes[0].getTagProp('baz', k)) for k in nodes[0].getTagProps('baz')])
400
+
401
+ q = 'test:str=src $n=$node -> { test:str=deny $lib.model.migration.copyTags($n, $node) }'
402
+ await self.asyncraises(s_exc.AuthDeny, core.nodes(q, opts=aslow))
@@ -575,6 +575,32 @@ class StormTypesTest(s_test.SynTest):
575
575
  self.len(1, nodes)
576
576
  self.eq(30, nodes[0].ndef[1])
577
577
 
578
+ # $lib.min / $lib.max behavior with 1 item
579
+ ret = await core.callStorm('$x = ([(1234)]) return ( $lib.min($x) )')
580
+ self.eq(ret, 1234)
581
+
582
+ ret = await core.callStorm('return ( $lib.min(1234) )')
583
+ self.eq(ret, 1234)
584
+
585
+ ret = await core.callStorm('$x = ([(1234)]) return ( $lib.max($x) )')
586
+ self.eq(ret, 1234)
587
+
588
+ ret = await core.callStorm('return ( $lib.max(1234) )')
589
+ self.eq(ret, 1234)
590
+
591
+ # $lib.min / $lib.max behavior with 0 items
592
+ with self.raises(s_exc.StormRuntimeError):
593
+ await core.callStorm('$lib.max()')
594
+
595
+ with self.raises(s_exc.StormRuntimeError):
596
+ await core.callStorm('$l=() $lib.max($l)')
597
+
598
+ with self.raises(s_exc.StormRuntimeError):
599
+ await core.callStorm('$lib.min()')
600
+
601
+ with self.raises(s_exc.StormRuntimeError):
602
+ await core.callStorm('$l=() $lib.min($l)')
603
+
578
604
  nodes = await core.nodes('[ inet:asn=$lib.len(asdf) ]')
579
605
  self.len(1, nodes)
580
606
  self.eq(4, nodes[0].ndef[1])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: synapse
3
- Version: 2.168.0
3
+ Version: 2.169.0
4
4
  Summary: Synapse Intelligence Analysis Framework
5
5
  Author-email: The Vertex Project LLC <root@vertex.link>
6
6
  License: Apache License 2.0
@@ -2,7 +2,7 @@ synapse/__init__.py,sha256=R2kOXlF5j-8m6G0JkHuN7rXRPg_tHLmbMxr__94mHQk,1145
2
2
  synapse/axon.py,sha256=Hbbb1BqyB8xsb7xkaIMyTQJEE01-r5HXebnoAnw-qEY,61120
3
3
  synapse/cells.py,sha256=eNvdglfAoTURVhGOLGcgMXCGpfsIX1a02SQnyiklo3E,308
4
4
  synapse/common.py,sha256=_-cBBcL88YGAnhVq9WJ5nUKtoq-NytfwbgYzCq02W-Q,35578
5
- synapse/cortex.py,sha256=3IIy5N9By4MKAt6rHDzTaQnFGxd3Y1OrN85or0XTpHg,235141
5
+ synapse/cortex.py,sha256=Yv5-PrhMIwpCnu5TBV2aYdAsQc1fa6EmKz8phy-spl0,235511
6
6
  synapse/cryotank.py,sha256=kOriVF8LnwYxgyTxQXSepyFRtSu2C6n9t_yImTV7ZNI,11714
7
7
  synapse/daemon.py,sha256=tPPggIATq0O0Cw1J2nzL-JW10VIOFcrvP4XqsKQwozc,16776
8
8
  synapse/datamodel.py,sha256=o4YktPuoprTwjGly-8217dvHzM-sUxTMCPCwByqJCDI,34070
@@ -83,14 +83,14 @@ synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-sch
83
83
  synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sros/relationship.json,sha256=9X6FOE_f31GFlZEXjlgqlfRLN96ZlnxZew_rn7fVxVQ,2839
84
84
  synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sros/sighting.json,sha256=f1T3r4CRcJP0743qmAlVCdNvi5ASrOU42PSoiDNlRqc,3575
85
85
  synapse/lib/__init__.py,sha256=qLS7nt8-Iot8jnD2Xss_6wZi5lJoyv2rqxF9kkektT0,129
86
- synapse/lib/agenda.py,sha256=WgISI-baosIrg1i5pB0zPL4IWpEb95Y9bUJXaOUDnQs,32724
86
+ synapse/lib/agenda.py,sha256=HymcezgP5e25iV0OQsfbteBtty3cl2gdUifouU1z38I,32810
87
87
  synapse/lib/aha.py,sha256=fT1Assn7j1YQFSr5IYuW1GNH2G19gSXwV7ajNS3mlLY,42392
88
88
  synapse/lib/ast.py,sha256=fkZ7P8-1yTam_9RTxyK2ze-GNLEvCSFgb7on_AcFMG4,148961
89
89
  synapse/lib/autodoc.py,sha256=CsGaX0tAKGh21YbIvUtvaUnZyqmsx6j-E9QD_vhKSP4,20747
90
90
  synapse/lib/base.py,sha256=sTti-XzyQnoAwq0JvbDrjSu0_GqRT_J2eBxfNV8_ZrI,22520
91
91
  synapse/lib/boss.py,sha256=rYu4jkHJ3Y5GLX23Hlrwe9H17LF27LZ0BkK_A_9Aqh0,2056
92
92
  synapse/lib/cache.py,sha256=mF8aUIIo2ejQ2PT2IFmz8a4qrnDqOSLaOXws0djXOhQ,6265
93
- synapse/lib/cell.py,sha256=X0v8i63yr2H4AL7p8pxQ5pgK6Jjeg-QnhTGqutbpMPU,157932
93
+ synapse/lib/cell.py,sha256=P9oLg8jfuWvmkqGzHdVv3ZkTIA1AKWOIttRUVs8fXH0,157593
94
94
  synapse/lib/certdir.py,sha256=8gRkzCcpNVDLR-rXNww4frzGffF160iG18Z6d9JkPJY,56086
95
95
  synapse/lib/chop.py,sha256=_IywOiCvI9jL2yncSJaXR05B5Il7XR81uYerOTD__eI,9421
96
96
  synapse/lib/cli.py,sha256=rwaO4SbJIzOhwxB9B7NHXpyegQeRsUQ1gULVwgnNCfg,14580
@@ -109,7 +109,7 @@ synapse/lib/hashset.py,sha256=6R9q6iNfxZ5iGGEmoN7ODDCUnba1XBn7w2PPJh4Yz9o,1468
109
109
  synapse/lib/health.py,sha256=wkVZObjo3quEmxA0VOUnYHapnRinOVZdTFOVobjoTH4,1730
110
110
  synapse/lib/hive.py,sha256=7nrh6-is0qy4lZPg23M61wf9Jq7eDcL3D4EEbaFWKJM,19755
111
111
  synapse/lib/hiveauth.py,sha256=J7a9LGwLdsVr6EBLoVG4DXC2ML2ahOYq8XihNfNhS7c,40054
112
- synapse/lib/httpapi.py,sha256=yqlsVh_7UVVYFdTo6VB-x4LcZpgdz_ZJOHNFMYcqfGo,43114
112
+ synapse/lib/httpapi.py,sha256=i0E2dFl54ovWjEPSq7VQ5kNs6FThjXDUkD7ml9XNLOI,43186
113
113
  synapse/lib/ingest.py,sha256=HNW1xs215c_UXVjKaxjipKBmVL4ujrjmarHBRvLPLkE,40
114
114
  synapse/lib/interval.py,sha256=PqpEhMGG6LD9mJxEms0oQWC-NB01H6gwsmLSc5LrDFk,1175
115
115
  synapse/lib/jsonstor.py,sha256=QQVf7Kl90sI_v97UZZAoa6stizDeMyy0ykR3RsHpmi8,19359
@@ -137,7 +137,7 @@ synapse/lib/scrape.py,sha256=ZnYDUlb5KoPwPJ8Dx5UZZwgGKYynO7mYNYfgIoNkXZ0,25042
137
137
  synapse/lib/share.py,sha256=HDQR7nb4IOleHB1kIFe6prZQVW7PjPAivSAkPuhNn5A,663
138
138
  synapse/lib/slaboffs.py,sha256=Fd0RrIRBMjh159aQz5y1ONmzw0NvV040kVX_jZjQW6I,815
139
139
  synapse/lib/slabseqn.py,sha256=64UyPav1cCLEXF15wzbWskVeKZKPR1iiDhhmpvDFnuw,10010
140
- synapse/lib/snap.py,sha256=DnNAV36-qRYisE2M6j_AtoH1M8p2m8c_dDQp-QBG4MQ,53456
140
+ synapse/lib/snap.py,sha256=fH3hSOiDnkN5VijIyLK2gURKwZ0YD9z8wo7SUB0sats,53522
141
141
  synapse/lib/spooled.py,sha256=00x_RS1TiJkfuTXwwdUcYifuECGYgC8B1tX-sX7nb_k,5385
142
142
  synapse/lib/storm.lark,sha256=KlzTs3-Gcv0eHfen8356Smn6XKBIpD_aH0uyogSZvv8,25604
143
143
  synapse/lib/storm.py,sha256=7V49wVB-f-NdeJ92jurmtYz6vAAHREl-NJr_W_LrBjE,210426
@@ -145,7 +145,7 @@ synapse/lib/storm_format.py,sha256=IySRTGUbCAsIhULY1VS1vxvAbLYUXMezPlPSCRJX4rU,4
145
145
  synapse/lib/stormctrl.py,sha256=XvyZ6M0Ew8sXsjGvRTWbXh0MjktZrGi_zQ9kNa7AWTE,285
146
146
  synapse/lib/stormhttp.py,sha256=DkpndsFRGsWlDnT5RKknd9a53FVebZGOFVKCqkPcnrQ,26885
147
147
  synapse/lib/stormsvc.py,sha256=c8W1-2tC8Cu6IDHjqObBn8qaKH6vc-7GOR5YCOmuENA,6825
148
- synapse/lib/stormtypes.py,sha256=6rJs8cQ3LxYoG1A0zP1QBSDrC2O1KgtdW2MnoA8iCEU,378765
148
+ synapse/lib/stormtypes.py,sha256=gWLypVJbwEAWbATFfsMT3bX7adfErplH1PJbHiDsqGs,379133
149
149
  synapse/lib/stormwhois.py,sha256=efG4s1_UOShY3YD8N2OLEa_ELOnzsfLaMEMfDCJYeLQ,2275
150
150
  synapse/lib/structlog.py,sha256=qiuD7TTdwCyYEDF2f-88G2iX54SuB-lJ1pqlYokL1r8,1303
151
151
  synapse/lib/task.py,sha256=krDjQvNh0EpAs1PILK8CJJa9DMeM0depI0K8Eimp010,5733
@@ -156,8 +156,8 @@ synapse/lib/time.py,sha256=FKTYwpdvpuAj8p8sSodRjOxoA7Vu67CIbbXz55gtghk,9231
156
156
  synapse/lib/trigger.py,sha256=cqKW0e2KmeiPsU3d3vwpo0PLLHUs6ZPVWZyxAxU6gMA,20849
157
157
  synapse/lib/types.py,sha256=LXpxw4aNKMA0GLs3uG-RpZE5HcZdejMg1g4XJZ9UIfk,67712
158
158
  synapse/lib/urlhelp.py,sha256=j-DvWGi-xH0TcO0NbCuwG7guUuiV8wxIxfMyJOzDygo,2523
159
- synapse/lib/version.py,sha256=yU__bTyfUKaRC850Fien8PbWr7Gi8-gYz22RHIj35WY,7162
160
- synapse/lib/view.py,sha256=Xzx0vt_6x4Sr8IjLAU_Zhyl8nXNYnHjMVyBWNNGU_Pk,55390
159
+ synapse/lib/version.py,sha256=QNqr71EggQZ-IyVWXx2C_ElX7f2vTguc2NfbbrGsn1U,7162
160
+ synapse/lib/view.py,sha256=zokigg_EynMYsfBmS7nk07dDMJhKWARAf8a-4dtRTtk,55393
161
161
  synapse/lib/crypto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
162
162
  synapse/lib/crypto/coin.py,sha256=_dhlkzIrHT8BvHdJOWK7PDThz3sK3dDRnWAUqjRpZJc,4910
163
163
  synapse/lib/crypto/ecc.py,sha256=e5XM8fsU3YnkT9u1eNROqOK8ccjp5QirIn7FljC_z1s,6522
@@ -195,7 +195,7 @@ synapse/lib/stormlib/log.py,sha256=wdV-lqzQMM0C3GXNJKJKvkSKjk0CBsUfjd-Cl06LOtE,7
195
195
  synapse/lib/stormlib/macro.py,sha256=7iQ18mCaNZcslmfXGQvOmGQ71HxD7JeDp0HDmu5-EKM,8807
196
196
  synapse/lib/stormlib/math.py,sha256=3RKHj40GkYFiJSINa2AZZOAA-GqqeEP98bWw2JNity8,1149
197
197
  synapse/lib/stormlib/mime.py,sha256=WMDAcUiF8RkABKL8EUOScrO77pwi5EHPTko7hI2FPIE,1095
198
- synapse/lib/stormlib/model.py,sha256=8jelYNLePO3ssXCM7RtIxFlSKZeD42iMezxETyHIgJY,27478
198
+ synapse/lib/stormlib/model.py,sha256=o5VFXhvYG5wUexPPpxPejLfKyJxWrIx1OTEFJ83WM0g,32727
199
199
  synapse/lib/stormlib/modelext.py,sha256=NZl0wOZ-QLyrHArvgsdMYJIKBnYaBWelYL9ujoNKydo,8897
200
200
  synapse/lib/stormlib/notifications.py,sha256=6y1YuMavQs34WwnW5D_KrLPZ0DQlQKg5VFU56sounSA,3305
201
201
  synapse/lib/stormlib/oauth.py,sha256=hgfjI--w8vbvgNbGvZlzINTOEdQv68nk5mB27CkC93M,13011
@@ -272,14 +272,14 @@ synapse/tests/test_datamodel.py,sha256=uHCLkjeYqyUeR8LZv7xXjGwLRzYuWGixsM1C1HbWf
272
272
  synapse/tests/test_exc.py,sha256=j24ddx0PFdwtmgtwsjIvypXxfn4ji3rhAWo9I2sUbSY,1725
273
273
  synapse/tests/test_glob.py,sha256=cSNrtEKWLsZXRhsjxQjRjjMqdgqfpl05yT4S53dC0NU,249
274
274
  synapse/tests/test_init.py,sha256=rHqYBVL_aFf1HO6zCF5akHVcHUP2g1kpJLRdTkV0yys,557
275
- synapse/tests/test_lib_agenda.py,sha256=PowCWygRdErvjvaQNx80G3zNIqsLMMlrakyJU9XF5nE,37779
275
+ synapse/tests/test_lib_agenda.py,sha256=B2B-xvpp_jtFILHeh2GdtFJABba_scitG3VnvvLfO_s,38461
276
276
  synapse/tests/test_lib_aha.py,sha256=-XbpX1M47afeBH2sI_TxW5YsIZ5WrpynuEkq78Qtj1U,68898
277
277
  synapse/tests/test_lib_ast.py,sha256=bFdcP2al2qgLuY_yTXWNMsZSClv4oJRxj9kOR8KReaE,160358
278
278
  synapse/tests/test_lib_autodoc.py,sha256=H9Yb7cvzXOMPGBIoCCqNClcyIp6zEWcawtfudKbG-2U,6282
279
279
  synapse/tests/test_lib_base.py,sha256=mgqGmjioQaT75r4tWH7QkyqiMFOi_Or02Wo79oAh9z0,14032
280
280
  synapse/tests/test_lib_boss.py,sha256=gZEuJnMO99Fu9gQ7Ct0g67umBW5XFCs8vcwInB5qr14,1598
281
281
  synapse/tests/test_lib_cache.py,sha256=oQgEBhm8pZFCEvMfcD3znTDQgl8Gv91fEOB-3eb2IIg,8594
282
- synapse/tests/test_lib_cell.py,sha256=M42fndA2kftfA_dzb2XU6UXGOp2foq92FrT5eA-iTKM,116130
282
+ synapse/tests/test_lib_cell.py,sha256=Apg6yl-ypHTztpKEIPvHsAOm4FvR9VRWwR40bi_tyrM,114876
283
283
  synapse/tests/test_lib_certdir.py,sha256=IRyDRP-QdfdMrNhqtrlF-LLJeS6EhbkzzOXxtS__Uks,42417
284
284
  synapse/tests/test_lib_chop.py,sha256=LkrM_pQU_KS88aVRPD4DI97qSdhxmw6EUA_jb-UJpww,6238
285
285
  synapse/tests/test_lib_cli.py,sha256=B8qGx9KtTWp31RlCMtfFMzhJ0TzaaO9ph7RCK2jHtx4,9283
@@ -335,7 +335,7 @@ synapse/tests/test_lib_stormlib_basex.py,sha256=DDOsH3XDR8MdJ1uj5avyqnFqBnlaIu8L
335
335
  synapse/tests/test_lib_stormlib_cache.py,sha256=fOfMHUMVitnUT54oZHB56v86KH-aoWtVDvqUpKUfVD4,9084
336
336
  synapse/tests/test_lib_stormlib_cell.py,sha256=M-UyOEdggChAMmOOAoL1k7aGVd9nXLbIq621XKVq3j8,14921
337
337
  synapse/tests/test_lib_stormlib_compression.py,sha256=JX8P5XQH66Mv97dfq0_mnY8kqA67T2B5pbBH4B91nPo,2859
338
- synapse/tests/test_lib_stormlib_cortex.py,sha256=JYIun7UGmuLv17twyLKDP3I738s8P7HRxYFjBghcAus,69245
338
+ synapse/tests/test_lib_stormlib_cortex.py,sha256=s6V2Td8zl8_sm_-hZU00S-59JxCwrb2KH8vRIU4XnDU,69887
339
339
  synapse/tests/test_lib_stormlib_easyperm.py,sha256=qPZr5qjjmD4BnLeLQM3i2HgiHhTsjvu7is7l26xkMxY,4133
340
340
  synapse/tests/test_lib_stormlib_ethereum.py,sha256=yfil8RZWmbH7CUOlnito1kyL7VJVegoCgLaLXNKHFRI,797
341
341
  synapse/tests/test_lib_stormlib_gen.py,sha256=KUWMs989LfRu0mSTyVqAabtu_jQ82SltpWU5kcnA4-M,12318
@@ -350,7 +350,7 @@ synapse/tests/test_lib_stormlib_json.py,sha256=Ds8YsNXHDBg_yNxOrBJDKjF9W3tzGzIeO
350
350
  synapse/tests/test_lib_stormlib_log.py,sha256=pZwEgCou368-MzeDL5jMEARRyswVNKKJ-VuuKjoSmlU,2905
351
351
  synapse/tests/test_lib_stormlib_macro.py,sha256=IfGRX6ZAJr_RJGNPq2BKTEPByY90pnYDYdtHp8C1JbQ,18508
352
352
  synapse/tests/test_lib_stormlib_mime.py,sha256=ozBJ70XxdrErOmycStWdh1xkBHVnM0BTPHvaP4faC0g,1510
353
- synapse/tests/test_lib_stormlib_model.py,sha256=tHToZzJcx4fnzZ0XG6TYiTgeANVeRUAF1sSepZ90QUI,14213
353
+ synapse/tests/test_lib_stormlib_model.py,sha256=OpMOSM0CG7rCtjvEbnONFIML1PQwVbl9C_vKkFaa6uI,18694
354
354
  synapse/tests/test_lib_stormlib_modelext.py,sha256=yLhqT7XnQsZ2bx-gBiyD8SZZfhFKIALPPHX7o1POloY,17863
355
355
  synapse/tests/test_lib_stormlib_oauth.py,sha256=rb6ZWyLrWwcDT32VfjdQUg3AurwlhzbQv-kXIfPeRsQ,28858
356
356
  synapse/tests/test_lib_stormlib_pack.py,sha256=YSb4dErPM3CeU0piqvhIQF_F1m3YjApo3nA14ewPWf0,1563
@@ -365,7 +365,7 @@ synapse/tests/test_lib_stormlib_vault.py,sha256=JWCDmSoclZyTVzFdfAvjdLxq6eWIwTCw
365
365
  synapse/tests/test_lib_stormlib_xml.py,sha256=dWa9NkXXE28VZ3bTmMDbddo7VpUKsSEHTS1ojJr-F90,3704
366
366
  synapse/tests/test_lib_stormlib_yaml.py,sha256=egTVXk8wW31V2msF__9WxP3THcqfysG1mYhc7hQG8rw,1358
367
367
  synapse/tests/test_lib_stormsvc.py,sha256=CGU22jCrWoQHPPccC_MsqkAyz6ARSx9YffZwakhwXQU,40042
368
- synapse/tests/test_lib_stormtypes.py,sha256=e3X97PPBhi8cWsjMvNud-JrDqi1_eQSigSD7bfsxXtI,292537
368
+ synapse/tests/test_lib_stormtypes.py,sha256=OIvWtBkeGrbvv2igVVsuCoV_tvauiS7C8SReNIgiJXs,293520
369
369
  synapse/tests/test_lib_stormwhois.py,sha256=Rd7yx07kZtEs385e_8aA-EIYh4CrYdn_bh7ikIobiDU,4782
370
370
  synapse/tests/test_lib_structlog.py,sha256=DGfzrfc2nybRq5RjwiUXd1v4sC5zl8d46RHgTmFD0iA,3964
371
371
  synapse/tests/test_lib_task.py,sha256=Zby9Evlg_mBwE3_aF7p_5PIMhWp2Er7Y-ye4Y-3L5RQ,1646
@@ -564,8 +564,8 @@ synapse/vendor/xrpl/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
564
564
  synapse/vendor/xrpl/tests/test_codec.py,sha256=Zwq6A5uZUK_FWDL3BA932c5b-rL3hnC6efobWHSLC4o,6651
565
565
  synapse/vendor/xrpl/tests/test_main.py,sha256=kZQwWk7I6HrP-PMvLdsUUN4POvWD9I-iXDHOwdeF090,4299
566
566
  synapse/vendor/xrpl/tests/test_main_test_cases.py,sha256=vTlUM4hJD2Hd2wCIdd9rfsvcMZZZQmNHWdCTTFeGz2Y,4221
567
- synapse-2.168.0.dist-info/LICENSE,sha256=xllut76FgcGL5zbIRvuRc7aezPbvlMUTWJPsVr2Sugg,11358
568
- synapse-2.168.0.dist-info/METADATA,sha256=hpyJSpbWPbvPgMIefUR3jFm1IjtR1Pvg_-9O9oF7VKE,4921
569
- synapse-2.168.0.dist-info/WHEEL,sha256=d-ss0RGbiSJGQggaPntAAFgCBIav_4d8GZcRrfBnZg4,94
570
- synapse-2.168.0.dist-info/top_level.txt,sha256=v_1YsqjmoSCzCKs7oIhzTNmWtSYoORiBMv1TJkOhx8A,8
571
- synapse-2.168.0.dist-info/RECORD,,
567
+ synapse-2.169.0.dist-info/LICENSE,sha256=xllut76FgcGL5zbIRvuRc7aezPbvlMUTWJPsVr2Sugg,11358
568
+ synapse-2.169.0.dist-info/METADATA,sha256=YcAKw0S-MTmIlQ4ng4R_PHSFYsQZqMol3E7wh6ggqaE,4921
569
+ synapse-2.169.0.dist-info/WHEEL,sha256=d-ss0RGbiSJGQggaPntAAFgCBIav_4d8GZcRrfBnZg4,94
570
+ synapse-2.169.0.dist-info/top_level.txt,sha256=v_1YsqjmoSCzCKs7oIhzTNmWtSYoORiBMv1TJkOhx8A,8
571
+ synapse-2.169.0.dist-info/RECORD,,