FastWARC 1.0.0__tar.gz → 1.0.1__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 (54) hide show
  1. {fastwarc-1.0.0 → fastwarc-1.0.1}/FastWARC.egg-info/PKG-INFO +3 -3
  2. {fastwarc-1.0.0 → fastwarc-1.0.1}/FastWARC.egg-info/SOURCES.txt +0 -1
  3. {fastwarc-1.0.0 → fastwarc-1.0.1}/PKG-INFO +3 -3
  4. {fastwarc-1.0.0 → fastwarc-1.0.1}/README.md +1 -1
  5. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/__init__.py +10 -13
  6. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/__init__.pyi +10 -2
  7. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/legacy/_shims.py +3 -3
  8. fastwarc-1.0.1/fastwarc/stream_io.pyi +187 -0
  9. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/warc.pyi +104 -70
  10. {fastwarc-1.0.0 → fastwarc-1.0.1}/pyproject.toml +20 -15
  11. fastwarc-1.0.0/fastwarc/_fastwarc.pyi +0 -35
  12. fastwarc-1.0.0/fastwarc/stream_io.pyi +0 -136
  13. {fastwarc-1.0.0 → fastwarc-1.0.1}/FastWARC.egg-info/dependency_links.txt +0 -0
  14. {fastwarc-1.0.0 → fastwarc-1.0.1}/FastWARC.egg-info/entry_points.txt +0 -0
  15. {fastwarc-1.0.0 → fastwarc-1.0.1}/FastWARC.egg-info/requires.txt +0 -0
  16. {fastwarc-1.0.0 → fastwarc-1.0.1}/FastWARC.egg-info/top_level.txt +0 -0
  17. {fastwarc-1.0.0 → fastwarc-1.0.1}/MANIFEST.in +0 -0
  18. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/cli.py +0 -0
  19. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/legacy/__init__.pxd +0 -0
  20. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/legacy/__init__.py +0 -0
  21. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/legacy/stream_io.pxd +0 -0
  22. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/legacy/stream_io.pyi +0 -0
  23. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/legacy/stream_io.pyx +0 -0
  24. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/legacy/tools.pyi +0 -0
  25. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/legacy/tools.pyx +0 -0
  26. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/legacy/warc.pxd +0 -0
  27. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/legacy/warc.pyi +0 -0
  28. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/legacy/warc.pyx +0 -0
  29. {fastwarc-1.0.0 → fastwarc-1.0.1}/fastwarc/py.typed +0 -0
  30. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_common/__init__.pxd +0 -0
  31. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_common/string_util.pxd +0 -0
  32. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/__init__.pxd +0 -0
  33. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/algorithm.pxd +0 -0
  34. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/atomic.pxd +0 -0
  35. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/boost_regex.pxd +0 -0
  36. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/cctype.pxd +0 -0
  37. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/cstdlib.pxd +0 -0
  38. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/cstring.pxd +0 -0
  39. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/dlfcn.pxd +0 -0
  40. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/errno.pxd +0 -0
  41. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/lexbor.pxd +0 -0
  42. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/lz4frame.pxd +0 -0
  43. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/lz4hc.pxd +0 -0
  44. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/pthread.pxd +0 -0
  45. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/re2.pxd +0 -0
  46. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/stdio.pxd +0 -0
  47. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/string_view.pxd +0 -0
  48. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/time.pxd +0 -0
  49. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/uchardet.pxd +0 -0
  50. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/unistd.pxd +0 -0
  51. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/utility.pxd +0 -0
  52. {fastwarc-1.0.0 → fastwarc-1.0.1}/resiliparse_inc/zlib.pxd +0 -0
  53. {fastwarc-1.0.0 → fastwarc-1.0.1}/setup.cfg +0 -0
  54. {fastwarc-1.0.0 → fastwarc-1.0.1}/setup.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: FastWARC
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: A high-performance WARC parsing library for Python written in C++/Cython.
5
5
  Author: Janek Bevendorff
6
- License: Apache License 2.0
6
+ License-Expression: Apache-2.0
7
7
  Project-URL: repository, https://github.com/chatnoir-eu/chatnoir-resiliparse
8
8
  Project-URL: homepage, https://resiliparse.chatnoir.eu
9
9
  Project-URL: documentation, https://resiliparse.chatnoir.eu
@@ -25,7 +25,7 @@ Requires-Dist: lz4; extra == "test"
25
25
  # FastWARC (Python)
26
26
 
27
27
  FastWARC is a high-performance WARC parsing library for Python written in Rust with Python bindings. FastWARC supports
28
- compressed and uncompressed WARC/1.0 and WARC/1.1 streams. Supported compression algorithms are GZip and LZ4.
28
+ compressed and uncompressed WARC/1.0 and WARC/1.1 streams. Supported compression algorithms are Gzip and LZ4.
29
29
 
30
30
  This crate contains the Python bindings for FastWARC.
31
31
 
@@ -10,7 +10,6 @@ FastWARC.egg-info/requires.txt
10
10
  FastWARC.egg-info/top_level.txt
11
11
  fastwarc/__init__.py
12
12
  fastwarc/__init__.pyi
13
- fastwarc/_fastwarc.pyi
14
13
  fastwarc/cli.py
