flow.record 3.17.dev6__tar.gz → 3.17.dev8__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 (84) hide show
  1. {flow_record-3.17.dev6/flow.record.egg-info → flow_record-3.17.dev8}/PKG-INFO +2 -3
  2. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/version.py +2 -2
  3. {flow_record-3.17.dev6 → flow_record-3.17.dev8/flow.record.egg-info}/PKG-INFO +2 -3
  4. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow.record.egg-info/requires.txt +0 -3
  5. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/pyproject.toml +1 -2
  6. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_fieldtypes.py +55 -35
  7. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tox.ini +1 -1
  8. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/COPYRIGHT +0 -0
  9. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/LICENSE +0 -0
  10. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/MANIFEST.in +0 -0
  11. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/README.md +0 -0
  12. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/examples/filesystem.py +0 -0
  13. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/examples/passivedns.py +0 -0
  14. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/examples/records.json +0 -0
  15. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/examples/tcpconn.py +0 -0
  16. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/__init__.py +0 -0
  17. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/__init__.py +0 -0
  18. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/archive.py +0 -0
  19. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/avro.py +0 -0
  20. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/broker.py +0 -0
  21. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/csvfile.py +0 -0
  22. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/duckdb.py +0 -0
  23. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/elastic.py +0 -0
  24. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/jsonfile.py +0 -0
  25. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/line.py +0 -0
  26. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/mongo.py +0 -0
  27. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/split.py +0 -0
  28. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/splunk.py +0 -0
  29. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/sqlite.py +0 -0
  30. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/stream.py +0 -0
  31. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/text.py +0 -0
  32. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/adapter/xlsx.py +0 -0
  33. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/base.py +0 -0
  34. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/exceptions.py +0 -0
  35. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/fieldtypes/__init__.py +0 -0
  36. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/fieldtypes/credential.py +0 -0
  37. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/fieldtypes/net/__init__.py +0 -0
  38. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/fieldtypes/net/ip.py +0 -0
  39. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/fieldtypes/net/ipv4.py +0 -0
  40. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/fieldtypes/net/tcp.py +0 -0
  41. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/fieldtypes/net/udp.py +0 -0
  42. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/jsonpacker.py +0 -0
  43. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/packer.py +0 -0
  44. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/selector.py +0 -0
  45. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/stream.py +0 -0
  46. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/tools/__init__.py +0 -0
  47. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/tools/geoip.py +0 -0
  48. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/tools/rdump.py +0 -0
  49. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/utils.py +0 -0
  50. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow/record/whitelist.py +0 -0
  51. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow.record.egg-info/SOURCES.txt +0 -0
  52. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow.record.egg-info/dependency_links.txt +0 -0
  53. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow.record.egg-info/entry_points.txt +0 -0
  54. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/flow.record.egg-info/top_level.txt +0 -0
  55. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/setup.cfg +0 -0
  56. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/__init__.py +0 -0
  57. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/_utils.py +0 -0
  58. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/docs/Makefile +0 -0
  59. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/docs/conf.py +0 -0
  60. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/docs/index.rst +0 -0
  61. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/selector_explain_example.py +0 -0
  62. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/standalone_test.py +0 -0
  63. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_adapter_line.py +0 -0
  64. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_adapter_text.py +0 -0
  65. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_avro.py +0 -0
  66. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_avro_adapter.py +0 -0
  67. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_compiled_selector.py +0 -0
  68. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_csv_adapter.py +0 -0
  69. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_deprecations.py +0 -0
  70. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_elastic_adapter.py +0 -0
  71. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_fieldtype_ip.py +0 -0
  72. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_json_packer.py +0 -0
  73. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_json_record_adapter.py +0 -0
  74. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_multi_timestamp.py +0 -0
  75. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_packer.py +0 -0
  76. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_rdump.py +0 -0
  77. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_record.py +0 -0
  78. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_record_adapter.py +0 -0
  79. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_record_descriptor.py +0 -0
  80. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_regression.py +0 -0
  81. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_selector.py +0 -0
  82. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_splunk_adapter.py +0 -0
  83. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_sqlite_duckdb_adapter.py +0 -0
  84. {flow_record-3.17.dev6 → flow_record-3.17.dev8}/tests/test_xlsx_adapter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flow.record
3
- Version: 3.17.dev6
3
+ Version: 3.17.dev8
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
@@ -16,12 +16,11 @@ Classifier: Operating System :: OS Independent
16
16
  Classifier: Programming Language :: Python :: 3
17
17
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
18
18
  Classifier: Topic :: Utilities
