Skip to content

Commit 8367952

Browse files
committed
chore: drop support for Python 3.9
1 parent 72c6afc commit 8367952

File tree

16 files changed

+64
-73
lines changed

16 files changed

+64
-73
lines changed

.github/workflows/build.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ jobs:
1818
strategy:
1919
matrix:
2020
python:
21-
- "3.9"
2221
- "3.10"
2322
- "3.11"
2423
- "3.12"

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ adheres to [Semantic Versioning](https://semver.org/).
1111

1212
### :boom: Breaking changes
1313

14-
- End of Python 3.7 and 3.8 support
14+
- End of Python 3.7, 3.8, and 3.9 support
1515

1616
### :house: Internal
1717

pyproject.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ classifiers = [
1313
"Programming Language :: Python",
1414
"Programming Language :: Python :: 3",
1515
"Programming Language :: Python :: 3 :: Only",
16-
"Programming Language :: Python :: 3.9",
1716
"Programming Language :: Python :: 3.10",
1817
"Programming Language :: Python :: 3.11",
1918
"Programming Language :: Python :: 3.12",
@@ -23,7 +22,7 @@ classifiers = [
2322
"Topic :: System :: Archiving",
2423
"Topic :: System :: Archiving :: Compression",
2524
]
26-
requires-python = ">=3.9"
25+
requires-python = ">=3.10"
2726

2827
[project.urls]
2928
Homepage = "https://github.com/rogdham/python-xz"
@@ -139,7 +138,7 @@ testpaths = ["tests"]
139138

140139
[tool.ruff]
141140
src = ["src"]
142-
target-version = "py39"
141+
target-version = "py310"
143142

144143
[tool.ruff.lint]
145144
select = ["ALL"]

src/xz/block.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from io import DEFAULT_BUFFER_SIZE, SEEK_SET
22
from lzma import FORMAT_XZ, LZMACompressor, LZMADecompressor, LZMAError
3-
from typing import Optional, Union
43

54
from xz.common import (
65
XZError,
@@ -122,7 +121,7 @@ def __init__(
122121
uncompressed_size: int,
123122
preset: _LZMAPresetType = None,
124123
filters: _LZMAFiltersType = None,
125-
block_read_strategy: Optional[_BlockReadStrategyType] = None,
124+
block_read_strategy: _BlockReadStrategyType | None = None,
126125
) -> None:
127126
super().__init__(uncompressed_size)
128127
self.fileobj = fileobj
@@ -131,7 +130,7 @@ def __init__(
131130
self.filters = filters
132131
self.block_read_strategy = block_read_strategy or KeepBlockReadStrategy()
133132
self.unpadded_size = unpadded_size
134-
self.operation: Union[BlockRead, BlockWrite, None] = None
133+
self.operation: BlockRead | BlockWrite | None = None
135134

136135
@property
137136
def uncompressed_size(self) -> int:

src/xz/file.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from io import SEEK_CUR, SEEK_END
22
import os
3-
import sys
4-
from typing import BinaryIO, Optional, cast
3+
from typing import BinaryIO, cast
54
import warnings
65

76
from xz.common import DEFAULT_CHECK, XZError
@@ -36,7 +35,7 @@ def __init__(
3635
check: int = -1,
3736
preset: _LZMAPresetType = None,
3837
filters: _LZMAFiltersType = None,
39-
block_read_strategy: Optional[_BlockReadStrategyType] = None,
38+
block_read_strategy: _BlockReadStrategyType | None = None,
4039
) -> None:
4140
"""Open an XZ file in binary mode.
4241
@@ -113,7 +112,7 @@ def __init__(
113112
self._close_check_empty = self._mode[0] != "r"
114113

115114
@property
116-
def _last_stream(self) -> Optional[XZStream]:
115+
def _last_stream(self) -> XZStream | None:
117116
try:
118117
return self._fileobjs.last_item
119118
except KeyError:
@@ -145,10 +144,9 @@ def close(self) -> None:
145144
finally:
146145
if self._close_fileobj:
147146
self.fileobj.close() # self.fileobj exists at this point
148-
if sys.version_info < (3, 10): # pragma: no cover
149-
# fix coverage issue on some Python versions
150-
# see https://github.com/nedbat/coveragepy/issues/1480
151-
pass
147+
148+
# fix coverage issue on some Python versions
149+
pass # noqa: PIE790
152150

153151
@property
154152
def stream_boundaries(self) -> list[int]:

src/xz/io.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
IOBase,
77
UnsupportedOperation,
88
)
9-
from typing import BinaryIO, Generic, Optional, TypeVar, Union, cast
9+
from typing import BinaryIO, Generic, TypeVar, cast
1010

1111
from xz.utils import FloorDict
1212

@@ -150,7 +150,7 @@ def write(self, data: bytes) -> int:
150150
self._length = max(self._length, self._pos)
151151
return written_bytes
152152

153-
def truncate(self, size: Optional[int] = None) -> int:
153+
def truncate(self, size: int | None = None) -> int:
154154
"""Truncate file to size bytes.
155155
Size defaults to the current IO position as reported by tell().
156156
@@ -242,7 +242,7 @@ def _read(self, size: int) -> bytes:
242242
class IOProxy(IOAbstract):
243243
def __init__(
244244
self,
245-
fileobj: Union[BinaryIO, IOBase], # see typing note on top of this file
245+
fileobj: BinaryIO | IOBase, # see typing note on top of this file
246246
start: int,
247247
end: int,
248248
) -> None:
@@ -290,7 +290,7 @@ def _write_after(self) -> None:
290290

291291
def _write(self, data: bytes) -> int:
292292
if self._fileobjs:
293-
fileobj: Optional[T] = self._get_fileobj()
293+
fileobj: T | None = self._get_fileobj()
294294
else:
295295
fileobj = None
296296

src/xz/open.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from io import TextIOWrapper
2-
from typing import BinaryIO, Optional, Union, cast, overload
2+
from typing import BinaryIO, cast, overload
33

44
from xz.file import XZFile
55
from xz.typing import (
@@ -22,10 +22,10 @@ def __init__(
2222
check: int = -1,
2323
preset: _LZMAPresetType = None,
2424
filters: _LZMAFiltersType = None,
25-
block_read_strategy: Optional[_BlockReadStrategyType] = None,
26-
encoding: Optional[str] = None,
27-
errors: Optional[str] = None,
28-
newline: Optional[str] = None,
25+
block_read_strategy: _BlockReadStrategyType | None = None,
26+
encoding: str | None = None,
27+
errors: str | None = None,
28+
newline: str | None = None,
2929
) -> None:
3030
self.xz_file = XZFile(
3131
filename,
@@ -75,11 +75,11 @@ def xz_open(
7575
check: int = -1,
7676
preset: _LZMAPresetType = None,
7777
filters: _LZMAFiltersType = None,
78-
block_read_strategy: Optional[_BlockReadStrategyType] = None,
78+
block_read_strategy: _BlockReadStrategyType | None = None,
7979
# text-mode kwargs
80-
encoding: Optional[str] = None,
81-
errors: Optional[str] = None,
82-
newline: Optional[str] = None,
80+
encoding: str | None = None,
81+
errors: str | None = None,
82+
newline: str | None = None,
8383
) -> XZFile: ...
8484

8585

@@ -92,11 +92,11 @@ def xz_open(
9292
check: int = -1,
9393
preset: _LZMAPresetType = None,
9494
filters: _LZMAFiltersType = None,
95-
block_read_strategy: Optional[_BlockReadStrategyType] = None,
95+
block_read_strategy: _BlockReadStrategyType | None = None,
9696
# text-mode kwargs
97-
encoding: Optional[str] = None,
98-
errors: Optional[str] = None,
99-
newline: Optional[str] = None,
97+
encoding: str | None = None,
98+
errors: str | None = None,
99+
newline: str | None = None,
100100
) -> _XZFileText: ...
101101

102102

@@ -109,12 +109,12 @@ def xz_open(
109109
check: int = -1,
110110
preset: _LZMAPresetType = None,
111111
filters: _LZMAFiltersType = None,
112-
block_read_strategy: Optional[_BlockReadStrategyType] = None,
112+
block_read_strategy: _BlockReadStrategyType | None = None,
113113
# text-mode kwargs
114-
encoding: Optional[str] = None,
115-
errors: Optional[str] = None,
116-
newline: Optional[str] = None,
117-
) -> Union[XZFile, _XZFileText]: ...
114+
encoding: str | None = None,
115+
errors: str | None = None,
116+
newline: str | None = None,
117+
) -> XZFile | _XZFileText: ...
118118

119119

120120
def xz_open(
@@ -125,12 +125,12 @@ def xz_open(
125125
check: int = -1,
126126
preset: _LZMAPresetType = None,
127127
filters: _LZMAFiltersType = None,
128-
block_read_strategy: Optional[_BlockReadStrategyType] = None,
128+
block_read_strategy: _BlockReadStrategyType | None = None,
129129
# text-mode kwargs
130-
encoding: Optional[str] = None,
131-
errors: Optional[str] = None,
132-
newline: Optional[str] = None,
133-
) -> Union[XZFile, _XZFileText]:
130+
encoding: str | None = None,
131+
errors: str | None = None,
132+
newline: str | None = None,
133+
) -> XZFile | _XZFileText:
134134
"""Open an XZ file in binary or text mode.
135135
136136
filename can be either an actual file name (given as a str, bytes,

src/xz/stream.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from io import SEEK_CUR
2-
from typing import BinaryIO, Optional
2+
from typing import BinaryIO
33

44
from xz.block import XZBlock
55
from xz.common import (
@@ -22,7 +22,7 @@ def __init__(
2222
check: int,
2323
preset: _LZMAPresetType = None,
2424
filters: _LZMAFiltersType = None,
25-
block_read_strategy: Optional[_BlockReadStrategyType] = None,
25+
block_read_strategy: _BlockReadStrategyType | None = None,
2626
) -> None:
2727
super().__init__()
2828
self.fileobj = fileobj
@@ -49,7 +49,7 @@ def _fileobj_blocks_end_pos(self) -> int:
4949
def parse(
5050
cls,
5151
fileobj: BinaryIO,
52-
block_read_strategy: Optional[_BlockReadStrategyType] = None,
52+
block_read_strategy: _BlockReadStrategyType | None = None,
5353
) -> "XZStream":
5454
"""Parse one XZ stream from a fileobj.
5555

src/xz/typing.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
from collections.abc import Mapping, Sequence
22
from os import PathLike
3-
from typing import TYPE_CHECKING, Any, BinaryIO, Literal, Optional, Protocol, Union
3+
from typing import TYPE_CHECKING, Any, BinaryIO, Literal, Protocol
44

5-
_LZMAFilenameType = Union[str, bytes, PathLike[str], PathLike[bytes], BinaryIO]
5+
_LZMAFilenameType = str | bytes | PathLike[str] | PathLike[bytes] | BinaryIO
66

77

88
if TYPE_CHECKING:
99
# avoid circular dependency
1010
from xz.block import XZBlock
1111

1212

13-
_LZMAPresetType = Optional[int]
14-
_LZMAFiltersType = Optional[Sequence[Mapping[str, Any]]]
13+
_LZMAPresetType = int | None
14+
_LZMAFiltersType = Sequence[Mapping[str, Any]] | None
1515

1616

1717
# all valid modes if we don't consider changing order nor repetitions

tests/integration/test_file_read.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@ def test_read_all(integration_case: _IntegrationCase, data_pattern: bytes) -> No
1414
pos = 0
1515
stream_boundaries = []
1616
block_boundaries = []
17-
for stream_item, metadata_stream in zip(streams_items, metadata["streams"]):
17+
for stream_item, metadata_stream in zip(
18+
streams_items, metadata["streams"], strict=True
19+
):
1820
stream_boundaries.append(pos)
1921
stream_pos, stream = stream_item
2022
assert stream_pos == pos
2123
assert stream.check == metadata_stream["check"]
2224
block_items = list(stream._fileobjs.items())
2325
assert len(block_items) == len(metadata_stream["blocks"])
2426
for block_item, metadata_block in zip(
25-
block_items, metadata_stream["blocks"]
27+
block_items, metadata_stream["blocks"], strict=True
2628
):
2729
block_boundaries.append(pos)
2830
block_pos, block = block_item

0 commit comments

Comments
 (0)