15
14
  fastwarc/py.typed
16
15
  fastwarc/stream_io.pyi
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: FastWARC
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: A high-performance WARC parsing library for Python written in C++/Cython.
5
5
  Author: Janek Bevendorff
6
- License: Apache License 2.0
6
+ License-Expression: Apache-2.0
7
7
  Project-URL: repository, https://github.com/chatnoir-eu/chatnoir-resiliparse
8
8
  Project-URL: homepage, https://resiliparse.chatnoir.eu
9
9
  Project-URL: documentation, https://resiliparse.chatnoir.eu
@@ -25,7 +25,7 @@ Requires-Dist: lz4; extra == "test"
25
25
  # FastWARC (Python)
26
26
 
27
27
  FastWARC is a high-performance WARC parsing library for Python written in Rust with Python bindings. FastWARC supports
28
- compressed and uncompressed WARC/1.0 and WARC/1.1 streams. Supported compression algorithms are GZip and LZ4.
28
+ compressed and uncompressed WARC/1.0 and WARC/1.1 streams. Supported compression algorithms are Gzip and LZ4.
29
29
 
30
30
  This crate contains the Python bindings for FastWARC.
31
31
 
@@ -1,7 +1,7 @@
1
1
  # FastWARC (Python)
2
2
 
3
3
  FastWARC is a high-performance WARC parsing library for Python written in Rust with Python bindings. FastWARC supports
4
- compressed and uncompressed WARC/1.0 and WARC/1.1 streams. Supported compression algorithms are GZip and LZ4.
4
+ compressed and uncompressed WARC/1.0 and WARC/1.1 streams. Supported compression algorithms are Gzip and LZ4.
5
5
 
6
6
  This crate contains the Python bindings for FastWARC.
7
7
 
@@ -13,23 +13,20 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import importlib
16
- import sys
17
16
 
18
17
  _native = importlib.import_module("._fastwarc", __name__)
19
18
  _legacy_shims = importlib.import_module(".legacy._shims", __name__)
20
19
 
21
- from ._fastwarc import * # noqa: F401,F403
20
+ import fastwarc.stream_io as stream_io # noqa: F401
21
+ import fastwarc.warc as warc # noqa: F401
22
22
 
23
- stream_io = _native.stream_io
24
- warc = _native.warc
25
-
26
- sys.modules[__name__ + ".stream_io"] = stream_io
27
- sys.modules[__name__ + ".warc"] = warc
23
+ # Re-export module attributes
24
+ globals().update({attr: getattr(_native, attr) for attr in _native.__all__})
28
25
 
29
26
  # Patch legacy shims onto stream_io
30
27
  for name in _legacy_shims.__all__:
31
28
  setattr(stream_io, name, getattr(_legacy_shims, name))
32
- stream_io.__all__ += getattr(_legacy_shims, "__all__", ())
29
+ stream_io.__all__ += getattr(_legacy_shims, "__all__", ()) # type: ignore[attr-defined]
33
30
 
34
31
  FileStream = _legacy_shims.FileStream
35
32
  GZipStream = _legacy_shims.GZipStream
@@ -39,9 +36,9 @@ StreamError = _legacy_shims.StreamError
39
36
 
40
37
  __all__ = [
41
38
  *_native.__all__,
42
- "FileStream",
43
- "GZipStream",
44
- "LZ4Stream",
45
- "FastWARCError",
46
- "StreamError",
39
+ 'FileStream',
40
+ 'GZipStream',
41
+ 'LZ4Stream',
42
+ 'FastWARCError',
43
+ 'StreamError',
47
44
  ]