19
- Requires-Python: ~=3.8
19
+ Requires-Python: ~=3.9
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
22
  License-File: COPYRIGHT
23
23
  Requires-Dist: msgpack>=0.5.2
24
- Requires-Dist: backports.zoneinfo[tzdata]; python_version < "3.9"
25
24
  Requires-Dist: tzdata; platform_system == "Windows"
26
25
  Provides-Extra: compression
27
26
  Requires-Dist: lz4; extra == "compression"
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '3.17.dev6'
16
- __version_tuple__ = version_tuple = (3, 17, 'dev6')
15
+ __version__ = version = '3.17.dev8'
16
+ __version_tuple__ = version_tuple = (3, 17, 'dev8')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flow.record
3
- Version: 3.17.dev6
3
+ Version: 3.17.dev8
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
@@ -16,12 +16,11 @@ Classifier: Operating System :: OS Independent
16
16
  Classifier: Programming Language :: Python :: 3
17
17
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
18
18
  Classifier: Topic :: Utilities
19
- Requires-Python: ~=3.8
19
+ Requires-Python: ~=3.9
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
22
  License-File: COPYRIGHT
23
23
  Requires-Dist: msgpack>=0.5.2
24
- Requires-Dist: backports.zoneinfo[tzdata]; python_version < "3.9"
25
24
  Requires-Dist: tzdata; platform_system == "Windows"
26
25
  Provides-Extra: compression
27
26
  Requires-Dist: lz4; extra == "compression"
@@ -3,9 +3,6 @@ msgpack>=0.5.2
3
3
  [:platform_system == "Windows"]
4
4
  tzdata
5
5
 
6
- [:python_version < "3.9"]
7
- backports.zoneinfo[tzdata]
8
-
9
6
  [avro]
10
7
  fastavro[snappy]
11
8
 
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
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.8"
9
+ requires-python = "~=3.9"
10
10
  license.text = "Affero General Public License v3"
