Skip to content

Commit d19157d

Browse files
authored
Drop Python 3.9 (#497)
# Changes ## Drop Python 3.9 EOL of 2025-10-31. See also: - https://devguide.python.org/versions/#:~:text=Release%20manager-,3.9,-PEP%20596 - https://peps.python.org/pep-0596/
2 parents 633127d + 1a8b6d3 commit d19157d

File tree

18 files changed

+200
-527
lines changed

18 files changed

+200
-527
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
runs-on: ubuntu-latest
1717
strategy:
1818
matrix:
19-
python-version: ['3.9', '3.14']
19+
python-version: ['3.10', '3.14']
2020
steps:
2121
- uses: actions/checkout@v4
2222
- name: Install uv

CHANGES

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ $ pip install --user --upgrade --pre libvcs
1515

1616
_Upcoming changes will be written here._
1717

18+
### Breaking changes
19+
20+
- Drop support for Python 3.9; the new minimum is Python 3.10 (#497).
21+
22+
See also:
23+
- [Python 3.9 EOL timeline](https://devguide.python.org/versions/#:~:text=Release%20manager-,3.9,-PEP%20596)
24+
- [PEP 596](https://peps.python.org/pep-0596/)
25+
1826
### Development
1927

2028
- Add Python 3.14 to test matrix (#496)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ detection and parsing of URLs, commanding, and syncing with `git`, `hg`, and `sv
1414
Python API.
1515
- **py.test fixtures**: Create temporary local repositories and working copies for testing for unit tests.
1616

17-
_Supports Python 3.9 and above, Git (including AWS CodeCommit), Subversion, and Mercurial._
17+
_Supports Python 3.10 and above, Git (including AWS CodeCommit), Subversion, and Mercurial._
1818

1919
To **get started**, see the [quickstart guide](https://libvcs.git-pull.com/quickstart.html) for more information.
2020

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "libvcs"
33
version = "0.36.0"
44
description = "Lite, typed, python utilities for Git, SVN, Mercurial, etc."
5-
requires-python = ">=3.9,<4.0"
5+
requires-python = ">=3.10,<4.0"
66
authors = [
77
{name = "Tony Narlock", email = "[email protected]"}
88
]
@@ -36,7 +36,6 @@ classifiers = [
3636
"Operating System :: MacOS :: MacOS X",
3737
"Programming Language :: Python",
3838
"Programming Language :: Python :: 3",
39-
"Programming Language :: Python :: 3.9",
4039
"Programming Language :: Python :: 3.10",
4140
"Programming Language :: Python :: 3.11",
4241
"Programming Language :: Python :: 3.12",
@@ -130,6 +129,7 @@ build-backend = "hatchling.build"
130129

131130
[tool.mypy]
132131
strict = true
132+
python_version = "3.10"
133133
files = [
134134
"src",
135135
"tests",
@@ -158,7 +158,7 @@ exclude_lines = [
158158
]
159159

160160
[tool.ruff]
161-
target-version = "py39"
161+
target-version = "py310"
162162

163163
[tool.ruff.lint]
164164
select = [

src/libvcs/_internal/query_list.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def keygetter(
9191
dct = getattr(dct, sub_field)
9292
except Exception as e:
9393
traceback.print_stack()
94-
logger.debug(f"The above error was {e}")
94+
logger.debug("The above error was %s", e)
9595
return None
9696
return dct
9797

@@ -122,12 +122,12 @@ def parse_lookup(obj: Mapping[str, t.Any], path: str, lookup: str) -> t.Any | No
122122
"""
123123
try:
124124
if isinstance(path, str) and isinstance(lookup, str) and path.endswith(lookup):
125-
field_name = path.rsplit(lookup)[0]
125+
field_name = path.split(lookup, maxsplit=1)[0]
126126
if field_name is not None:
127127
return keygetter(obj, field_name)
128128
except Exception as e:
129129
traceback.print_stack()
130-
logger.debug(f"The above error was {e}")
130+
logger.debug("The above error was %s", e)
131131
return None
132132

133133

@@ -489,7 +489,7 @@ def __eq__(
489489
return False
490490

491491
if len(self) == len(data):
492-
for a, b in zip(self, data):
492+
for a, b in zip(self, data, strict=False):
493493
if isinstance(a, Mapping):
494494
a_keys = a.keys()
495495
if a.keys == b.keys():

src/libvcs/_internal/run.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def console_to_str(s: bytes) -> str:
3737

3838
if t.TYPE_CHECKING:
3939
_LoggerAdapter = logging.LoggerAdapter[logging.Logger]
40-
from typing_extensions import TypeAlias
40+
from typing import TypeAlias
4141
else:
4242
_LoggerAdapter = logging.LoggerAdapter
4343

@@ -98,13 +98,10 @@ def __call__(self, output: str, timestamp: datetime.datetime) -> None:
9898
if sys.platform == "win32":
9999
_ENV: TypeAlias = Mapping[str, str]
100100
else:
101-
_ENV: TypeAlias = t.Union[
102-
Mapping[bytes, StrPath],
103-
Mapping[str, StrPath],
104-
]
101+
_ENV: TypeAlias = Mapping[bytes, StrPath] | Mapping[str, StrPath]
105102

106-
_CMD = t.Union[StrPath, Sequence[StrPath]]
107-
_FILE: TypeAlias = t.Optional[t.Union[int, t.IO[t.Any]]]
103+
_CMD = StrPath | Sequence[StrPath]
104+
_FILE: TypeAlias = int | t.IO[t.Any] | None
108105

109106

110107
def run(

src/libvcs/_internal/shortcuts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from libvcs.url import registry as url_tools
1515

1616
if t.TYPE_CHECKING:
17-
from typing_extensions import TypeGuard
17+
from typing import TypeGuard
1818

1919
from libvcs._internal.run import ProgressCallbackProtocol
2020
from libvcs._internal.types import StrPath, VCSLiteral

src/libvcs/_internal/subprocess.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
from .dataclasses import SkipDefaultFieldsReprMixin
5353

5454
if t.TYPE_CHECKING:
55-
from typing_extensions import TypeAlias
55+
from typing import TypeAlias
5656

5757

5858
F = t.TypeVar("F", bound=t.Callable[..., t.Any])
@@ -66,14 +66,11 @@ def __init__(self, output: str, *args: object) -> None:
6666
if sys.platform == "win32":
6767
_ENV: TypeAlias = Mapping[str, str]
6868
else:
69-
_ENV: TypeAlias = t.Union[
70-
Mapping[bytes, StrOrBytesPath],
71-
Mapping[str, StrOrBytesPath],
72-
]
73-
_FILE: TypeAlias = t.Union[None, int, t.IO[t.Any]]
74-
_TXT: TypeAlias = t.Union[bytes, str]
69+
_ENV: TypeAlias = Mapping[bytes, StrOrBytesPath] | Mapping[str, StrOrBytesPath]
70+
_FILE: TypeAlias = None | int | t.IO[t.Any]
71+
_TXT: TypeAlias = bytes | str
7572
#: Command
76-
_CMD: TypeAlias = t.Union[StrOrBytesPath, Sequence[StrOrBytesPath]]
73+
_CMD: TypeAlias = StrOrBytesPath | Sequence[StrOrBytesPath]
7774

7875

7976
@dataclasses.dataclass(repr=False)
@@ -191,8 +188,7 @@ class SubprocessCommand(SkipDefaultFieldsReprMixin):
191188
start_new_session: bool = False
192189
pass_fds: t.Any = ()
193190
umask: int = -1
194-
if sys.version_info >= (3, 10):
195-
pipesize: int = -1
191+
pipesize: int = -1
196192
user: str | None = None
197193
group: str | None = None
198194
extra_groups: list[str] | None = None

src/libvcs/_internal/types.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,12 @@
1313
from os import PathLike
1414

1515
if t.TYPE_CHECKING:
16-
from typing_extensions import TypeAlias
16+
from typing import TypeAlias
1717

18-
StrPath: TypeAlias = t.Union[str, PathLike[str]] # stable
18+
StrPath: TypeAlias = str | PathLike[str] # stable
1919
""":class:`os.PathLike` or :class:`str`"""
2020

21-
StrOrBytesPath: TypeAlias = t.Union[
22-
str,
23-
bytes,
24-
PathLike[str],
25-
PathLike[bytes], # stable
26-
]
21+
StrOrBytesPath: TypeAlias = str | bytes | PathLike[str] | PathLike[bytes]
2722
""":class:`os.PathLike`, :class:`str` or :term:`bytes-like object`"""
2823

2924

src/libvcs/cmd/git.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from libvcs._internal.run import ProgressCallbackProtocol, run
1212
from libvcs._internal.types import StrOrBytesPath, StrPath
1313

14-
_CMD = t.Union[StrOrBytesPath, Sequence[StrOrBytesPath]]
14+
_CMD = StrOrBytesPath | Sequence[StrOrBytesPath]
1515

1616

1717
class Git:

0 commit comments

Comments
 (0)