flow.record 3.21.dev8__tar.gz → 3.21.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.
Files changed (93) hide show
  1. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/PKG-INFO +4 -13
  2. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/elastic.py +1 -1
  3. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/jsonpacker.py +2 -1
  4. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/version.py +3 -3
  5. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow.record.egg-info/PKG-INFO +4 -13
  6. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow.record.egg-info/requires.txt +3 -12
  7. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/pyproject.toml +60 -18
  8. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/adapter/test_splunk.py +2 -2
  9. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/adapter/test_sqlite_duckdb.py +2 -1
  10. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/packer/test_json_packer.py +26 -0
  11. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/record/test_record.py +1 -1
  12. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tox.ini +4 -8
  13. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/.git-blame-ignore-revs +0 -0
  14. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/.gitattributes +0 -0
  15. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/COPYRIGHT +0 -0
  16. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/LICENSE +0 -0
  17. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/MANIFEST.in +0 -0
  18. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/README.md +0 -0
  19. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/examples/__init__.py +0 -0
  20. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/examples/filesystem.py +0 -0
  21. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/examples/passivedns.py +0 -0
  22. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/examples/records.json +0 -0
  23. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/examples/selectors.py +0 -0
  24. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/examples/tcpconn.py +0 -0
  25. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/__init__.py +0 -0
  26. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/__init__.py +0 -0
  27. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/archive.py +0 -0
  28. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/avro.py +0 -0
  29. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/broker.py +0 -0
  30. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/csvfile.py +0 -0
  31. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/duckdb.py +0 -0
  32. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/jsonfile.py +0 -0
  33. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/line.py +0 -0
  34. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/mongo.py +0 -0
  35. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/split.py +0 -0
  36. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/splunk.py +0 -0
  37. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/sqlite.py +0 -0
  38. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/stream.py +0 -0
  39. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/text.py +0 -0
  40. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/adapter/xlsx.py +0 -0
  41. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/base.py +0 -0
  42. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/exceptions.py +0 -0
  43. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/fieldtypes/__init__.py +0 -0
  44. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/fieldtypes/credential.py +0 -0
  45. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/fieldtypes/net/__init__.py +0 -0
  46. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/fieldtypes/net/ip.py +0 -0
  47. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/fieldtypes/net/ipv4.py +0 -0
  48. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/fieldtypes/net/tcp.py +0 -0
  49. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/fieldtypes/net/udp.py +0 -0
  50. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/packer.py +0 -0
  51. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/selector.py +0 -0
  52. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/stream.py +0 -0
  53. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/tools/__init__.py +0 -0
  54. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/tools/geoip.py +0 -0
  55. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/tools/rdump.py +0 -0
  56. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/utils.py +0 -0
  57. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow/record/whitelist.py +0 -0
  58. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow.record.egg-info/SOURCES.txt +0 -0
  59. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow.record.egg-info/dependency_links.txt +0 -0
  60. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow.record.egg-info/entry_points.txt +0 -0
  61. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/flow.record.egg-info/top_level.txt +0 -0
  62. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/setup.cfg +0 -0
  63. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/__init__.py +0 -0
  64. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/_data/.gitkeep +0 -0
  65. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/_docs/Makefile +0 -0
  66. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/_docs/conf.py +0 -0
  67. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/_docs/index.rst +0 -0
  68. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/_utils.py +0 -0
  69. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/adapter/__init__.py +0 -0
  70. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/adapter/test_avro.py +0 -0
  71. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/adapter/test_csv.py +0 -0
  72. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/adapter/test_elastic.py +0 -0
  73. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/adapter/test_json.py +0 -0
  74. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/adapter/test_line.py +0 -0
  75. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/adapter/test_text.py +0 -0
  76. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/adapter/test_xlsx.py +0 -0
  77. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/fieldtypes/__init__.py +0 -0
  78. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/fieldtypes/test_fieldtypes.py +0 -0
  79. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/fieldtypes/test_ip.py +0 -0
  80. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/packer/__init__.py +0 -0
  81. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/packer/test_packer.py +0 -0
  82. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/record/__init__.py +0 -0
  83. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/record/test_adapter.py +0 -0
  84. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/record/test_descriptor.py +0 -0
  85. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/record/test_multi_timestamp.py +0 -0
  86. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/selector/__init__.py +0 -0
  87. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/selector/test_compiled.py +0 -0
  88. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/selector/test_selectors.py +0 -0
  89. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/test_deprecations.py +0 -0
  90. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/test_regressions.py +0 -0
  91. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/test_utils.py +0 -0
  92. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/tools/__init__.py +0 -0
  93. {flow_record-3.21.dev8 → flow_record-3.21.dev10}/tests/tools/test_rdump.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flow.record