@@ -12,8 +12,16 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from ._fastwarc import *
16
- from .legacy import (
15
+ from .warc import ArchiveIterator, WarcRecord, WarcRecordType
16
+ from .stream_io import (
17
+ GzipReader,
18
+ GzipWriter,
19
+ ZstdReader,
20
+ ZstdWriter,
21
+ Lz4Reader,
22
+ Lz4Writer,
23
+
24
+ # Legacy names
17
25
  FileStream,
18
26
  GZipStream,
19
27
  LZ4Stream,
@@ -172,7 +172,7 @@ class BytesIOStream:
172
172
 
173
173
  class GZipStream:
174
174
  def __new__(cls, raw_stream, compression_level=9, zlib=False, fsspec_args=None):
175
- from fastwarc.stream_io import GzipReader, GzipWriter
175
+ from ..stream_io import GzipReader, GzipWriter
176
176
  stream = CompressingStream(
177
177
  _reader_factory=lambda: GzipReader(raw_stream, zlib=zlib, fsspec_args=fsspec_args),
178
178
  _writer_factory=lambda: GzipWriter(raw_stream, compression_level=compression_level, zlib=zlib,
@@ -184,7 +184,7 @@ class GZipStream:
184
184
  class LZ4Stream:
185
185
  def __new__(cls, raw_stream, mode='r', compression_level=12,
186
186
  favor_dec_speed=True, fsspec_args=None):
187
- from fastwarc.stream_io import Lz4Reader, Lz4Writer
187
+ from ..stream_io import Lz4Reader, Lz4Writer
188
188
  stream = CompressingStream(
189
189
  _reader_factory=lambda: Lz4Reader(raw_stream, fsspec_args=fsspec_args),
190
190
  _writer_factory=lambda: Lz4Writer(raw_stream, fsspec_args=fsspec_args))
@@ -194,7 +194,7 @@ class LZ4Stream:
194
194
 
195
195
  class BrotliStream:
196
196
  def __new__(cls, raw_stream, quality=11, lgwin=22, lgblock=0, fsspec_args=None):
197
- from fastwarc.stream_io import BrotliReader, BrotliWriter
197
+ from ..stream_io import BrotliReader, BrotliWriter
198
198
  stream = CompressingStream(
199
199
  _reader_factory=lambda: BrotliReader(raw_stream, fsspec_args=fsspec_args),
200
200
  _writer_factory=lambda: BrotliWriter(raw_stream, fsspec_args=fsspec_args))
@@ -0,0 +1,187 @@
1
+ # Copyright 2026 Janek Bevendorff
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from os import PathLike
16
+ from types import TracebackType
17
+ from typing import BinaryIO, ContextManager, Protocol, Type, Self
18
+ from typing_extensions import disjoint_base
19
+
20
+ # Legacy shims
21
+ from .legacy._shims import *
22
+
23
+ __all__ = [
24
+ 'WarcReader',
25
+ 'WarcWriter',
26
+ 'GzipReader',
27
+ 'GzipWriter',
28
+ 'ZstdReader',
29
+ 'ZstdWriter',
30
+ 'Lz4Reader',
31
+ 'Lz4Writer',
32
+ 'BrotliReader',
33
+ 'BrotliWriter',
34
+ 'ChunkedReader',
35
+ 'ChunkedWriter',
36
+ 'zstd_train_dictionary_from_continuous',
37
+ 'zstd_train_dictionary_from_files',
38
+ 'zstd_train_dictionary_from_samples',
39
+
40
+ # Legacy names
41
+ 'BrotliStream',
42
+ 'BufferedReader',
43
+ 'BytesIOStream',
44
+ 'CompressingStream',
45
+ 'FastWARCError',
46
+ 'FileStream',
47
+ 'GZipStream',
48
+ 'IOStream',
49
+ 'LZ4Stream',
50
+ 'PythonIOStreamAdapter',
51
+ 'ReaderStaleError',
52
+ 'StreamError',
53
+ 'wrap_stream'
54
+ ]
55
+
56
+
57
+ class _GenericReader(Protocol):
58
+ def read(self, size: int = ...) -> bytes: ...
59
+
60
+ def seek(self, offset: int, whence: int = ...) -> int: ...
61
+
62
+ def tell(self) -> int: ...
63
+
64
+ def close(self) -> None: ...
65
+
66
+
67
+ class _GenericWriter(Protocol):
68
+ def write(self, data: bytes) -> int: ...
69
+
70
+ def flush(self) -> None: ...
71
+
72
+ def close(self) -> None: ...
73
+
74
+
75
+ @disjoint_base
76
+ class WarcReader(ContextManager["WarcReader"]):
77
+ def __new__(cls) -> Self: ...
78
+
79
+ def read(self, size: int = ...) -> bytes: ...
80
+
81
+ def seek(self, offset: int, whence: int = 0) -> int: ...
82
+
83
+ def tell(self) -> int: ...
84
+
85
+ def close(self) -> None: ...
86
+
87
+ def __enter__(self) -> Self: ...
88
+
89
+ def __exit__(
90
+ self,
91
+ exc_type: Type[BaseException] | None,
92
+ exc: BaseException | None,
93
+ traceback: TracebackType | None
94
+ ) -> None: ...
95
+
96
+ def inner_seek(self, offset: int, whence: int = 0) -> int: ...
97
+
98
+ def inner_tell(self) -> int: ...
99
+
100
+ def frame_start_position(self) -> int | None: ...
101
+
102
+
103
+ @disjoint_base
104
+ class WarcWriter(ContextManager["WarcWriter"]):
105
+ def __new__(cls) -> Self: ...
106
+
107
+ def write(self, data: bytes) -> int: ...
108
+
109
+ def flush(self) -> None: ...
110
+
111
+ def close(self) -> None: ...
112
+
113
+ def __enter__(self) -> Self: ...
114
+
115
+ def __exit__(
116
+ self,
117
+ exc_type: Type[BaseException] | None,
118
+ exc: BaseException | None,
119
+ traceback: TracebackType | None
120
+ ) -> None: ...
121
+
122
+ def finish(self) -> None: ...
123
+
124
+
125
+ _ReaderInput = WarcReader | BinaryIO | _GenericReader | PathLike[str] | str
126
+ _WriterInput = WarcWriter | BinaryIO | _GenericWriter | PathLike[str] | str
127
+
128
+
129
+ @disjoint_base
130
+ class GzipReader(WarcReader):
131
+ def __new__(cls, inner: _ReaderInput, buffer_size=4096, zlib=False, fsspec_args=None) -> Self: ...
132
+
133
+
134
+ @disjoint_base
135
+ class GzipWriter(WarcWriter):
136
+ def __new__(cls, inner: _WriterInput, compression_level=9, buffer_size=8192, zlib=False,
137
+ fsspec_args=None) -> Self: ...
138
+
139
+
140
+ @disjoint_base
141
+ class ZstdReader(WarcReader):
142
+ def __new__(cls, inner: _ReaderInput, buffer_size=4096, fsspec_args=None, dictionary=None) -> Self: ...
143
+
144
+
145
+ @disjoint_base
146
+ class ZstdWriter(WarcWriter):
147
+ def __new__(cls, inner: _WriterInput, buffer_size=8192, fsspec_args=None, dictionary=None,
148
+ compress_dictionary_frame=False) -> Self: ...
149
+
150
+
151
+ @disjoint_base
152
+ class Lz4Reader(WarcReader):
153
+ def __new__(cls, inner: _ReaderInput, buffer_size=4096, fsspec_args=None) -> Self: ...
154
+
155
+
156
+ @disjoint_base
157
+ class Lz4Writer(WarcWriter):
158
+ def __new__(cls, inner: _WriterInput, buffer_size=8192, fsspec_args=None) -> Self: ...
159
+
160
+
161
+ @disjoint_base
162
+ class BrotliReader(WarcReader):
163
+ def __new__(cls, inner: _ReaderInput, buffer_size=4096, fsspec_args=None) -> Self: ...
164
+
165
+
166
+ @disjoint_base
167
+ class BrotliWriter(WarcWriter):
168
+ def __new__(cls, inner: _WriterInput, buffer_size=8192, fsspec_args=None) -> Self: ...
169
+
170
+
171
+ @disjoint_base
172
+ class ChunkedReader(WarcReader):
173
+ def __new__(cls, inner: _ReaderInput, buffer_size=1024, fsspec_args=None) -> Self: ...
174
+
175
+
176
+ @disjoint_base
177
+ class ChunkedWriter(WarcWriter):
178
+ def __new__(cls, inner: _WriterInput, min_chunk_size=512, fsspec_args=None) -> Self: ...
179
+
180
+
181
+ def zstd_train_dictionary_from_continuous(sample_data: bytes, sample_sizes: list[int], max_size: int) -> bytes: ...
182
+
183
+
184
+ def zstd_train_dictionary_from_samples(samples: list[bytes], max_size: int) -> bytes: ...
185
+
186
+
187
+ def zstd_train_dictionary_from_files(filenames: list[str], max_size: int) -> bytes: ...
@@ -13,13 +13,45 @@
13
13
  # limitations under the License.
14
14
 
15
15
  from datetime import datetime
16
+ from collections.abc import Callable, Iterable, Iterator
16
17
  from enum import IntFlag
17
- from os import PathLike
18
- from typing import BinaryIO, Callable, Dict, Iterable, Iterator, Literal, Optional, Self, Tuple, Union
19
-
20
- from .stream_io import _GenericReader, _GenericWriter, WarcReader, WarcWriter
21
-
22
-
18
+ from typing import BinaryIO, final, Literal, Self
19
+ from typing_extensions import disjoint_base
20
+
21
+ from .stream_io import _GenericReader, _GenericWriter, _ReaderInput, WarcReader, WarcWriter
22
+
23
+ __all__ = [
24
+ 'WarcRecordType',
25
+ 'WarcRecord',
26
+ 'ArchiveIterator',
27
+ 'HeaderMap',
28
+ 'WarcHeaderMap',
29
+ 'WarcRecordPayloadReader',
30
+
31
+ 'warcinfo',
32
+ 'response',
33
+ 'resource',
34
+ 'request',
35
+ 'metadata',
36
+ 'revisit',
37
+ 'conversion',
38
+ 'continuation',
39
+ 'unknown',
40
+ 'any_type',
41
+ 'no_type',
42
+
43
+ 'is_warc_10',
44
+ 'is_warc_11',
45
+ 'has_block_digest',
46
+ 'has_valid_block_digest',
47
+ 'has_payload_digest',
48
+ 'has_valid_payload_digest',
49
+ 'is_http',
50
+ 'is_concurrent',
51
+ ]
52
+
53
+
54
+ @final
23
55
  class WarcRecordType(IntFlag):
24
56
  warcinfo = 2
25
57
  response = 4
@@ -37,21 +69,17 @@ class WarcRecordType(IntFlag):
37
69
 
38
70
  def __index__(self) -> int: ...
39
71
 
40
- def __and__(self, other: int) -> int: ...
41
-
42
- def __rand__(self, other: int) -> int: ...
72
+ def __and__(self, other: int, /) -> Self: ...
43
73
 
44
- def __or__(self, other: int) -> int: ...
74
+ def __or__(self, other: int, /) -> Self: ...
45
75
 
46
- def __ror__(self, other: int) -> int: ...
76
+ def __xor__(self, other: int, /) -> Self: ...
47
77
 
48
- def __xor__(self, other: int) -> int: ...
78
+ def __str__(self) -> str:
79
+ return self.name or str(self.value)
49
80
 
50
- def __rxor__(self, other: int) -> int: ...
51
-
52
- def __str__(self) -> str: ...
53
-
54
- def __repr__(self) -> str: ...
81
+ def __repr__(self) -> str:
82
+ return self.name or str(self.value)
55
83
 
56
84
 
57
85
  warcinfo = WarcRecordType.warcinfo
@@ -67,56 +95,57 @@ no_type = WarcRecordType.no_type
67
95
  any_type = WarcRecordType.any_type
68
96
 
69
97
 
98
+ @final
70
99
  class HeaderMap:
71
100
  def __new__(cls, encoding: str = "utf-8") -> Self: ...
72
101
 
73
102
  @property
74
- def reason_phrase(self) -> Optional[str]: ...
103
+ def reason_phrase(self) -> str | None: ...
75
104
 
76
105
  @property
77
- def status_code(self) -> Optional[int]: ...
106
+ def status_code(self) -> int | None: ...
78
107
 
79
108
  @property
80
- def status_line(self) -> Optional[str]: ...
109
+ def status_line(self) -> str | None: ...
81
110
 
82
111
  @status_line.setter
83
112
  def status_line(self, status_line: str): ...
84
113
 
85
114
  @property
86
- def status_line_bytes(self) -> Optional[bytes]: ...
115
+ def status_line_bytes(self) -> bytes | None: ...
87
116
 
88
117
  @status_line_bytes.setter
89
118
  def status_line_bytes(self, status_line: bytes): ...
90
119
 
91
120
  def encoding(self) -> str: ...
92
121
 
93
- def parse(self, reader: Union[WarcReader, BinaryIO, _GenericReader], has_status_line: bool = True) -> int: ...
122
+ def parse(self, reader: WarcReader | BinaryIO | _GenericReader, has_status_line: bool = True) -> int: ...
94
123
 
95
- def write(self, writer: Union[WarcWriter, BinaryIO, _GenericWriter]) -> int: ...
124
+ def write(self, writer: WarcWriter | BinaryIO | _GenericWriter) -> int: ...
96
125
 
97
126
  def append(self, key: str, value: str): ...
98
127
 
99
- def to_dict(self) -> Dict[str, str]: ...
128
+ def to_dict(self) -> dict[str, str]: ...
100
129
 
101
130
  # deprecated
102
- def asdict(self) -> Dict[str, str]: ...
131
+ def asdict(self) -> dict[str, str]: ...
103
132
 
104
- def to_tuples(self) -> Tuple[Tuple[str, str], ...]: ...
133
+ def to_tuples(self) -> tuple[tuple[str, str], ...]: ...
105
134
 
106
135
  # deprecated
107
- def astuples(self) -> Tuple[Tuple[str, str], ...]: ...
136
+ def astuples(self) -> tuple[tuple[str, str], ...]: ...
108
137
 
109
138
  def is_empty(self) -> bool: ...
110
139
 
111
140
  def clear(self): ...
112
141
 
113
- def get(self, key: str, default: Optional[str] = None) -> Optional[str]: ...
142
+ def get(self, key: str, default: str | None = None) -> str | None: ...
114
143
 
115
- def get_multiple(self, key: str) -> Tuple[str, ...]: ...
144
+ def get_multiple(self, key: str) -> tuple[str, ...]: ...
116
145
 
117
- def get_bytes(self, key: bytes, default: Optional[bytes] = None) -> Optional[bytes]: ...
146
+ def get_bytes(self, key: bytes, default: bytes | None = None) -> bytes | None: ...
118
147
 
119
- def get_bytes_multiple(self, key: bytes) -> Tuple[bytes, ...]: ...
148
+ def get_bytes_multiple(self, key: bytes) -> tuple[bytes, ...]: ...
120
149
 
121
150
  def contains_key(self, key: str) -> bool: ...
122
151
 
@@ -132,58 +161,60 @@ class HeaderMap:
132
161
 
133
162
  def remove_bytes(self, key: bytes): ...
134
163
 
135
- def items(self) -> Tuple[Tuple[str, str], ...]: ...
164
+ def items(self) -> tuple[tuple[str, str], ...]: ...
136
165
 
137
- def items_bytes(self) -> Tuple[Tuple[bytes, bytes], ...]: ...
166
+ def items_bytes(self) -> tuple[tuple[bytes, bytes], ...]: ...
138
167
 
139
- def keys(self) -> Tuple[str, ...]: ...
168
+ def keys(self) -> tuple[str, ...]: ...
140
169
 
141
- def keys_bytes(self) -> Tuple[bytes, ...]: ...
170
+ def keys_bytes(self) -> tuple[bytes, ...]: ...
142
171
 
143
- def values(self) -> Tuple[str, ...]: ...
172
+ def values(self) -> tuple[str, ...]: ...
144
173
 
145
- def values_bytes(self) -> Tuple[bytes, ...]: ...
174
+ def values_bytes(self) -> tuple[bytes, ...]: ...
146
175
 
147
- def __getitem__(self, item: str) -> str: ...
176
+ def __getitem__(self, item: str, /) -> str: ...
148
177
 
149
- def __iter__(self) -> Iterator[Tuple[str, str]]: ...
178
+ def __iter__(self) -> Iterator[tuple[str, str]]: ...
150
179
 
151
180
  def __len__(self) -> int: ...
152
181
 
153
- def __setitem__(self, key: str, value: str): ...
182
+ def __setitem__(self, key: str, value: str, /): ...
154
183
 
155
- def __contains__(self, item: str) -> bool: ...
184
+ def __contains__(self, item: str, /) -> bool: ...
156
185
 
157
- def __eq__(self, other: HeaderMap) -> bool: ...
186
+ def __eq__(self, other, /) -> bool: ...
158
187
 
159
- def __ne__(self, other: HeaderMap) -> bool: ...
188
+ def __ne__(self, other, /) -> bool: ...
160
189
 
161
190
  def __str__(self) -> str: ...
162
191
 
163
192
  def __repr__(self) -> str: ...
164
193
 
165
- def __getnewargs__(self) -> Tuple[str]: ...
194
+ def __getnewargs__(self) -> tuple[str]: ...
166
195
 
167
- def __getstate__(self) -> Tuple[bytes, bool]: ...
196
+ def __getstate__(self) -> tuple[bytes, bool]: ...
168
197
 
169
- def __setstate__(self, state: Tuple[bytes, bool]): ...
198
+ def __setstate__(self, state: tuple[bytes, bool]): ...
170
199
 
171
200
 
172
201
  # Legacy name
173
202
  WarcHeaderMap = HeaderMap
174
203
 
175
204
 
205
+ @final
176
206
  class WarcRecordPayloadReader(WarcReader):
177
207
  def readline(self, max_line_len: int = 8192) -> bytes: ...
178
208
 
179
- def consume(self, size: int = -1) -> int: ...
209
+ def consume(self, size: int = ...) -> int: ...
180
210
 
181
211
 
212
+ @disjoint_base
182
213
  class WarcRecord:
183
214
  def __new__(cls) -> Self: ...
184
215
 
185
216
  @property
186
- def record_id(self) -> Optional[str]: ...
217
+ def record_id(self) -> str | None: ...
187
218
 
188
219
  @record_id.setter
189
220
  def record_id(self, record_id: str): ...
@@ -192,13 +223,13 @@ class WarcRecord:
192
223
  def record_type(self) -> WarcRecordType: ...
193
224
 
194
225
  @record_type.setter
195
- def record_type(self, record_type: Union[WarcRecordType, int]): ...
226
+ def record_type(self, record_type: WarcRecordType | int): ...
196
227
 
197
228
  @property
198
229
  def content_length(self) -> int: ...
199
230
 
200
231
  @property
201
- def record_date(self) -> Optional[datetime]: ...
232
+ def record_date(self) -> datetime: ...
202
233
 
203
234
  @record_date.setter
204
235
  def record_date(self, record_date: datetime): ...
@@ -216,22 +247,22 @@ class WarcRecord:
216
247
  def is_http_parsed(self) -> bool: ...
217
248
 
218
249
  @property
219
- def http_headers(self) -> Optional[HeaderMap]: ...
250
+ def http_headers(self) -> HeaderMap: ...
220
251
 
221
252
  @property
222
- def http_content_type(self) -> Optional[str]: ...
253
+ def http_content_type(self) -> str | None: ...
223
254
 
224
255
  @property
225
- def http_charset(self) -> Optional[str]: ...
256
+ def http_charset(self) -> str | None: ...
226
257
 
227
258
  @property
228
- def http_date(self) -> Optional[datetime]: ...
259
+ def http_date(self) -> datetime: ...
229
260
 
230
261
  @property
231
- def http_last_modified(self) -> Optional[datetime]: ...
262
+ def http_last_modified(self) -> datetime: ...
232
263
 
233
264
  @property
234
- def reader(self) -> Optional[WarcRecordPayloadReader]: ...
265
+ def reader(self) -> WarcRecordPayloadReader: ...
235
266
 
236
267
  @property
237
268
  def stream_pos(self) -> int: ...
@@ -239,9 +270,8 @@ class WarcRecord:
239
270
  @property
240
271
  def is_frozen(self) -> bool: ...
241
272
 
242
- def init_headers(
243
- self, content_length: int = 0, record_type: WarcRecordType = no_type, record_urn: Optional[bytes] = None
244
- ): ...
273
+ def init_headers(self, record_type: WarcRecordType = ..., record_urn: bytes | None = None, *,
274
+ content_length: int | None = None): ...
245
275
 
246
276
  def freeze(self) -> bool: ...
247
277
 
@@ -249,11 +279,12 @@ class WarcRecord:
249
279
 
250
280
  def set_bytes_payload(self, content: bytes): ...
251
281
 
252
- def consume(self, n: Optional[int] = None) -> int: ...
282
+ def consume(self, n: int | None = None) -> int: ...
253
283
 
254
284
  def parse_warc_headers(self, quirks_mode: bool = False) -> int: ...
255
285
 
256
- def parse_http(self, auto_decode: Literal['none', 'content', 'transfer', 'all'] = 'none'): ...
286
+ def parse_http(self, auto_decode: Literal['none', 'content', 'transfer', 'all'] = 'none', *,
287
+ strict_mode: bool = True): ...
257
288
 
258
289
  def verify_block_digest(self, consume: bool = False) -> bool: ...
259
290
 
@@ -261,9 +292,9 @@ class WarcRecord:
261
292
 
262
293
  def write(
263
294
  self,
264
- stream: Union[WarcWriter, BinaryIO, _GenericWriter],
295
+ stream: WarcWriter | BinaryIO | _GenericWriter,
265
296
  checksum_data: bool = False,
266
- payload_digest: Optional[bytes] = None,
297
+ payload_digest: bytes | None = None,
267
298
  chunk_size: int = 16384
268
299
  ) -> int: ...
269
300
 
@@ -271,27 +302,30 @@ class WarcRecord:
271
302
 
272
303
  def __repr__(self) -> str: ...
273
304
 
274
- def __getnewargs__(self) -> Tuple[()]: ...
305
+ def __getnewargs__(self) -> tuple[()]: ...
275
306
 
276
- def __getstate__(self) -> Tuple[bytes, bool]: ...
307
+ def __getstate__(self) -> tuple[bytes, bool]: ...
277
308
 
278
- def __setstate__(self, state: Tuple[bytes, bool]): ...
309
+ def __setstate__(self, state: tuple[bytes, bool]): ...
279
310
 
280
311
 
312
+ @final
281
313
  class ArchiveIterator(Iterable[WarcRecord]):
282
314
  def __new__(
283
315
  cls,
284
- stream: Union[WarcReader, BinaryIO, _GenericReader, PathLike, str],
316
+ stream: _ReaderInput,
285
317
  record_types: WarcRecordType = any_type,
286
318
  parse_http: bool = True,
287
- min_content_length: int = -1,
288
- max_content_length: int = -1,
289
- func_filter: Optional[Callable[[WarcRecord], bool]] = None,
319
+ min_content_length: int | None = None,
320
+ max_content_length: int | None = None,
321
+ func_filter: Callable[[WarcRecord], bool] | None = None,
290
322
  verify_digests: bool = False,
291
323
  quirks_mode: bool = False,
292
324
  auto_decode: Literal['none', 'content', 'transfer', 'all'] = 'none',
293
325
  stream_detect: bool = True,
294
326
  fsspec_args=None,
327
+ *,
328
+ strict_mode: bool = True
295
329
  ) -> Self: ...
296
330
 
297
331
  def __iter__(self) -> Iterator[WarcRecord]: ...
@@ -1,23 +1,21 @@
1
1
  [build-system]
2
- requires = ["setuptools>=75.0.0", "setuptools-rust>=1.10", "Cython>=0.29.33"]
2
+ requires = ["setuptools>=77.0", "setuptools-rust>=1.10", "Cython>=0.29.33"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "FastWARC"
7
- version = "1.0.0"
7
+ version = "1.0.1"
8
8
  description = "A high-performance WARC parsing library for Python written in C++/Cython."
9
9
  authors = [
10
- { name = "Janek Bevendorff" }
10
+ { name = "Janek Bevendorff" }
11
11
  ]
12
- license = { text = "Apache License 2.0" }
13
- # TODO: Replace with this once we deprecate Python 3.8 and upgrade to setuptools 77:
14
- # license = "Apache-2.0"
12
+ license = "Apache-2.0"
15
13
  readme = "README.md"
16
14
  requires-python = ">=3.8"
17
15
  dependencies = [
18
- "brotli",
19
- "click",
20
- "tqdm"
16
+ "brotli",
17
+ "click",
18
+ "tqdm"
21
19
  ]
22
20
 
23
21
  [project.urls]
@@ -27,16 +25,16 @@ documentation = "https://resiliparse.chatnoir.eu"
27
25
 
28
26
  [project.optional-dependencies]
29
27
  all = [
30
- "fastwarc[fsspec]"
28
+ "fastwarc[fsspec]"
31
29
  ]
32
30
  fsspec = [
33
- "fsspec"
31
+ "fsspec"
34
32
  ]
35
33
  test = [
36
- "fastwarc[all]",
37
- "pytest>=7.2.2",
38
- "pytest-cov>=4.0.0",
39
- "lz4",
34
+ "fastwarc[all]",
35
+ "pytest>=7.2.2",
36
+ "pytest-cov>=4.0.0",
37
+ "lz4",
40
38
  ]
41
39
 
42
40
  [project.scripts]
@@ -53,3 +51,10 @@ archs = "native"
53
51
  build = "cp3*"
54
52
  build-frontend = "build"
55
53
  test-extras = ["all", "test"]
54
+
55
+ [tool.mypy]
56
+ exclude = ["fastwarc/cli\\.py", "fastwarc/legacy/.*"]
57
+
58
+ [[tool.mypy.overrides]]
59
+ module = ["fsspec.*"]
60
+ ignore_missing_imports = true
@@ -1,35 +0,0 @@
1
- # Copyright 2026 Janek Bevendorff
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from .warc import ArchiveIterator, WarcRecord, WarcRecordType
16
- from .stream_io import (
17
- GzipReader,
18
- GzipWriter,
19
- ZstdReader,
20
- ZstdWriter,
21
- Lz4Reader,
22
- Lz4Writer
23
- )
24
-
25
- __all__ = [
26
- 'ArchiveIterator',
27
- 'WarcRecord',
28
- 'WarcRecordType',
29
- 'GzipReader',
30
- 'GzipWriter',
31
- 'ZstdReader',
32
- 'ZstdWriter',
33
- 'Lz4Reader',
34
- 'Lz4Writer',
35
- ]
@@ -1,136 +0,0 @@
1
- # Copyright 2026 Janek Bevendorff
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from os import PathLike
16
- from types import TracebackType
17
- from typing import BinaryIO, ContextManager, Optional, Protocol, Type, Self, Union
18
-
19
- # Legacy shims
20
- from fastwarc.legacy.stream_io import *
21
-
22
-
23
- class _GenericReader(Protocol):
24
- def read(self, size: int = -1) -> bytes: ...
25
-
26
- def seek(self, offset: int, whence: int = 0) -> int: ...
27
-
28
- def tell(self) -> int: ...
29
-
30
- def close(self) -> None: ...
31
-
32
-
33
- class _GenericWriter(Protocol):
34
- def write(self, data: bytes) -> int: ...
35
-
36
- def flush(self) -> None: ...
37
-
38
- def close(self) -> None: ...
39
-
40
-
41
- class WarcReader(ContextManager[WarcReader]):
42
- def __new__(cls) -> Self: ...
43
-
44
- def read(self, size: int = -1) -> bytes: ...
45
-
46
- def seek(self, offset: int, whence: int = 0) -> int: ...
47
-
48
- def tell(self) -> int: ...
49
-
50
- def close(self) -> None: ...
51
-
52
- def __enter__(self) -> Self: ...
53
-
54
- def __exit__(
55
- self,
56
- exc_type: Optional[Type[BaseException]],
57
- exc: Optional[BaseException],
58
- traceback: Optional[TracebackType]
59
- ) -> None: ...
60
-
61
- def inner_seek(self, offset: int, whence: int = 0) -> int: ...
62
-
63
- def inner_tell(self) -> int: ...
64
-
65
- def frame_start_position(self) -> Optional[int]: ...
66
-
67
-
68
- class WarcWriter(ContextManager[WarcWriter]):
69
- def __new__(cls) -> Self: ...
70
-
71
- def write(self, data: bytes) -> int: ...
72
-
73
- def flush(self) -> None: ...
74
-
75
- def close(self) -> None: ...
76
-
77
- def __enter__(self) -> Self: ...
78
-
79
- def __exit__(
80
- self,
81
- exc_type: Optional[Type[BaseException]],
82
- exc: Optional[BaseException],
83
- traceback: Optional[TracebackType]
84
- ) -> None: ...
85
-
86
- def finish(self) -> None: ...
87
-
88
-
89
- class GzipReader(WarcReader):
90
- def __new__(cls, inner: Union[WarcReader, BinaryIO, _GenericReader, PathLike, str],
91
- buffer_size=4096, zlib=False, fsspec_args=None) -> Self: ...
92
-
93
-
94
- class GzipWriter(WarcWriter):
95
- def __new__(cls, inner: Union[WarcWriter, BinaryIO, _GenericWriter, PathLike, str],
96
- compression_level=9, buffer_size=8192, zlib=False, fsspec_args=None) -> Self: ...
97
-
98
-
99
- class ZstdReader(WarcReader):
100
- def __new__(cls, inner: Union[WarcReader, BinaryIO, _GenericReader, PathLike, str],
101
- buffer_size=4096, fsspec_args=None, dictionary=None) -> Self: ...
102
-
103
-
104
- class ZstdWriter(WarcWriter):
105
- def __new__(cls, inner: Union[WarcWriter, BinaryIO, _GenericWriter, PathLike, str],
106
- buffer_size=8192, fsspec_args=None, dictionary=None, compress_dictionary_frame=False) -> Self: ...
107
-
108
-
109
- class Lz4Reader(WarcReader):
110
- def __new__(cls, inner: Union[WarcReader, BinaryIO, _GenericReader, PathLike, str],
111
- buffer_size=4096, fsspec_args=None) -> Self: ...
112
-
113
-
114
- class Lz4Writer(WarcWriter):
115
- def __new__(cls, inner: Union[WarcWriter, BinaryIO, _GenericWriter, PathLike, str],
116
- buffer_size=8192, fsspec_args=None) -> Self: ...
117
-
118
-
119
- class BrotliReader(WarcReader):
120
- def __new__(cls, inner: Union[WarcReader, BinaryIO, _GenericReader, PathLike, str],
121
- buffer_size=4096, fsspec_args=None) -> Self: ...
122
-
123
-
124
- class BrotliWriter(WarcWriter):
125
- def __new__(cls, inner: Union[WarcWriter, BinaryIO, _GenericWriter, PathLike, str],
126
- buffer_size=8192, fsspec_args=None) -> Self: ...
127
-
128
-
129
- class ChunkedReader(WarcReader):
130
- def __new__(cls, inner: Union[WarcReader, BinaryIO, _GenericReader, PathLike, str],
131
- buffer_size=1024, fsspec_args=None) -> Self: ...
132
-
133
-
134
- class ChunkedWriter(WarcWriter):
135
- def __new__(cls, inner: Union[WarcWriter, BinaryIO, _GenericWriter, PathLike, str],
136
- min_chunk_size=512, fsspec_args=None) -> Self: ...
File without changes
File without changes
File without changes
File without changes
File without changes