Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ jobs:
strategy:
matrix:
python:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ adheres to [Semantic Versioning](https://semver.org/).

### :boom: Breaking changes

- End of Python 3.7 and 3.8 support
- End of Python 3.7, 3.8, and 3.9 support

### :house: Internal

Expand Down
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand All @@ -23,7 +22,7 @@ classifiers = [
"Topic :: System :: Archiving",
"Topic :: System :: Archiving :: Compression",
]
requires-python = ">=3.9"
requires-python = ">=3.10"

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

[tool.ruff]
src = ["src"]
target-version = "py39"
target-version = "py310"

[tool.ruff.lint]
select = ["ALL"]
Expand Down
5 changes: 2 additions & 3 deletions src/xz/block.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from io import DEFAULT_BUFFER_SIZE, SEEK_SET
from lzma import FORMAT_XZ, LZMACompressor, LZMADecompressor, LZMAError
from typing import Optional, Union

from xz.common import (
XZError,
Expand Down Expand Up @@ -122,7 +121,7 @@ def __init__(
uncompressed_size: int,
preset: _LZMAPresetType = None,
filters: _LZMAFiltersType = None,
block_read_strategy: Optional[_BlockReadStrategyType] = None,
block_read_strategy: _BlockReadStrategyType | None = None,
) -> None:
super().__init__(uncompressed_size)
self.fileobj = fileobj
Expand All @@ -131,7 +130,7 @@ def __init__(
self.filters = filters
self.block_read_strategy = block_read_strategy or KeepBlockReadStrategy()
self.unpadded_size = unpadded_size
self.operation: Union[BlockRead, BlockWrite, None] = None
self.operation: BlockRead | BlockWrite | None = None

@property
def uncompressed_size(self) -> int:
Expand Down
14 changes: 6 additions & 8 deletions src/xz/file.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from io import SEEK_CUR, SEEK_END
import os
import sys
from typing import BinaryIO, Optional, cast
from typing import BinaryIO, cast
import warnings

from xz.common import DEFAULT_CHECK, XZError
Expand Down Expand Up @@ -36,7 +35,7 @@ def __init__(
check: int = -1,
preset: _LZMAPresetType = None,
filters: _LZMAFiltersType = None,
block_read_strategy: Optional[_BlockReadStrategyType] = None,
block_read_strategy: _BlockReadStrategyType | None = None,
) -> None:
"""Open an XZ file in binary mode.

Expand Down Expand Up @@ -113,7 +112,7 @@ def __init__(
self._close_check_empty = self._mode[0] != "r"

@property
def _last_stream(self) -> Optional[XZStream]:
def _last_stream(self) -> XZStream | None:
try:
return self._fileobjs.last_item
except KeyError:
Expand Down Expand Up @@ -145,10 +144,9 @@ def close(self) -> None:
finally:
if self._close_fileobj:
self.fileobj.close() # self.fileobj exists at this point
if sys.version_info < (3, 10): # pragma: no cover
# fix coverage issue on some Python versions
# see https://github.com/nedbat/coveragepy/issues/1480
pass

# fix coverage issue on some Python versions
pass # noqa: PIE790

@property
def stream_boundaries(self) -> list[int]:
Expand Down
8 changes: 4 additions & 4 deletions src/xz/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
IOBase,
UnsupportedOperation,
)
from typing import BinaryIO, Generic, Optional, TypeVar, Union, cast
from typing import BinaryIO, Generic, TypeVar, cast

from xz.utils import FloorDict

Expand Down Expand Up @@ -150,7 +150,7 @@ def write(self, data: bytes) -> int:
self._length = max(self._length, self._pos)
return written_bytes

def truncate(self, size: Optional[int] = None) -> int:
def truncate(self, size: int | None = None) -> int:
"""Truncate file to size bytes.
Size defaults to the current IO position as reported by tell().

Expand Down Expand Up @@ -242,7 +242,7 @@ def _read(self, size: int) -> bytes:
class IOProxy(IOAbstract):
def __init__(
self,
fileobj: Union[BinaryIO, IOBase], # see typing note on top of this file
fileobj: BinaryIO | IOBase, # see typing note on top of this file
start: int,
end: int,
) -> None:
Expand Down Expand Up @@ -290,7 +290,7 @@ def _write_after(self) -> None:

def _write(self, data: bytes) -> int:
if self._fileobjs:
fileobj: Optional[T] = self._get_fileobj()
fileobj: T | None = self._get_fileobj()
else:
fileobj = None

Expand Down
46 changes: 23 additions & 23 deletions src/xz/open.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from io import TextIOWrapper
from typing import BinaryIO, Optional, Union, cast, overload
from typing import BinaryIO, cast, overload

from xz.file import XZFile
from xz.typing import (
Expand All @@ -22,10 +22,10 @@ def __init__(
check: int = -1,
preset: _LZMAPresetType = None,
filters: _LZMAFiltersType = None,
block_read_strategy: Optional[_BlockReadStrategyType] = None,
encoding: Optional[str] = None,
errors: Optional[str] = None,
newline: Optional[str] = None,
block_read_strategy: _BlockReadStrategyType | None = None,
encoding: str | None = None,
errors: str | None = None,
newline: str | None = None,
) -> None:
self.xz_file = XZFile(
filename,
Expand Down Expand Up @@ -75,11 +75,11 @@ def xz_open(
check: int = -1,
preset: _LZMAPresetType = None,
filters: _LZMAFiltersType = None,
block_read_strategy: Optional[_BlockReadStrategyType] = None,
block_read_strategy: _BlockReadStrategyType | None = None,
# text-mode kwargs
encoding: Optional[str] = None,
errors: Optional[str] = None,
newline: Optional[str] = None,
encoding: str | None = None,
errors: str | None = None,
newline: str | None = None,
) -> XZFile: ...


Expand All @@ -92,11 +92,11 @@ def xz_open(
check: int = -1,
preset: _LZMAPresetType = None,
filters: _LZMAFiltersType = None,
block_read_strategy: Optional[_BlockReadStrategyType] = None,
block_read_strategy: _BlockReadStrategyType | None = None,
# text-mode kwargs
encoding: Optional[str] = None,
errors: Optional[str] = None,
newline: Optional[str] = None,
encoding: str | None = None,
errors: str | None = None,
newline: str | None = None,
) -> _XZFileText: ...


Expand All @@ -109,12 +109,12 @@ def xz_open(
check: int = -1,
preset: _LZMAPresetType = None,
filters: _LZMAFiltersType = None,
block_read_strategy: Optional[_BlockReadStrategyType] = None,
block_read_strategy: _BlockReadStrategyType | None = None,
# text-mode kwargs
encoding: Optional[str] = None,
errors: Optional[str] = None,
newline: Optional[str] = None,
) -> Union[XZFile, _XZFileText]: ...
encoding: str | None = None,
errors: str | None = None,
newline: str | None = None,
) -> XZFile | _XZFileText: ...


def xz_open(
Expand All @@ -125,12 +125,12 @@ def xz_open(
check: int = -1,
preset: _LZMAPresetType = None,
filters: _LZMAFiltersType = None,
block_read_strategy: Optional[_BlockReadStrategyType] = None,
block_read_strategy: _BlockReadStrategyType | None = None,
# text-mode kwargs
encoding: Optional[str] = None,
errors: Optional[str] = None,
newline: Optional[str] = None,
) -> Union[XZFile, _XZFileText]:
encoding: str | None = None,
errors: str | None = None,
newline: str | None = None,
) -> XZFile | _XZFileText:
"""Open an XZ file in binary or text mode.

filename can be either an actual file name (given as a str, bytes,
Expand Down
6 changes: 3 additions & 3 deletions src/xz/stream.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from io import SEEK_CUR
from typing import BinaryIO, Optional
from typing import BinaryIO

from xz.block import XZBlock
from xz.common import (
Expand All @@ -22,7 +22,7 @@ def __init__(
check: int,
preset: _LZMAPresetType = None,
filters: _LZMAFiltersType = None,
block_read_strategy: Optional[_BlockReadStrategyType] = None,
block_read_strategy: _BlockReadStrategyType | None = None,
) -> None:
super().__init__()
self.fileobj = fileobj
Expand All @@ -49,7 +49,7 @@ def _fileobj_blocks_end_pos(self) -> int:
def parse(
cls,
fileobj: BinaryIO,
block_read_strategy: Optional[_BlockReadStrategyType] = None,
block_read_strategy: _BlockReadStrategyType | None = None,
) -> "XZStream":
"""Parse one XZ stream from a fileobj.

Expand Down
8 changes: 4 additions & 4 deletions src/xz/typing.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
from collections.abc import Mapping, Sequence
from os import PathLike
from typing import TYPE_CHECKING, Any, BinaryIO, Literal, Optional, Protocol, Union
from typing import TYPE_CHECKING, Any, BinaryIO, Literal, Protocol

_LZMAFilenameType = Union[str, bytes, PathLike[str], PathLike[bytes], BinaryIO]
_LZMAFilenameType = str | bytes | PathLike[str] | PathLike[bytes] | BinaryIO


if TYPE_CHECKING:
# avoid circular dependency
from xz.block import XZBlock


_LZMAPresetType = Optional[int]
_LZMAFiltersType = Optional[Sequence[Mapping[str, Any]]]
_LZMAPresetType = int | None
_LZMAFiltersType = Sequence[Mapping[str, Any]] | None


# all valid modes if we don't consider changing order nor repetitions
Expand Down
6 changes: 4 additions & 2 deletions tests/integration/test_file_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ def test_read_all(integration_case: _IntegrationCase, data_pattern: bytes) -> No
pos = 0
stream_boundaries = []
block_boundaries = []
for stream_item, metadata_stream in zip(streams_items, metadata["streams"]):
for stream_item, metadata_stream in zip(
streams_items, metadata["streams"], strict=True
):
stream_boundaries.append(pos)
stream_pos, stream = stream_item
assert stream_pos == pos
assert stream.check == metadata_stream["check"]
block_items = list(stream._fileobjs.items())
assert len(block_items) == len(metadata_stream["blocks"])
for block_item, metadata_block in zip(
block_items, metadata_stream["blocks"]
block_items, metadata_stream["blocks"], strict=True
):
block_boundaries.append(pos)
block_pos, block = block_item
Expand Down
6 changes: 3 additions & 3 deletions tests/integration/test_ram_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from lzma import compress
from pathlib import Path
from random import randbytes, seed
from typing import BinaryIO, Optional, cast
from typing import BinaryIO, cast

import pytest

Expand Down Expand Up @@ -70,7 +70,7 @@ def test_read_linear(fileobj: BinaryIO, ram_usage: Callable[[], int]) -> None:
def test_partial_read_each_block(
fileobj: BinaryIO, ram_usage: Callable[[], int]
) -> None:
one_block_memory: Optional[int] = None
one_block_memory: int | None = None

with XZFile(fileobj) as xz_file:
for pos in xz_file.block_boundaries[1:]:
Expand All @@ -93,7 +93,7 @@ def test_write(tmp_path: Path, ram_usage: Callable[[], int]) -> None:

seed(0)

one_block_memory: Optional[int] = None
one_block_memory: int | None = None

with XZFile(tmp_path / "archive.xz", "w") as xz_file:
for i in range(nb_blocks):
Expand Down
3 changes: 1 addition & 2 deletions tests/integration/test_readme.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import os
from pathlib import Path
import shutil
from typing import Optional

import pytest

Expand All @@ -22,7 +21,7 @@ def change_dir(tmp_path: Path) -> Iterator[None]:
def _parse_readme() -> list[tuple[int, str]]:
code_blocks = []
current_code_block = ""
current_code_block_line: Optional[int] = None
current_code_block_line: int | None = None
with (Path(__file__).parent.parent.parent / "README.md").open() as fin:
for line_no, line in enumerate(fin):
if line.startswith("```"):
Expand Down
4 changes: 1 addition & 3 deletions tests/unit/test_attr_proxy.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import Optional

import pytest

from xz.utils import AttrProxy
Expand All @@ -10,7 +8,7 @@ class Dest:


class Src:
proxy: Optional[Dest] = None
proxy: Dest | None = None
abc = AttrProxy[str]("proxy")


Expand Down
Loading