flow.record 3.22.dev9__tar.gz → 3.22.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.22.dev9 → flow_record-3.22.dev10}/PKG-INFO +1 -1
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/fieldtypes/__init__.py +1 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/version.py +3 -3
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow.record.egg-info/PKG-INFO +1 -1
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/fieldtypes/test_fieldtypes.py +81 -1
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/.git-blame-ignore-revs +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/.gitattributes +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/COPYRIGHT +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/LICENSE +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/MANIFEST.in +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/README.md +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/examples/__init__.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/examples/filesystem.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/examples/passivedns.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/examples/records.json +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/examples/selectors.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/examples/tcpconn.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/__init__.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/__init__.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/archive.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/avro.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/broker.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/csvfile.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/duckdb.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/elastic.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/jsonfile.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/line.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/mongo.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/split.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/splunk.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/sqlite.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/stream.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/text.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/adapter/xlsx.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/base.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/context.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/exceptions.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/fieldtypes/credential.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/fieldtypes/net/__init__.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/fieldtypes/net/ip.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/fieldtypes/net/ipv4.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/fieldtypes/net/tcp.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/fieldtypes/net/udp.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/jsonpacker.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/packer.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/selector.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/stream.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/tools/__init__.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/tools/geoip.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/tools/rdump.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/utils.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow/record/whitelist.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow.record.egg-info/SOURCES.txt +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow.record.egg-info/dependency_links.txt +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow.record.egg-info/entry_points.txt +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow.record.egg-info/requires.txt +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/flow.record.egg-info/top_level.txt +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/pyproject.toml +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/setup.cfg +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/__init__.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/_data/.gitkeep +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/_docs/Makefile +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/_docs/conf.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/_docs/index.rst +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/_utils.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/adapter/__init__.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/adapter/test_avro.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/adapter/test_csv.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/adapter/test_elastic.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/adapter/test_json.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/adapter/test_line.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/adapter/test_splunk.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/adapter/test_sqlite_duckdb.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/adapter/test_text.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/adapter/test_xlsx.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/conftest.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/fieldtypes/__init__.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/fieldtypes/test_boolean.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/fieldtypes/test_ip.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/packer/__init__.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/packer/test_json_packer.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/packer/test_packer.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/record/__init__.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/record/test_adapter.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/record/test_context.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/record/test_descriptor.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/record/test_multi_timestamp.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/record/test_record.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/selector/__init__.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/selector/test_compiled.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/selector/test_selectors.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/test_deprecations.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/test_regressions.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/test_utils.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/tools/__init__.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tests/tools/test_rdump.py +0 -0
- {flow_record-3.22.dev9 → flow_record-3.22.dev10}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flow.record
|
|
3
|
-
Version: 3.22.
|
|
3
|
+
Version: 3.22.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-Expression: AGPL-3.0-or-later
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '3.22.
|
|
32
|
-
__version_tuple__ = version_tuple = (3, 22, '
|
|
31
|
+
__version__ = version = '3.22.dev10'
|
|
32
|
+
__version_tuple__ = version_tuple = (3, 22, 'dev10')
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'ga594c193b'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flow.record
|
|
3
|
-
Version: 3.22.
|
|
3
|
+
Version: 3.22.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-Expression: AGPL-3.0-or-later
|
|
@@ -13,6 +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
|
+
HAS_ZONE_INFO,
|
|
16
17
|
PY_312_OR_HIGHER,
|
|
17
18
|
PY_313_OR_HIGHER,
|
|
18
19
|
TYPE_POSIX,
|
|
@@ -28,6 +29,9 @@ from flow.record.fieldtypes import (
|
|
|
28
29
|
)
|
|
29
30
|
from flow.record.fieldtypes import datetime as dt
|
|
30
31
|
|
|
32
|
+
if HAS_ZONE_INFO:
|
|
33
|
+
from flow.record.fieldtypes import ZoneInfo
|
|
34
|
+
|
|
31
35
|
if TYPE_CHECKING:
|
|
32
36
|
from collections.abc import Callable
|
|
33
37
|
|
|
@@ -427,7 +431,7 @@ def test_datetime() -> None:
|
|
|
427
431
|
("2006-11-10T14:29:55.585192699999999-07:00", datetime(2006, 11, 10, 21, 29, 55, 585192, tzinfo=UTC)),
|
|
428
432
|
],
|
|
429
433
|
)
|
|
430
|
-
def test_datetime_formats(tmp_path: pathlib.Path, value: str, expected_dt: datetime) -> None:
|
|
434
|
+
def test_datetime_formats(tmp_path: pathlib.Path, value: str | datetime | float, expected_dt: datetime) -> None:
|
|
431
435
|
TestRecord = RecordDescriptor(
|
|
432
436
|
"test/datetime",
|
|
433
437
|
[
|
|
@@ -448,6 +452,82 @@ def test_datetime_formats(tmp_path: pathlib.Path, value: str, expected_dt: datet
|
|
|
448
452
|
assert record.dt == expected_dt
|
|
449
453
|
|
|
450
454
|
|
|
455
|
+
DATETIME_FOLD_PARAMS = [
|
|
456
|
+
(datetime(2023, 1, 1, tzinfo=UTC, fold=1), datetime(2023, 1, 1, tzinfo=UTC)),
|
|
457
|
+
]
|
|
458
|
+
if HAS_ZONE_INFO:
|
|
459
|
+
DATETIME_FOLD_PARAMS.append(
|
|
460
|
+
(
|
|
461
|
+
datetime(2025, 10, 26, 2, 0, 3, tzinfo=ZoneInfo("Europe/Amsterdam"), fold=1),
|
|
462
|
+
datetime(2025, 10, 26, 1, 0, 3, tzinfo=UTC),
|
|
463
|
+
),
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
@pytest.mark.skipif(not HAS_ZONE_INFO, reason="ZoneInfo is required for testing datetime fold parameter")
|
|
468
|
+
@pytest.mark.parametrize(("value", "expected_dt"), DATETIME_FOLD_PARAMS)
|
|
469
|
+
def test_datetime_formats_fold(tmp_path: pathlib.Path, value: datetime, expected_dt: datetime) -> None:
|
|
470
|
+
"""test whether datetime accepts fold parameters and converts it correctly"""
|
|
471
|
+
TestRecord = RecordDescriptor(
|
|
472
|
+
"test/datetime",
|
|
473
|
+
[
|
|
474
|
+
("datetime", "dt"),
|
|
475
|
+
],
|
|
476
|
+
)
|
|
477
|
+
record = TestRecord(dt=value)
|
|
478
|
+
assert record.dt.fold == 1
|
|
479
|
+
assert record.dt.astimezone(UTC) == expected_dt
|
|
480
|
+
|
|
481
|
+
# test packing / serialization of datetime fields
|
|
482
|
+
path = tmp_path / "datetime.records"
|
|
483
|
+
with RecordWriter(path) as writer:
|
|
484
|
+
writer.write(record)
|
|
485
|
+
|
|
486
|
+
# test unpacking / deserialization of datetime fields
|
|
487
|
+
with RecordReader(path) as reader:
|
|
488
|
+
record = next(iter(reader))
|
|
489
|
+
# Need to convert it to UTC specifically as the timezones do not match
|
|
490
|
+
assert record.dt.astimezone(UTC) == expected_dt
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
@pytest.mark.skipif(not HAS_ZONE_INFO, reason="ZoneInfo is required for testing datetime fold parameter")
|
|
494
|
+
def test_datetime_fold_example() -> None:
|
|
495
|
+
"""
|
|
496
|
+
Test datetime fold parameter during daylight saving time changes in the Netherlands, which has a
|
|
497
|
+
timezone offset of +01:00 during wintertime and +02:00 during summertime.
|
|
498
|
+
"""
|
|
499
|
+
|
|
500
|
+
TestRecord = RecordDescriptor(
|
|
501
|
+
"test/datetime",
|
|
502
|
+
[
|
|
503
|
+
("datetime", "dt"),
|
|
504
|
+
],
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
# 2025-10-26 is the date of the end of daylight saving time in the Netherlands.
|
|
508
|
+
# At 3:00 AM the clock goes back to 2:00 AM, so 2:00 AM occurs twice. The first occurrence has fold=0
|
|
509
|
+
record = TestRecord("2025-10-26T00:00:00+00:00")
|
|
510
|
+
nl_dt = record.dt.astimezone(ZoneInfo("Europe/Amsterdam"))
|
|
511
|
+
assert nl_dt.isoformat() == "2025-10-26T02:00:00+02:00"
|
|
512
|
+
assert nl_dt.hour == 2
|
|
513
|
+
assert nl_dt.fold == 0
|
|
514
|
+
|
|
515
|
+
# test that both datetimes are considered equal when converted to UTC
|
|
516
|
+
record2 = TestRecord(nl_dt)
|
|
517
|
+
assert record.dt.astimezone(UTC) == record2.dt.astimezone(UTC)
|
|
518
|
+
|
|
519
|
+
# wintertime, the clock goes back from 3:00 AM to 2:00 AM, so 2:00 AM occurs twice. The second occurrence has fold=1
|
|
520
|
+
record = TestRecord("2025-10-26T01:00:00+00:00")
|
|
521
|
+
nl_dt = record.dt.astimezone(ZoneInfo("Europe/Amsterdam"))
|
|
522
|
+
assert nl_dt.isoformat() == "2025-10-26T02:00:00+01:00"
|
|
523
|
+
assert nl_dt.hour == 2
|
|
524
|
+
assert nl_dt.fold == 1
|
|
525
|
+
|
|
526
|
+
# test that both datetimes are considered equal when converted to UTC
|
|
527
|
+
record2 = TestRecord(nl_dt)
|
|
528
|
+
assert record.dt.astimezone(UTC) == record2.dt.astimezone(UTC)
|
|
529
|
+
|
|
530
|
+
|
|
451
531
|
def test_digest() -> None:
|
|
452
532
|
TestRecord = RecordDescriptor(
|
|
453
533
|
"test/digest",
|
|
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
|
|
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
|