flow.record 3.16.dev8__tar.gz → 3.16.dev10__tar.gz
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.
- {flow_record-3.16.dev8/flow.record.egg-info → flow_record-3.16.dev10}/PKG-INFO +1 -1
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/fieldtypes/__init__.py +16 -8
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/selector.py +1 -24
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/version.py +2 -2
- {flow_record-3.16.dev8 → flow_record-3.16.dev10/flow.record.egg-info}/PKG-INFO +1 -1
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_fieldtypes.py +40 -2
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/COPYRIGHT +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/LICENSE +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/MANIFEST.in +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/README.md +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/examples/filesystem.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/examples/passivedns.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/examples/records.json +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/examples/tcpconn.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/__init__.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/__init__.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/archive.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/avro.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/broker.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/csvfile.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/duckdb.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/elastic.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/jsonfile.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/line.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/mongo.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/split.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/splunk.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/sqlite.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/stream.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/text.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/adapter/xlsx.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/base.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/exceptions.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/fieldtypes/credential.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/fieldtypes/net/__init__.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/fieldtypes/net/ip.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/fieldtypes/net/ipv4.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/fieldtypes/net/tcp.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/fieldtypes/net/udp.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/jsonpacker.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/packer.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/stream.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/tools/__init__.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/tools/geoip.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/tools/rdump.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/utils.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow/record/whitelist.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow.record.egg-info/SOURCES.txt +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow.record.egg-info/dependency_links.txt +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow.record.egg-info/entry_points.txt +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow.record.egg-info/requires.txt +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/flow.record.egg-info/top_level.txt +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/pyproject.toml +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/setup.cfg +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/__init__.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/_utils.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/docs/Makefile +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/docs/conf.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/docs/index.rst +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/selector_explain_example.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/standalone_test.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_avro.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_avro_adapter.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_compiled_selector.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_csv_adapter.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_deprecations.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_elastic_adapter.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_fieldtype_ip.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_json_packer.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_json_record_adapter.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_multi_timestamp.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_packer.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_rdump.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_record.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_record_adapter.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_record_descriptor.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_regression.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_selector.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_splunk_adapter.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/test_sqlite_duckdb_adapter.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tests/utils_inspect.py +0 -0
- {flow_record-3.16.dev8 → flow_record-3.16.dev10}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flow.record
|
|
3
|
-
Version: 3.16.
|
|
3
|
+
Version: 3.16.dev10
|
|
4
4
|
Summary: A library for defining and creating structured data (called records) that can be streamed to disk or piped to other tools that use flow.record
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License: Affero General Public License v3
|
|
@@ -32,8 +32,8 @@ NATIVE_UNICODE = isinstance("", str)
|
|
|
32
32
|
|
|
33
33
|
UTC = timezone.utc
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
PY_311_OR_HIGHER = sys.version_info >= (3, 11, 0)
|
|
36
|
+
PY_312_OR_HIGHER = sys.version_info >= (3, 12, 0)
|
|
37
37
|
|
|
38
38
|
TYPE_POSIX = 0
|
|
39
39
|
TYPE_WINDOWS = 1
|
|
@@ -288,7 +288,7 @@ class datetime(_dt, FieldType):
|
|
|
288
288
|
# - Python 3.10 and older requires "T" between date and time in fromisoformat()
|
|
289
289
|
#
|
|
290
290
|
# There are other incompatibilities, but we don't care about those for now.
|
|
291
|
-
if not
|
|
291
|
+
if not PY_311_OR_HIGHER:
|
|
292
292
|
# Convert Z to +00:00 so that fromisoformat() works correctly on Python 3.10 and older
|
|
293
293
|
if arg[-1] == "Z":
|
|
294
294
|
arg = arg[:-1] + "+00:00"
|
|
@@ -633,6 +633,8 @@ def _is_windowslike_path(path: Any):
|
|
|
633
633
|
|
|
634
634
|
|
|
635
635
|
class path(pathlib.PurePath, FieldType):
|
|
636
|
+
_empty_path = False
|
|
637
|
+
|
|
636
638
|
def __new__(cls, *args):
|
|
637
639
|
# This is modelled after pathlib.PurePath's __new__(), which means you
|
|
638
640
|
# will never get an instance of path, only instances of either
|
|
@@ -647,7 +649,7 @@ class path(pathlib.PurePath, FieldType):
|
|
|
647
649
|
for path_part in args:
|
|
648
650
|
if isinstance(path_part, pathlib.PureWindowsPath):
|
|
649
651
|
cls = windows_path
|
|
650
|
-
if not
|
|
652
|
+
if not PY_312_OR_HIGHER:
|
|
651
653
|
# For Python < 3.12, the (string) representation of a
|
|
652
654
|
# pathlib.PureWindowsPath is not round trip equivalent if a path
|
|
653
655
|
# starts with a \ or / followed by a drive letter, e.g.: \C:\...
|
|
@@ -670,7 +672,7 @@ class path(pathlib.PurePath, FieldType):
|
|
|
670
672
|
# This handles any custom PurePath based implementations that have a windows
|
|
671
673
|
# like path separator (\).
|
|
672
674
|
cls = windows_path
|
|
673
|
-
if not
|
|
675
|
+
if not PY_312_OR_HIGHER:
|
|
674
676
|
args = tuple(str(arg) for arg in args)
|
|
675
677
|
elif _is_posixlike_path(path_part):
|
|
676
678
|
# This handles any custom PurePath based implementations that don't have a
|
|
@@ -680,7 +682,7 @@ class path(pathlib.PurePath, FieldType):
|
|
|
680
682
|
continue
|
|
681
683
|
break
|
|
682
684
|
|
|
683
|
-
if
|
|
685
|
+
if PY_312_OR_HIGHER:
|
|
684
686
|
obj = super().__new__(cls)
|
|
685
687
|
else:
|
|
686
688
|
obj = cls._from_parts(args)
|
|
@@ -693,8 +695,8 @@ class path(pathlib.PurePath, FieldType):
|
|
|
693
695
|
def __eq__(self, other: Any) -> bool:
|
|
694
696
|
if isinstance(other, str):
|
|
695
697
|
return str(self) == other or self == self.__class__(other)
|
|
696
|
-
|
|
697
|
-
return
|
|
698
|
+
elif isinstance(other, self.__class__) and (self._empty_path or other._empty_path):
|
|
699
|
+
return self._empty_path == other._empty_path
|
|
698
700
|
return super().__eq__(other)
|
|
699
701
|
|
|
700
702
|
def __str__(self) -> str:
|
|
@@ -705,6 +707,12 @@ class path(pathlib.PurePath, FieldType):
|
|
|
705
707
|
def __repr__(self) -> str:
|
|
706
708
|
return repr(str(self))
|
|
707
709
|
|
|
710
|
+
@property
|
|
711
|
+
def parent(self):
|
|
712
|
+
if self._empty_path:
|
|
713
|
+
return self
|
|
714
|
+
return super().parent
|
|
715
|
+
|
|
708
716
|
def _pack(self):
|
|
709
717
|
path_type = TYPE_WINDOWS if isinstance(self, windows_path) else TYPE_POSIX
|
|
710
718
|
return (str(self), path_type)
|
|
@@ -17,25 +17,6 @@ except ImportError:
|
|
|
17
17
|
|
|
18
18
|
string_types = (str, type(""))
|
|
19
19
|
|
|
20
|
-
AST_NODE_S_TYPES = tuple(
|
|
21
|
-
filter(
|
|
22
|
-
None,
|
|
23
|
-
[
|
|
24
|
-
getattr(ast, "Str", None),
|
|
25
|
-
getattr(ast, "Bytes", None),
|
|
26
|
-
],
|
|
27
|
-
),
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
AST_NODE_VALUE_TYPES = tuple(
|
|
31
|
-
filter(
|
|
32
|
-
None,
|
|
33
|
-
[
|
|
34
|
-
getattr(ast, "NameConstant", None),
|
|
35
|
-
getattr(ast, "Constant", None),
|
|
36
|
-
],
|
|
37
|
-
),
|
|
38
|
-
)
|
|
39
20
|
|
|
40
21
|
AST_OPERATORS = {
|
|
41
22
|
ast.Add: operator.add,
|
|
@@ -581,11 +562,7 @@ class RecordContextMatcher:
|
|
|
581
562
|
return r
|
|
582
563
|
|
|
583
564
|
def _eval(self, node):
|
|
584
|
-
if isinstance(node, ast.
|
|
585
|
-
return node.n
|
|
586
|
-
elif isinstance(node, AST_NODE_S_TYPES):
|
|
587
|
-
return node.s
|
|
588
|
-
elif isinstance(node, AST_NODE_VALUE_TYPES):
|
|
565
|
+
if isinstance(node, ast.Constant):
|
|
589
566
|
return node.value
|
|
590
567
|
elif isinstance(node, ast.List):
|
|
591
568
|
return list(map(self.eval, node.elts))
|
|
@@ -12,5 +12,5 @@ __version__: str
|
|
|
12
12
|
__version_tuple__: VERSION_TUPLE
|
|
13
13
|
version_tuple: VERSION_TUPLE
|
|
14
14
|
|
|
15
|
-
__version__ = version = '3.16.
|
|
16
|
-
__version_tuple__ = version_tuple = (3, 16, '
|
|
15
|
+
__version__ = version = '3.16.dev10'
|
|
16
|
+
__version_tuple__ = version_tuple = (3, 16, 'dev10')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flow.record
|
|
3
|
-
Version: 3.16.
|
|
3
|
+
Version: 3.16.dev10
|
|
4
4
|
Summary: A library for defining and creating structured data (called records) that can be streamed to disk or piped to other tools that use flow.record
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License: Affero General Public License v3
|
|
@@ -13,7 +13,7 @@ import pytest
|
|
|
13
13
|
import flow.record.fieldtypes
|
|
14
14
|
from flow.record import RecordDescriptor, RecordReader, RecordWriter, fieldtypes
|
|
15
15
|
from flow.record.fieldtypes import (
|
|
16
|
-
|
|
16
|
+
PY_312_OR_HIGHER,
|
|
17
17
|
TYPE_POSIX,
|
|
18
18
|
TYPE_WINDOWS,
|
|
19
19
|
_is_posixlike_path,
|
|
@@ -543,7 +543,7 @@ def custom_pure_path(sep, altsep):
|
|
|
543
543
|
# The flavour property of Path's is replaced by a link to e.g.
|
|
544
544
|
# posixpath or ntpath.
|
|
545
545
|
# See also: https://github.com/python/cpython/issues/88302
|
|
546
|
-
if
|
|
546
|
+
if PY_312_OR_HIGHER:
|
|
547
547
|
|
|
548
548
|
class CustomFlavour:
|
|
549
549
|
def __new__(cls, *args, **kwargs):
|
|
@@ -1154,6 +1154,7 @@ def test_empty_path(path_cls) -> None:
|
|
|
1154
1154
|
assert p1._empty_path
|
|
1155
1155
|
assert str(p1) == ""
|
|
1156
1156
|
assert p1 != path_cls(".")
|
|
1157
|
+
assert path_cls(".") != p1
|
|
1157
1158
|
|
|
1158
1159
|
# initialize without any arguments
|
|
1159
1160
|
p2 = path_cls()
|
|
@@ -1161,6 +1162,7 @@ def test_empty_path(path_cls) -> None:
|
|
|
1161
1162
|
assert p2._empty_path
|
|
1162
1163
|
assert str(p2) == ""
|
|
1163
1164
|
assert p2 != path_cls(".")
|
|
1165
|
+
assert path_cls(".") != p2
|
|
1164
1166
|
|
|
1165
1167
|
assert p1 == p2
|
|
1166
1168
|
|
|
@@ -1213,5 +1215,41 @@ def test_empty_path_serialization(tmp_path) -> None:
|
|
|
1213
1215
|
assert record.value == ""
|
|
1214
1216
|
|
|
1215
1217
|
|
|
1218
|
+
def test_empty_windows_path_parent() -> None:
|
|
1219
|
+
# test that the parent of an empty path is also an empty path
|
|
1220
|
+
path = fieldtypes.windows_path("")
|
|
1221
|
+
assert path.parent == ""
|
|
1222
|
+
assert path.parent.parent == ""
|
|
1223
|
+
assert path._empty_path
|
|
1224
|
+
assert path.parent._empty_path
|
|
1225
|
+
assert list(path.parents) == []
|
|
1226
|
+
|
|
1227
|
+
path = fieldtypes.windows_path("c:/windows/temp")
|
|
1228
|
+
assert path.parent == "c:/windows"
|
|
1229
|
+
assert path.parent.parent == "c:/"
|
|
1230
|
+
assert path.parent.parent.parent == "c:/"
|
|
1231
|
+
assert not path.parent._empty_path
|
|
1232
|
+
assert not path._empty_path
|
|
1233
|
+
assert list(path.parents) == ["c:/windows", "c:/"]
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
def test_empty_posix_path_parent() -> None:
|
|
1237
|
+
# test that the parent of an empty path is also an empty path
|
|
1238
|
+
path = fieldtypes.posix_path("")
|
|
1239
|
+
assert path.parent == ""
|
|
1240
|
+
assert path.parent.parent == ""
|
|
1241
|
+
assert path._empty_path
|
|
1242
|
+
assert path.parent._empty_path
|
|
1243
|
+
assert list(path.parents) == []
|
|
1244
|
+
|
|
1245
|
+
path = fieldtypes.posix_path("/var/log")
|
|
1246
|
+
assert path.parent == "/var"
|
|
1247
|
+
assert path.parent.parent == "/"
|
|
1248
|
+
assert path.parent.parent.parent == "/"
|
|
1249
|
+
assert not path.parent._empty_path
|
|
1250
|
+
assert not path._empty_path
|
|
1251
|
+
assert list(path.parents) == ["/var", "/"]
|
|
1252
|
+
|
|
1253
|
+
|
|
1216
1254
|
if __name__ == "__main__":
|
|
1217
1255
|
__import__("standalone_test").main(globals())
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|