11
11
  authors = [
12
12
  {name = "Dissect Team", email = "dissect@fox-it.com"}
@@ -24,7 +24,6 @@ classifiers = [
24
24
  ]
25
25
  dependencies = [
26
26
  "msgpack>=0.5.2",
27
- "backports.zoneinfo[tzdata]; python_version<'3.9'",
28
27
  "tzdata; platform_system=='Windows'",
29
28
  ]
30
29
  dynamic = ["version"]
@@ -7,6 +7,7 @@ import pathlib
7
7
  import posixpath
8
8
  import types
9
9
  from datetime import datetime, timedelta, timezone
10
+ from typing import Callable
10
11
 
11
12
  import pytest
12
13
 
@@ -25,6 +26,7 @@ from flow.record.fieldtypes import (
25
26
  fieldtype_for_value,
26
27
  net,
27
28
  posix_command,
29
+ posix_path,
28
30
  uri,
29
31
  windows_command,
30
32
  windows_path,
@@ -42,7 +44,7 @@ UINT32_MAX = (1 << 32) - 1
42
44
  UINT16_MAX = (1 << 16) - 1
43
45
 
44
46
 
45
- def test_uint16():
47
+ def test_uint16() -> None:
46
48
  desc = RecordDescriptor(
47
49
  "test/uint16",
48
50
  [
@@ -66,7 +68,7 @@ def test_uint16():
66
68
  desc.recordType(UINT128_MAX)
67
69
 
68
70
 
69
- def test_uint32():
71
+ def test_uint32() -> None:
70
72
  TestRecord = RecordDescriptor(
71
73
  "test/uint32",
72
74
  [
@@ -91,7 +93,7 @@ def test_uint32():
91
93
  TestRecord(UINT128_MAX)
92
94
 
93
95
 
94
- def test_net_ipv4_address():
96
+ def test_net_ipv4_address() -> None:
95
97
  TestRecord = RecordDescriptor(
96
98
  "test/net/ipv4/address",
97
99
  [
@@ -119,7 +121,7 @@ def test_net_ipv4_address():
119
121
  assert r.ip is None
120
122
 
121
123
 
122
- def test_net_ipv4_subnet():
124
+ def test_net_ipv4_subnet() -> None:
123
125
  TestRecord = RecordDescriptor(
124
126
  "test/net/ipv4/subnet",
125
127
  [
@@ -162,7 +164,7 @@ def test_net_ipv4_subnet():
162
164
  excinfo.match(r"Not a valid subnet '192\.168\.0\.106/28', did you mean '192\.168\.0\.96/28' ?")
163
165
 
164
166
 
165
- def test_bytes():
167
+ def test_bytes() -> None:
166
168
  TestRecord = RecordDescriptor(
167
169
  "test/string",
168
170
  [
@@ -194,7 +196,7 @@ def test_bytes():
194
196
  assert r.body == b"HTTP/1.1 500 Error\r\n\r\nError"
195
197
 
196
198
 
197
- def test_string():
199
+ def test_string() -> None:
198
200
  TestRecord = RecordDescriptor(
199
201
  "test/string",
200
202
  [
@@ -217,7 +219,7 @@ def test_string():
217
219
  assert r.name == "Ré\udceamy"
218
220
 
219
221
 
220
- def test_wstring():
222
+ def test_wstring() -> None:
221
223
  # Behaves the same as test/string, only available for backwards compatibility purposes
222
224
  TestRecord = RecordDescriptor(
223
225
  "test/wstring",
@@ -230,7 +232,7 @@ def test_wstring():
230
232
  assert r.name == "Fox-IT"
231
233
 
232
234
 
233
- def test_typedlist():
235
+ def test_typedlist() -> None:
234
236
  TestRecord = RecordDescriptor(
235
237
  "test/typedlist",
236
238
  [
@@ -261,7 +263,7 @@ def test_typedlist():
261
263
  r = TestRecord(uint32_value=["a", "b", "c"])
262
264
 
263
265
 
264
- def test_stringlist():
266
+ def test_stringlist() -> None:
265
267
  TestRecord = RecordDescriptor(
266
268
  "test/string",
267
269
  [
@@ -277,7 +279,7 @@ def test_stringlist():
277
279
  assert r.value[0]
278
280
 
279
281
 
280
- def test_dictlist():
282
+ def test_dictlist() -> None:
281
283
  TestRecord = RecordDescriptor(
282
284
  "test/dictlist",
283
285
  [
@@ -294,7 +296,7 @@ def test_dictlist():
294
296
  assert r.hits[1]["b"] == 4
295
297
 
296
298
 
297
- def test_boolean():
299
+ def test_boolean() -> None:
298
300
  TestRecord = RecordDescriptor(
299
301
  "test/boolean",
300
302
  [
@@ -324,7 +326,7 @@ def test_boolean():
324
326
  r = TestRecord("True", "False")
325
327
 
326
328
 
327
- def test_float():
329
+ def test_float() -> None:
328
330
  TestRecord = RecordDescriptor(
329
331
  "test/float",
330
332
  [
@@ -353,7 +355,7 @@ def test_float():
353
355
  r = TestRecord("abc")
354
356
 
355
357
 
356
- def test_uri_type():
358
+ def test_uri_type() -> None:
357
359
  TestRecord = RecordDescriptor(
358
360
  "test/uri",
359
361
  [
@@ -396,7 +398,7 @@ def test_uri_type():
396
398
  assert r.path.dirname == "/usr/local/bin"
397
399
 
398
400
 
399
- def test_datetime():
401
+ def test_datetime() -> None:
400
402
  TestRecord = RecordDescriptor(
401
403
  "test/datetime",
402
404
  [
@@ -452,7 +454,7 @@ def test_datetime():
452
454
  ("2006-11-10T14:29:55.585192699999999-07:00", datetime(2006, 11, 10, 21, 29, 55, 585192, tzinfo=UTC)),
453
455
  ],
454
456
  )
455
- def test_datetime_formats(tmp_path, value, expected_dt):
457
+ def test_datetime_formats(tmp_path: pathlib.Path, value: str, expected_dt: datetime) -> None:
456
458
  TestRecord = RecordDescriptor(
457
459
  "test/datetime",
458
460
  [
@@ -473,7 +475,7 @@ def test_datetime_formats(tmp_path, value, expected_dt):
473
475
  assert record.dt == expected_dt
474
476
 
475
477
 
476
- def test_digest():
478
+ def test_digest() -> None:
477
479
  TestRecord = RecordDescriptor(
478
480
  "test/digest",
479
481
  [
@@ -530,7 +532,7 @@ def test_digest():
530
532
  excinfo.match(r".*Invalid MD5.*")
531
533
 
532
534
 
533
- def custom_pure_path(sep, altsep):
535
+ def custom_pure_path(sep: str, altsep: str) -> pathlib.PurePath:
534
536
  # Starting from Python 3.12, pathlib._Flavours are removed as you can
535
537
  # now properly subclass pathlib.Path
536
538
  # The flavour property of Path's is replaced by a link to e.g.
@@ -572,7 +574,7 @@ def custom_pure_path(sep, altsep):
572
574
  ("/foo/bar", False),
573
575
  ],
574
576
  )
575
- def test__is_posixlike_path(path_, is_posix):
577
+ def test__is_posixlike_path(path_: pathlib.PurePath | str, is_posix: bool) -> None:
576
578
  assert _is_posixlike_path(path_) == is_posix
577
579
 
578
580
 
@@ -587,11 +589,11 @@ def test__is_posixlike_path(path_, is_posix):
587
589
  ("/foo/bar", False),
588
590
  ],
589
591
  )
590
- def test__is_windowslike_path(path_, is_windows):
592
+ def test__is_windowslike_path(path_: pathlib.PurePath, is_windows: bool) -> None:
591
593
  assert _is_windowslike_path(path_) == is_windows
592
594
 
593
595
 
594
- def test_path():
596
+ def test_path() -> None:
595
597
  TestRecord = RecordDescriptor(
596
598
  "test/path",
597
599
  [
@@ -688,7 +690,9 @@ def test_path():
688
690
  ),
689
691
  ],
690
692
  )
691
- def test_path_multiple_parts(path_parts, expected_instance):
693
+ def test_path_multiple_parts(
694
+ path_parts: tuple[str | pathlib.PurePath, ...], expected_instance: type[pathlib.PurePath]
695
+ ) -> None:
692
696
  assert isinstance(flow.record.fieldtypes.path(*path_parts), expected_instance)
693
697
 
694
698
 
@@ -708,7 +712,7 @@ def test_path_multiple_parts(path_parts, expected_instance):
708
712
  ("user/.bash_history", "user/.bash_history"),
709
713
  ],
710
714
  )
711
- def test_path_posix(path_initializer, path, expected_repr):
715
+ def test_path_posix(path_initializer: Callable[[str], pathlib.PurePath], path: str, expected_repr: str) -> None:
712
716
  TestRecord = RecordDescriptor(
713
717
  "test/path",
714
718
  [
@@ -754,7 +758,9 @@ def test_path_posix(path_initializer, path, expected_repr):
754
758
  ("c:\\my'quotes\".txt", "'c:\\my\\'quotes\".txt'", "c:\\my'quotes\".txt"),
755
759
  ],
756
760
  )
757
- def test_path_windows(path_initializer, path, expected_repr, expected_str):
761
+ def test_path_windows(
762
+ path_initializer: Callable[[str], pathlib.PurePath], path: str, expected_repr: str, expected_str: str
763
+ ) -> None:
758
764
  TestRecord = RecordDescriptor(
759
765
  "test/path",
760
766
  [
@@ -767,16 +773,28 @@ def test_path_windows(path_initializer, path, expected_repr, expected_str):
767
773
  assert str(record.path) == expected_str
768
774
 
769
775
 
770
- def test_windows_path_eq():
776
+ def test_windows_path_eq() -> None:
771
777
  path = windows_path("c:\\windows\\test.exe")
772
778
  assert path == "c:\\windows\\test.exe"
773
779
  assert path == "c:/windows/test.exe"
774
780
  assert path == "c:/windows\\test.exe"
775
781
  assert path == "c:\\WINDOWS\\tEsT.ExE"
776
782
  assert path != "c:/windows\\test2.exe"
783
+ assert path == windows_path("c:\\windows\\test.exe")
784
+ assert path != posix_path("c:\\windows\\test.exe")
777
785
 
778
786
 
779
- def test_fieldtype_for_value():
787
+ def test_posix_path_eq() -> None:
788
+ path = posix_path("/usr/local/bin/test")
789
+ assert path == "/usr/local/bin/test"
790
+ assert path != "\\usr\\local\\bin\\test"
791
+ assert path != "/usr/local/bin/test2"
792
+ assert path != "/uSr/lOcAl/bIn/tEst"
793
+ assert path == posix_path("/usr/local/bin/test")
794
+ assert path != windows_path("/usr/local/bin/test2")
795
+
796
+
797
+ def test_fieldtype_for_value() -> None:
780
798
  assert fieldtype_for_value(True) == "boolean"
781
799
  assert fieldtype_for_value(False) == "boolean"
782
800
  assert fieldtype_for_value(1337) == "varint"
@@ -790,7 +808,7 @@ def test_fieldtype_for_value():
790
808
  assert fieldtype_for_value(pathlib.PurePosixPath("/foo/bar.py")) == "path"
791
809
 
792
810
 
793
- def test_dynamic():
811
+ def test_dynamic() -> None:
794
812
  TestRecord = RecordDescriptor(
795
813
  "test/dynamic",
796
814
  [
@@ -852,7 +870,7 @@ def test_dynamic():
852
870
  ),
853
871
  ],
854
872
  )
855
- def test_format_defang(record_type, value, expected):
873
+ def test_format_defang(record_type: str, value: str, expected: str) -> None:
856
874
  TestRecord = RecordDescriptor(
857
875
  "test/format/defang",
858
876
  [
@@ -877,7 +895,7 @@ def test_format_defang(record_type, value, expected):
877
895
  ("x", b"", ""),
878
896
  ],
879
897
  )
880
- def test_format_hex(spec, value, expected):
898
+ def test_format_hex(spec: str, value: bytes, expected: str) -> None:
881
899
  TestRecord = RecordDescriptor(
882
900
  "test/format/hex",
883
901
  [
@@ -907,7 +925,9 @@ def test_format_hex(spec, value, expected):
907
925
  (b"hello \xa7 world", "ignore", "hello world"),
908
926
  ],
909
927
  )
910
- def test_string_serialization(tmp_path, filename, str_bytes, unicode_errors, expected_str):
928
+ def test_string_serialization(
929
+ tmp_path: pathlib.Path, filename: str, str_bytes: bytes, unicode_errors: str, expected_str: str
930
+ ) -> None:
911
931
  TestRecord = RecordDescriptor(
912
932
  "test/record",
913
933
  [
@@ -929,7 +949,7 @@ def test_string_serialization(tmp_path, filename, str_bytes, unicode_errors, exp
929
949
  assert record.str_value == expected_str
930
950
 
931
951
 
932
- def test_datetime_strip_nanoseconds():
952
+ def test_datetime_strip_nanoseconds() -> None:
933
953
  d1 = dt("1984-01-01T08:10:12.123456789Z")
934
954
  d2 = dt("1984-01-01T08:10:12.123456Z")
935
955
  assert isinstance(d1, dt)
@@ -937,7 +957,7 @@ def test_datetime_strip_nanoseconds():
937
957
  assert d1 == d2
938
958
 
939
959
 
940
- def test_datetime_handle_nanoseconds_without_timezone():
960
+ def test_datetime_handle_nanoseconds_without_timezone() -> None:
941
961
  d1 = dt("2006-11-10T14:29:55.5851926")
942
962
  d2 = dt("2006-11-10T14:29:55")
943
963
  assert isinstance(d1, dt)
@@ -957,7 +977,7 @@ def test_datetime_handle_nanoseconds_without_timezone():
957
977
  "out.jsonl",
958
978
  ],
959
979
  )
960
- def test_datetime_timezone_aware(tmp_path, record_filename):
980
+ def test_datetime_timezone_aware(tmp_path: pathlib.Path, record_filename: str) -> None:
961
981
  TestRecord = RecordDescriptor(
962
982
  "test/tz",
963
983
  [
@@ -981,7 +1001,7 @@ def test_datetime_timezone_aware(tmp_path, record_filename):
981
1001
  assert record._generated.tzinfo == UTC
982
1002
 
983
1003
 
984
- def test_datetime_comparisions():
1004
+ def test_datetime_comparisions() -> None:
985
1005
  with pytest.raises(TypeError, match=".* compare .*naive"):
986
1006
  assert dt("2023-01-01") > datetime(2022, 1, 1)
987
1007
 
@@ -1140,7 +1160,7 @@ def test_command_failed() -> None:
1140
1160
  fieldtypes.path,
1141
1161
  ],
1142
1162
  )
1143
- def test_empty_path(path_cls) -> None:
1163
+ def test_empty_path(path_cls: type[pathlib.PurePath]) -> None:
1144
1164
  # initialize with empty string
1145
1165
  p1 = path_cls("")
1146
1166
  assert p1 == ""
@@ -1181,7 +1201,7 @@ def test_record_empty_path() -> None:
1181
1201
  assert repr(r) == "<test/path value=''>"
1182
1202
 
1183
1203
 
1184
- def test_empty_path_serialization(tmp_path) -> None:
1204
+ def test_empty_path_serialization(tmp_path: pathlib.Path) -> None:
1185
1205
  TestRecord = RecordDescriptor(
1186
1206
  "test/path",
1187
1207
  [
@@ -50,7 +50,7 @@ deps =
50
50
  vermin
51
51
  commands =
52
52
  flake8 flow tests
53
- vermin -t=3.8- --no-tips --lint --exclude zoneinfo flow tests
53
+ vermin --target=3.9 --no-tips --lint flow tests
54
54
 
55
55
  [flake8]
56
56
  max-line-length = 120
File without changes