3
- Version: 3.21.dev8
3
+ Version: 3.21.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
- License: Affero General Public License v3
6
+ License-Expression: AGPL-3.0-or-later
7
7
  Project-URL: homepage, https://dissect.tools
8
8
  Project-URL: documentation, https://docs.dissect.tools/en/latest/projects/flow.record
9
9
  Project-URL: repository, https://github.com/fox-it/flow.record
@@ -11,12 +11,11 @@ Classifier: Development Status :: 5 - Production/Stable
11
11
  Classifier: Environment :: Console
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Intended Audience :: Information Technology
14
- Classifier: License :: OSI Approved
15
14
  Classifier: Operating System :: OS Independent
16
15
  Classifier: Programming Language :: Python :: 3
17
16
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
18
17
  Classifier: Topic :: Utilities
19
- Requires-Python: ~=3.9
18
+ Requires-Python: >=3.9.0
20
19
  Description-Content-Type: text/markdown
21
20
  License-File: LICENSE
22
21
  License-File: COPYRIGHT
@@ -25,6 +24,7 @@ Requires-Dist: tzdata; platform_system == "Windows"
25
24
  Provides-Extra: compression
26
25
  Requires-Dist: lz4; extra == "compression"
27
26
  Requires-Dist: zstandard; extra == "compression"
27
+ Requires-Dist: zstandard==0.23.0; (platform_python_implementation == "PyPy" and python_version == "3.9") and extra == "compression"
28
28
  Provides-Extra: elastic
29
29
  Requires-Dist: elasticsearch; extra == "elastic"
30
30
  Provides-Extra: geoip
@@ -39,15 +39,6 @@ Provides-Extra: splunk
39
39
  Requires-Dist: httpx; extra == "splunk"
40
40
  Provides-Extra: xlsx
41
41
  Requires-Dist: openpyxl; extra == "xlsx"
42
- Provides-Extra: test
43
- Requires-Dist: flow.record[compression]; extra == "test"
44
- Requires-Dist: flow.record[avro]; extra == "test"
45
- Requires-Dist: flow.record[elastic]; extra == "test"
46
- Requires-Dist: flow.record[xlsx]; extra == "test"
47
- Requires-Dist: duckdb; (platform_python_implementation != "PyPy" and python_version < "3.12") and extra == "test"
48
- Requires-Dist: pytz; (platform_python_implementation != "PyPy" and python_version < "3.12") and extra == "test"
49
- Requires-Dist: tqdm; extra == "test"
50
- Requires-Dist: structlog; extra == "test"
51
42
  Provides-Extra: full
52
43
  Requires-Dist: flow.record[compression]; extra == "full"
53
44
  Requires-Dist: tqdm; extra == "full"
@@ -287,6 +287,6 @@ def enrich_elastic_exception(exception: Exception) -> Exception:
287
287
  error_str = ", ".join(errors)
288
288
  original_message = exception.args[0] if exception.args else ""
289
289
  new_message = f"{original_message} {error_str}"
290
- exception.args = (new_message,) + exception.args[1:]
290
+ exception.args = (new_message, *exception.args[1:])
291
291
 
292
292
  return exception
@@ -97,7 +97,8 @@ class JsonRecordPacker:
97
97
  del obj["_type"]
98
98
  for field_type, field_name in record_descriptor.get_field_tuples():
99
99
  if field_type == "bytes":
100
- obj[field_name] = base64.b64decode(obj[field_name])
100
+ value = obj[field_name]
101
+ obj[field_name] = base64.b64decode(value) if value is not None else None
101
102
  return record_descriptor.recordType(**obj)
102
103
  if _type == "recorddescriptor":
103
104
  data = obj["_data"]
@@ -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.21.dev8'
32
- __version_tuple__ = version_tuple = (3, 21, 'dev8')
31
+ __version__ = version = '3.21.dev10'
32
+ __version_tuple__ = version_tuple = (3, 21, 'dev10')
33
33
 
34
- __commit_id__ = commit_id = 'g820113cc3'
34
+ __commit_id__ = commit_id = 'g04aec16c5'
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flow.record
3
- Version: 3.21.dev8
3
+ Version: 3.21.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
- License: Affero General Public License v3
6
+ License-Expression: AGPL-3.0-or-later
7
7
  Project-URL: homepage, https://dissect.tools
