flow.record 3.15.dev9__tar.gz → 3.15.dev12__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.
Files changed (81) hide show
  1. {flow.record-3.15.dev9/flow.record.egg-info → flow.record-3.15.dev12}/PKG-INFO +1 -1
  2. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/base.py +12 -0
  3. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/version.py +2 -2
  4. {flow.record-3.15.dev9 → flow.record-3.15.dev12/flow.record.egg-info}/PKG-INFO +1 -1
  5. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/pyproject.toml +1 -1
  6. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_record.py +66 -0
  7. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/COPYRIGHT +0 -0
  8. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/LICENSE +0 -0
  9. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/MANIFEST.in +0 -0
  10. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/README.md +0 -0
  11. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/examples/filesystem.py +0 -0
  12. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/examples/passivedns.py +0 -0
  13. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/examples/records.json +0 -0
  14. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/examples/tcpconn.py +0 -0
  15. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/__init__.py +0 -0
  16. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/__init__.py +0 -0
  17. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/archive.py +0 -0
  18. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/avro.py +0 -0
  19. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/broker.py +0 -0
  20. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/csvfile.py +0 -0
  21. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/duckdb.py +0 -0
  22. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/elastic.py +0 -0
  23. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/jsonfile.py +0 -0
  24. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/line.py +0 -0
  25. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/mongo.py +0 -0
  26. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/split.py +0 -0
  27. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/splunk.py +0 -0
  28. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/sqlite.py +0 -0
  29. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/stream.py +0 -0
  30. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/text.py +0 -0
  31. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/xlsx.py +0 -0
  32. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/exceptions.py +0 -0
  33. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/__init__.py +0 -0
  34. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/credential.py +0 -0
  35. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/net/__init__.py +0 -0
  36. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/net/ip.py +0 -0
  37. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/net/ipv4.py +0 -0
  38. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/net/tcp.py +0 -0
  39. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/net/udp.py +0 -0
  40. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/jsonpacker.py +0 -0
  41. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/packer.py +0 -0
  42. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/selector.py +0 -0
  43. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/stream.py +0 -0
  44. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/tools/__init__.py +0 -0
  45. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/tools/geoip.py +0 -0
  46. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/tools/rdump.py +0 -0
  47. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/utils.py +0 -0
  48. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/whitelist.py +0 -0
  49. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow.record.egg-info/SOURCES.txt +0 -0
  50. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow.record.egg-info/dependency_links.txt +0 -0
  51. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow.record.egg-info/entry_points.txt +0 -0
  52. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow.record.egg-info/requires.txt +0 -0
  53. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow.record.egg-info/top_level.txt +0 -0
  54. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/setup.cfg +0 -0
  55. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/__init__.py +0 -0
  56. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/_utils.py +0 -0
  57. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/docs/Makefile +0 -0
  58. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/docs/conf.py +0 -0
  59. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/docs/index.rst +0 -0
  60. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/selector_explain_example.py +0 -0
  61. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/standalone_test.py +0 -0
  62. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_avro.py +0 -0
  63. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_avro_adapter.py +0 -0
  64. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_compiled_selector.py +0 -0
  65. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_csv_adapter.py +0 -0
  66. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_deprecations.py +0 -0
  67. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_fieldtype_ip.py +0 -0
  68. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_fieldtypes.py +0 -0
  69. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_json_packer.py +0 -0
  70. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_json_record_adapter.py +0 -0
  71. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_multi_timestamp.py +0 -0
  72. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_packer.py +0 -0
  73. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_rdump.py +0 -0
  74. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_record_adapter.py +0 -0
  75. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_record_descriptor.py +0 -0
  76. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_regression.py +0 -0
  77. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_selector.py +0 -0
  78. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_splunk_adapter.py +0 -0
  79. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_sqlite_duckdb_adapter.py +0 -0
  80. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/utils_inspect.py +0 -0
  81. {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flow.record
3
- Version: 3.15.dev9
3
+ Version: 3.15.dev12
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
@@ -12,6 +12,7 @@ import os
12
12
  import re
13
13
  import sys
14
14
  import warnings
15
+ from contextlib import contextmanager
15
16
  from datetime import datetime, timezone
16
17
  from itertools import zip_longest
17
18
  from pathlib import Path
@@ -118,6 +119,17 @@ def set_ignored_fields_for_comparison(ignored_fields: Iterable[str]) -> None:
118
119
  IGNORE_FIELDS_FOR_COMPARISON = set(ignored_fields)
119
120
 
120
121
 
122
+ @contextmanager
123
+ def ignore_fields_for_comparison(ignored_fields: Iterable[str]):
124
+ """Context manager to temporarily ignore fields for comparison."""
125
+ original_ignored_fields = IGNORE_FIELDS_FOR_COMPARISON
126
+ try:
127
+ set_ignored_fields_for_comparison(ignored_fields)
128
+ yield
129
+ finally:
130
+ set_ignored_fields_for_comparison(original_ignored_fields)
131
+
132
+
121
133
  class FieldType:
122
134
  def _typename(self):
123
135
  t = type(self)
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '3.15.dev9'
16
- __version_tuple__ = version_tuple = (3, 15, 'dev9')
15
+ __version__ = version = '3.15.dev12'
16
+ __version_tuple__ = version_tuple = (3, 15, 'dev12')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flow.record
3
- Version: 3.15.dev9
3
+ Version: 3.15.dev12
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
@@ -79,4 +79,4 @@ include = ["flow.*"]
79
79
 
80
80
  [tool.setuptools_scm]
81
81
  local_scheme = "no-local-version"
82
- write_to = "flow/record/version.py"
82
+ version_file = "flow/record/version.py"
@@ -19,6 +19,7 @@ from flow.record import (
19
19
  record_stream,
20
20
  )
21
21
  from flow.record.base import (
22
+ ignore_fields_for_comparison,
22
23
  merge_record_descriptors,
23
24
  normalize_fieldname,
24
25
  set_ignored_fields_for_comparison,
@@ -856,3 +857,68 @@ def test_compare_environment_variable():
856
857
  assert same_same == but_still_same
857
858
  assert same_same != but_different
858
859
  assert len(set(records)) == 2
860
+
861
+
862
+ def test_ignore_fields_for_comparision_contextmanager():
863
+ TestRecord = RecordDescriptor(
864
+ "test/record",
865
+ [
866
+ ("string", "firstname"),
867
+ ("string", "lastname"),
868
+ ("string", "movie"),
869
+ ],
870
+ )
871
+ records = [
872
+ TestRecord("John", "Rambo", "First Blood"),
873
+ TestRecord("John", "Rambo", "Rambo: First Blood Part II"),
874
+ TestRecord("John", "Rambo", "Rambo III"),
875
+ TestRecord("John", "Rambo", "Rambo"),
876
+ TestRecord("John", "Rambo", "Rambo: Last Blood"),
877
+ TestRecord("Johnny", "English", "Johnny English"),
878
+ TestRecord("Johnny", "English", "Johnny English Strikes Again"),
879
+ TestRecord("John", "McClane", "Die Hard"),
880
+ TestRecord("John", "McClane", "Die Hard 2"),
881
+ TestRecord("John", "McClane", "Die Hard with a Vengeance"),
882
+ TestRecord("John", "McClane", "Live Free or Die Hard"),
883
+ TestRecord("John", "McClane", "A Good Day to Die Hard"),
884
+ TestRecord("John", "Wick", "John Wick"),
885
+ TestRecord("John", "Wick", "John Wick: Chapter 2"),
886
+ TestRecord("John", "Wick", "John Wick: Chapter 3 - Parabellum"),
887
+ ]
888
+
889
+ with ignore_fields_for_comparison({"_generated", "lastname", "movie"}):
890
+ # unique by firstname
891
+ first_name_records = set(records)
892
+ firstnames = [first_name.firstname for first_name in first_name_records]
893
+ assert len(first_name_records) == 2
894
+ assert firstnames.count("John") == 1
895
+ assert firstnames.count("Johnny") == 1
896
+ assert records[0] == records[1]
897
+
898
+ # test nested context manager
899
+ with ignore_fields_for_comparison({"_generated", "firstname", "movie"}):
900
+ # unique by lastname
901
+ last_name_records = set(records)
902
+ lastnames = [last_name.lastname for last_name in last_name_records]
903
+ assert len(lastnames) == 4
904
+ assert lastnames.count("Rambo") == 1
905
+ assert lastnames.count("English") == 1
906
+ assert lastnames.count("McClane") == 1
907
+ assert lastnames.count("Wick") == 1
908
+ assert records[0] == records[1]
909
+
910
+ # test if the contextmanager properly resets the ignored fields
911
+ with ignore_fields_for_comparison({"_generated", "movie"}):
912
+ # unique by firstname + lastname
913
+ main_character_records = set(records)
914
+ main_characters = [f"{r.firstname} {r.lastname}" for r in main_character_records]
915
+ assert len(main_characters) == 4
916
+ assert main_characters.count("John Rambo") == 1
917
+ assert main_characters.count("Johnny English") == 1
918
+ assert main_characters.count("John McClane") == 1
919
+ assert main_characters.count("John Wick") == 1
920
+ assert records[0] == records[1]
921
+
922
+ # test reset again
923
+ assert len(set(records)) == len(records)
924
+ assert records[0] != records[1]