8
8
  Project-URL: documentation, https://docs.dissect.tools/en/latest/projects/flow.record
9
9
  Project-URL: repository, https://github.com/fox-it/flow.record
@@ -11,12 +11,11 @@ Classifier: Development Status :: 5 - Production/Stable
11
11
  Classifier: Environment :: Console
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Intended Audience :: Information Technology
14
- Classifier: License :: OSI Approved
15
14
  Classifier: Operating System :: OS Independent
16
15
  Classifier: Programming Language :: Python :: 3
17
16
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
18
17
  Classifier: Topic :: Utilities
19
- Requires-Python: ~=3.9
18
+ Requires-Python: >=3.9.0
20
19
  Description-Content-Type: text/markdown
21
20
  License-File: LICENSE
22
21
  License-File: COPYRIGHT
@@ -25,6 +24,7 @@ Requires-Dist: tzdata; platform_system == "Windows"
25
24
  Provides-Extra: compression
26
25
  Requires-Dist: lz4; extra == "compression"
27
26
  Requires-Dist: zstandard; extra == "compression"
27
+ Requires-Dist: zstandard==0.23.0; (platform_python_implementation == "PyPy" and python_version == "3.9") and extra == "compression"
28
28
  Provides-Extra: elastic
29
29
  Requires-Dist: elasticsearch; extra == "elastic"
30
30
  Provides-Extra: geoip
@@ -39,15 +39,6 @@ Provides-Extra: splunk
39
39
  Requires-Dist: httpx; extra == "splunk"
40
40
  Provides-Extra: xlsx
41
41
  Requires-Dist: openpyxl; extra == "xlsx"
42
- Provides-Extra: test
43
- Requires-Dist: flow.record[compression]; extra == "test"
44
- Requires-Dist: flow.record[avro]; extra == "test"
45
- Requires-Dist: flow.record[elastic]; extra == "test"
46
- Requires-Dist: flow.record[xlsx]; extra == "test"
47
- Requires-Dist: duckdb; (platform_python_implementation != "PyPy" and python_version < "3.12") and extra == "test"
48
- Requires-Dist: pytz; (platform_python_implementation != "PyPy" and python_version < "3.12") and extra == "test"
49
- Requires-Dist: tqdm; extra == "test"
50
- Requires-Dist: structlog; extra == "test"
51
42
  Provides-Extra: full
52
43
  Requires-Dist: flow.record[compression]; extra == "full"
53
44
  Requires-Dist: tqdm; extra == "full"
@@ -13,6 +13,9 @@ cramjam<2.8.4
13
13
  lz4
14
14
  zstandard
15
15
 
16
+ [compression:platform_python_implementation == "PyPy" and python_version == "3.9"]
17
+ zstandard==0.23.0
18
+
16
19
  [duckdb]
17
20
  duckdb
18
21
  pytz
@@ -31,17 +34,5 @@ maxminddb
31
34
  [splunk]
32
35
  httpx
33
36
 
34
- [test]
35
- flow.record[compression]
36
- flow.record[avro]
37
- flow.record[elastic]
38
- flow.record[xlsx]
39
- tqdm
40
- structlog
41
-
42
- [test:platform_python_implementation != "PyPy" and python_version < "3.12"]
43
- duckdb
44
- pytz
45
-
46
37
  [xlsx]
47
38
  openpyxl
@@ -1,13 +1,14 @@
1
1
  [build-system]
2
- requires = ["setuptools>=65.5.0", "setuptools_scm[toml]>=6.4.0"]
2
+ requires = ["setuptools>=80.9.0", "setuptools_scm[toml]>=6.4.0"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "flow.record"
7
7
  description = "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"
8
8
  readme = "README.md"
9
- requires-python = "~=3.9"
10
- license.text = "Affero General Public License v3"
9
+ requires-python = ">=3.9.0"
10
+ license = "AGPL-3.0-or-later"
11
+ license-files = ["LICENSE", "COPYRIGHT"]
11
12
  authors = [
12
13
  {name = "Dissect Team", email = "dissect@fox-it.com"}
13
14
  ]
@@ -16,7 +17,6 @@ classifiers = [
16
17
  "Environment :: Console",
17
18
  "Intended Audience :: Developers",
18
19
  "Intended Audience :: Information Technology",
19
- "License :: OSI Approved",
20
20
  "Operating System :: OS Independent",
21
21
  "Programming Language :: Python :: 3",
22
22
  "Topic :: Scientific/Engineering :: Information Analysis",
@@ -38,6 +38,7 @@ repository = "https://github.com/fox-it/flow.record"
38
38
  compression = [
39
39
  "lz4",
40
40
  "zstandard",
41
+ "zstandard==0.23.0; platform_python_implementation == 'PyPy' and python_version == '3.9'", # Pin to last working for PyPy3.9
41
42
  ]
42
43
  elastic = [
43
44
  "elasticsearch",
@@ -46,7 +47,7 @@ geoip = [
46
47
  "maxminddb",
47
48
  ]
48
49
  avro = [
49
- "cramjam<2.8.4; platform_python_implementation == 'PyPy' and python_version == '3.9'",
50
+ "cramjam<2.8.4; platform_python_implementation == 'PyPy' and python_version == '3.9'", # Pin to last working for PyPy3.9
50
51
  "fastavro[snappy]",
51
52
  ]
52
53
  duckdb = [
@@ -59,16 +60,6 @@ splunk = [
59
60
  xlsx = [
60
61
  "openpyxl",
61
62
  ]
62
- test = [
63
- "flow.record[compression]",
64
- "flow.record[avro]",
65
- "flow.record[elastic]",
66
- "flow.record[xlsx]",
67
- "duckdb; platform_python_implementation != 'PyPy' and python_version < '3.12'", # duckdb
68
- "pytz; platform_python_implementation != 'PyPy' and python_version < '3.12'", # duckdb
69
- "tqdm",
70
- "structlog",
71
- ]
72
63
  full = [
73
64
  "flow.record[compression]",
74
65
  "tqdm",
@@ -130,12 +121,63 @@ ignore = ["E203", "B904", "UP024", "ANN002", "ANN003", "ANN204", "ANN401", "SIM1
130
121
  [tool.ruff.lint.isort]
131
122
  known-first-party = ["flow.record"]
132
123
 
133
- [tool.setuptools]
134
- license-files = ["LICENSE", "COPYRIGHT"]
135
-
136
124
  [tool.setuptools.packages.find]
137
125
  include = ["flow.*"]
138
126
 
139
127
  [tool.setuptools_scm]
140
128
  local_scheme = "no-local-version"
141
129
  version_file = "flow/record/version.py"
130
+
131
+ # This list is duplicated due to https://github.com/fox-it/flow.record/pull/182#discussion_r2284582481
132
+ [dependency-groups]
133
+ compression = [
134
+ "lz4",
135
+ "zstandard==0.23.0; platform_python_implementation == 'PyPy' and python_version == '3.9'", # Pin to last working for PyPy3.9
136
+ "zstandard",
137
+ ]
138
+ elastic = [
139
+ "elasticsearch",
140
+ ]
141
+ geoip = [
142
+ "maxminddb",
143
+ ]
144
+ avro = [
145
+ "cramjam<2.8.4; platform_python_implementation == 'PyPy' and python_version == '3.9'", # Pin to last working for PyPy3.9
146
+ "fastavro[snappy]",
147
+ ]
148
+ duckdb = [
149
+ "duckdb; platform_python_implementation != 'PyPy'", # Don't install duckdb on PyPy
150
+ "pytz; platform_python_implementation != 'PyPy'", # Don't install duckdb on PyPy
151
+ ]
152
+ splunk = [
153
+ "httpx",
154
+ ]
155
+ xlsx = [
156
+ "openpyxl",
157
+ ]
158
+ test = [
159
+ {include-group = "compression"},
160
+ {include-group = "avro"},
161
+ {include-group = "elastic"},
162
+ {include-group = "xlsx"},
163
+ {include-group = "duckdb"},
164
+ "tqdm",
165
+ "structlog",
166
+ "pytest",
167
+ ]
168
+ full = [
169
+ {include-group = "compression"},
170
+ "tqdm",
171
+ "structlog",
172
+ ]
173
+ build = [
174
+ "build",
175
+ ]
176
+ lint = [
177
+ "ruff==0.12.9",
178
+ "vermin",
179
+ ]
180
+ dev = [
181
+ {include-group = "test"},
182
+ {include-group = "lint"},
183
+ ]
@@ -339,7 +339,7 @@ def test_https_protocol_records_sourcetype(mock_httpx_package: MagicMock) -> Non
339
339
  if "flow.record.adapter.splunk" in sys.modules:
340
340
  del sys.modules["flow.record.adapter.splunk"]
341
341
 
342
- from flow.record.adapter.splunk import Protocol, SourceType, SplunkWriter
342
+ from flow.record.adapter.splunk import Protocol, SourceType, SplunkWriter # noqa: PLC0415
343
343
 
344
344
  with patch.object(
345
345
  flow.record.adapter.splunk,
@@ -387,7 +387,7 @@ def test_https_protocol_json_sourcetype(mock_httpx_package: MagicMock) -> None:
387
387
  if "flow.record.adapter.splunk" in sys.modules:
388
388
  del sys.modules["flow.record.adapter.splunk"]
389
389
 
390
- from flow.record.adapter.splunk import SplunkWriter
390
+ from flow.record.adapter.splunk import SplunkWriter # noqa: PLC0415
391
391
 
392
392
  with patch.object(
393
393
  flow.record.adapter.splunk,
@@ -169,11 +169,12 @@ def test_read_from_sqlite(tmp_path: Path, db: Database) -> None:
169
169
  """
170
170
  )
171
171
  for i in range(1, 30):
172
+ dt_isoformat = datetime(2023, 10, i, 13, 37, tzinfo=timezone.utc).isoformat()
172
173
  con.execute(
173
174
  """
174
175
  INSERT INTO 'test/record' VALUES (?, ?, ?, ?)
175
176
  """,
176
- (f"record{i}", f"foobar{i}".encode(), datetime(2023, 10, i, 13, 37, tzinfo=timezone.utc), 3.14 + i),
177
+ (f"record{i}", f"foobar{i}".encode(), dt_isoformat, 3.14 + i),
177
178
  )
178
179
 
179
180
  # Read the SQLite database using flow.record
@@ -112,3 +112,29 @@ def test_record_pack_surrogateescape() -> None:
112
112
 
113
113
  # pack the json string back to a record and make sure it is the same as before
114
114
  assert packer.unpack(data) == record
115
+
116
+
117
+ def test_json_packer_bytes_type() -> None:
118
+ TestRecord = RecordDescriptor(
119
+ "test/bytes",
120
+ [
121
+ ("bytes", "data"),
122
+ ],
123
+ )
124
+
125
+ packer = JsonRecordPacker()
126
+
127
+ record = TestRecord(b"hello world")
128
+ data = packer.pack(record)
129
+ assert data.startswith('{"data": "aGVsbG8gd29ybGQ="')
130
+ assert packer.unpack(data) == record
131
+
132
+ record = TestRecord(data=None)
133
+ data = packer.pack(record)
134
+ assert data.startswith('{"data": null')
135
+ assert packer.unpack(data) == record
136
+
137
+ record = TestRecord(data=b"")
138
+ data = packer.pack(record)
139
+ assert data.startswith('{"data": ""')
140
+ assert packer.unpack(data) == record
@@ -877,7 +877,7 @@ def test_compare_environment_variable() -> None:
877
877
 
878
878
  importlib.import_module("flow.record")
879
879
 
880
- from flow.record import IGNORE_FIELDS_FOR_COMPARISON, RecordDescriptor
880
+ from flow.record import IGNORE_FIELDS_FOR_COMPARISON, RecordDescriptor # noqa: PLC0415
881
881
 
882
882
  assert {"_generated", "lastname"} == IGNORE_FIELDS_FOR_COMPARISON
883
883
 
@@ -16,7 +16,7 @@ deps =
16
16
  pytest
17
17
  pytest-cov
18
18
  coverage
19
- extras = test
19
+ dependency_groups = test
20
20
  commands =
21
21
  # Capturing output will fail on pypy, possibly due to this issue: https://github.com/pytest-dev/pytest/issues/5502
22
22
  pytest --basetemp="{envtmpdir}" {posargs:--color=yes --capture=no --cov=flow --cov-report=term-missing -v tests}
@@ -25,24 +25,20 @@ commands =
25
25
 
26
26
  [testenv:build]
27
27
  package = skip
28
- deps =
29
- build
28
+ dependency_groups = build
30
29
  commands =
31
30
  pyproject-build
32
31
 
33
32
  [testenv:fix]
34
33
  package = skip
35
- deps =
36
- ruff==0.9.2
34
+ dependency_groups = lint
37
35
  commands =
38
36
  ruff check --fix flow tests
39
37
  ruff format flow tests
40
38
 
41
39
  [testenv:lint]
42
40
  package = skip
43
- deps =
44
- ruff==0.9.2
45
- vermin
41
+ dependency_groups = lint
46
42
  commands =
47
43
  ruff check flow tests
48
44
  vermin -t=3.9- --no-tips --lint flow tests