Skip to content

Commit e14775b

Browse files
authored
Drop Python 3.7 (#497)
2 parents 825f442 + b374c46 commit e14775b

File tree

11 files changed

+284
-356
lines changed

11 files changed

+284
-356
lines changed

.github/workflows/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636

3737
- name: Install poetry
3838
if: env.PUBLISH == 'true'
39-
run: pipx install "poetry==1.5.1"
39+
run: pipx install "poetry==1.6.1"
4040

4141
- name: Set up Python ${{ matrix.python-version }}
4242
if: env.PUBLISH == 'true'

.github/workflows/tests.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ jobs:
1010
runs-on: ubuntu-latest
1111
strategy:
1212
matrix:
13-
python-version: ["3.7", "3.11"]
13+
python-version: ["3.8", "3.11"]
1414
tmux-version: ["2.6", "2.7", "2.8", "3.0a", "3.1b", "3.2a", "3.3a", "master"]
1515
steps:
1616
- uses: actions/checkout@v3
1717

1818
- name: Install poetry
19-
run: pipx install "poetry==1.5.1"
19+
run: pipx install "poetry==1.6.1"
2020

2121
- name: Set up Python ${{ matrix.python-version }}
2222
uses: actions/setup-python@v4
@@ -91,7 +91,7 @@ jobs:
9191
- uses: actions/checkout@v3
9292

9393
- name: Install poetry
94-
run: pipx install "poetry==1.5.1"
94+
run: pipx install "poetry==1.6.1"
9595

9696
- name: Set up Python ${{ matrix.python-version }}
9797
uses: actions/setup-python@v4

.tool-versions

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
poetry 1.5.1
1+
poetry 1.6.1
22
python 3.11.5 3.10.13 3.9.18 3.8.18 3.7.17

CHANGES

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

1515
<!-- Maintainers and contributors: Insert change notes for the next release above -->
1616

17+
### Breaking changes
18+
19+
- Python 3.7 Dropped (#497)
20+
21+
### Development
22+
23+
- Poetry 1.5.1 -> 1.6.1 (#497)
24+
1725
## libtmux 0.23.2 (2023-09-09)
1826

1927
_Maintenance only, no bug fixes or new features_

poetry.lock

Lines changed: 208 additions & 283 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ classifiers = [
1313
"Framework :: Pytest",
1414
"Intended Audience :: Developers",
1515
"Programming Language :: Python",
16-
"Programming Language :: Python :: 3.7",
1716
"Programming Language :: Python :: 3.8",
1817
"Programming Language :: Python :: 3.9",
1918
"Programming Language :: Python :: 3.10",
@@ -46,16 +45,16 @@ Repository = "https://github.com/tmux-python/libtmux"
4645
Changes = "https://github.com/tmux-python/libtmux/blob/master/CHANGES"
4746

4847
[tool.poetry.dependencies]
49-
python = "^3.7"
48+
python = "^3.8"
5049

5150
[tool.poetry.group.dev.dependencies]
5251
### Docs ###
5352
sphinx = "*"
5453
furo = "*"
55-
gp-libs = "~0.0.1"
54+
gp-libs = "~0.0.2"
5655
sphinx-autobuild = "*"
5756
sphinx-autodoc-typehints = "*"
58-
sphinx-inline-tabs = "<2023.4.21" # For Python 3.7 support
57+
sphinx-inline-tabs = "*"
5958
sphinxext-opengraph = "<0.8" # https://github.com/wpilibsuite/sphinxext-opengraph/issues/100
6059
sphinx-copybutton = "*"
6160
sphinxext-rediraffe = "*"
@@ -129,7 +128,7 @@ exclude_lines = [
129128
]
130129

131130
[tool.ruff]
132-
target-version = "py37"
131+
target-version = "py38"
133132
select = [
134133
"E", # pycodestyle
135134
"F", # pyflakes

src/libtmux/_internal/query_list.py

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,24 @@
66
"""
77
import re
88
import traceback
9+
import typing as t
910
from collections.abc import Mapping, Sequence
10-
from re import Pattern
11-
from typing import TYPE_CHECKING, Any, Callable, List, Optional, TypeVar, Union
1211

13-
if TYPE_CHECKING:
14-
from typing_extensions import Protocol
12+
if t.TYPE_CHECKING:
1513

16-
class LookupProtocol(Protocol):
14+
class LookupProtocol(t.Protocol):
1715
"""Protocol for :class:`QueryList` filtering operators."""
1816

1917
def __call__(
2018
self,
21-
data: Union[str, List[str], "Mapping[str, str]"],
22-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
19+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
20+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
2321
) -> bool:
2422
"""Callback for :class:`QueryList` filtering operators."""
2523
...
2624

2725

28-
T = TypeVar("T", Any, Any)
26+
T = t.TypeVar("T", t.Any, t.Any)
2927

3028
no_arg = object()
3129

@@ -39,9 +37,9 @@ class ObjectDoesNotExist(Exception):
3937

4038

4139
def keygetter(
42-
obj: "Mapping[str, Any]",
40+
obj: "Mapping[str, t.Any]",
4341
path: str,
44-
) -> Union[None, Any, str, List[str], "Mapping[str, str]"]:
42+
) -> t.Union[None, t.Any, str, t.List[str], "Mapping[str, str]"]:
4543
"""obj, "foods__breakfast", obj['foods']['breakfast']
4644
4745
>>> keygetter({ "foods": { "breakfast": "cereal" } }, "foods__breakfast")
@@ -67,7 +65,9 @@ def keygetter(
6765
return dct
6866

6967

70-
def parse_lookup(obj: "Mapping[str, Any]", path: str, lookup: str) -> Optional[Any]:
68+
def parse_lookup(
69+
obj: "Mapping[str, t.Any]", path: str, lookup: str
70+
) -> t.Optional[t.Any]:
7171
"""Check if field lookup key, e.g. "my__path__contains" has comparator, return val.
7272
7373
If comparator not used or value not found, return None.
@@ -88,15 +88,15 @@ def parse_lookup(obj: "Mapping[str, Any]", path: str, lookup: str) -> Optional[A
8888

8989

9090
def lookup_exact(
91-
data: Union[str, List[str], "Mapping[str, str]"],
92-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
91+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
92+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
9393
) -> bool:
9494
return rhs == data
9595

9696

9797
def lookup_iexact(
98-
data: Union[str, List[str], "Mapping[str, str]"],
99-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
98+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
99+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
100100
) -> bool:
101101
if not isinstance(rhs, str) or not isinstance(data, str):
102102
return False
@@ -105,8 +105,8 @@ def lookup_iexact(
105105

106106

107107
def lookup_contains(
108-
data: Union[str, List[str], "Mapping[str, str]"],
109-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
108+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
109+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
110110
) -> bool:
111111
if not isinstance(rhs, str) or not isinstance(data, (str, Mapping, list)):
112112
return False
@@ -115,8 +115,8 @@ def lookup_contains(
115115

116116

117117
def lookup_icontains(
118-
data: Union[str, List[str], "Mapping[str, str]"],
119-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
118+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
119+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
120120
) -> bool:
121121
if not isinstance(rhs, str) or not isinstance(data, (str, Mapping, list)):
122122
return False
@@ -130,8 +130,8 @@ def lookup_icontains(
130130

131131

132132
def lookup_startswith(
133-
data: Union[str, List[str], "Mapping[str, str]"],
134-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
133+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
134+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
135135
) -> bool:
136136
if not isinstance(rhs, str) or not isinstance(data, str):
137137
return False
@@ -140,8 +140,8 @@ def lookup_startswith(
140140

141141

142142
def lookup_istartswith(
143-
data: Union[str, List[str], "Mapping[str, str]"],
144-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
143+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
144+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
145145
) -> bool:
146146
if not isinstance(rhs, str) or not isinstance(data, str):
147147
return False
@@ -150,8 +150,8 @@ def lookup_istartswith(
150150

151151

152152
def lookup_endswith(
153-
data: Union[str, List[str], "Mapping[str, str]"],
154-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
153+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
154+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
155155
) -> bool:
156156
if not isinstance(rhs, str) or not isinstance(data, str):
157157
return False
@@ -160,17 +160,17 @@ def lookup_endswith(
160160

161161

162162
def lookup_iendswith(
163-
data: Union[str, List[str], "Mapping[str, str]"],
164-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
163+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
164+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
165165
) -> bool:
166166
if not isinstance(rhs, str) or not isinstance(data, str):
167167
return False
168168
return data.lower().endswith(rhs.lower())
169169

170170

171171
def lookup_in(
172-
data: Union[str, List[str], "Mapping[str, str]"],
173-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
172+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
173+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
174174
) -> bool:
175175
if isinstance(rhs, list):
176176
return data in rhs
@@ -191,8 +191,8 @@ def lookup_in(
191191

192192

193193
def lookup_nin(
194-
data: Union[str, List[str], "Mapping[str, str]"],
195-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
194+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
195+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
196196
) -> bool:
197197
if isinstance(rhs, list):
198198
return data not in rhs
@@ -213,17 +213,17 @@ def lookup_nin(
213213

214214

215215
def lookup_regex(
216-
data: Union[str, List[str], "Mapping[str, str]"],
217-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
216+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
217+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
218218
) -> bool:
219219
if isinstance(data, (str, bytes, re.Pattern)) and isinstance(rhs, (str, bytes)):
220220
return bool(re.search(rhs, data))
221221
return False
222222

223223

224224
def lookup_iregex(
225-
data: Union[str, List[str], "Mapping[str, str]"],
226-
rhs: Union[str, List[str], "Mapping[str, str]", "Pattern[str]"],
225+
data: t.Union[str, t.List[str], "Mapping[str, str]"],
226+
rhs: t.Union[str, t.List[str], "Mapping[str, str]", "re.Pattern[str]"],
227227
) -> bool:
228228
if isinstance(data, (str, bytes, re.Pattern)) and isinstance(rhs, (str, bytes)):
229229
return bool(re.search(rhs, data, re.IGNORECASE))
@@ -257,7 +257,7 @@ def __init__(self, op: str, *args: object):
257257
return super().__init__(f"{op} not in LOOKUP_NAME_MAP")
258258

259259

260-
class QueryList(List[T]):
260+
class QueryList(t.List[T]):
261261
"""Filter list of object/dictionaries. For small, local datasets.
262262
263263
*Experimental, unstable*.
@@ -293,21 +293,21 @@ class QueryList(List[T]):
293293
"""
294294

295295
data: "Sequence[T]"
296-
pk_key: Optional[str]
296+
pk_key: t.Optional[str]
297297

298-
def items(self) -> List[T]:
298+
def items(self) -> t.List[T]:
299299
if self.pk_key is None:
300300
raise PKRequiredException()
301301
return [(getattr(item, self.pk_key), item) for item in self]
302302

303303
def __eq__(
304304
self,
305305
other: object,
306-
# other: Union[
306+
# other: t.Union[
307307
# "QueryList[T]",
308-
# List[Mapping[str, str]],
309-
# List[Mapping[str, int]],
310-
# List[Mapping[str, Union[str, Mapping[str, Union[List[str], str]]]]],
308+
# t.List[Mapping[str, str]],
309+
# t.List[Mapping[str, int]],
310+
# t.List[Mapping[str, t.Union[str, Mapping[str, t.Union[List[str], str]]]]],
311311
# ],
312312
) -> bool:
313313
data = other
@@ -331,11 +331,13 @@ def __eq__(
331331
return False
332332

333333
def filter(
334-
self, matcher: Optional[Union[Callable[[T], bool], T]] = None, **kwargs: Any
334+
self,
335+
matcher: t.Optional[t.Union[t.Callable[[T], bool], T]] = None,
336+
**kwargs: t.Any,
335337
) -> "QueryList[T]":
336338
"""Filter list of objects."""
337339

338-
def filter_lookup(obj: Any) -> bool:
340+
def filter_lookup(obj: t.Any) -> bool:
339341
for path, v in kwargs.items():
340342
try:
341343
lhs, op = path.rsplit("__", 1)
@@ -359,7 +361,7 @@ def filter_lookup(obj: Any) -> bool:
359361
_filter = matcher
360362
elif matcher is not None:
361363

362-
def val_match(obj: Union[str, List[Any]]) -> bool:
364+
def val_match(obj: t.Union[str, t.List[t.Any]]) -> bool:
363365
if isinstance(matcher, list):
364366
return obj in matcher
365367
else:
@@ -373,10 +375,10 @@ def val_match(obj: Union[str, List[Any]]) -> bool:
373375

374376
def get(
375377
self,
376-
matcher: Optional[Union[Callable[[T], bool], T]] = None,
377-
default: Optional[Any] = no_arg,
378-
**kwargs: Any,
379-
) -> Optional[T]:
378+
matcher: t.Optional[t.Union[t.Callable[[T], bool], T]] = None,
379+
default: t.Optional[t.Any] = no_arg,
380+
**kwargs: t.Any,
381+
) -> t.Optional[T]:
380382
"""Retrieve one object.
381383
382384
Raises :exc:`MultipleObjectsReturned` if multiple objects found.

src/libtmux/neo.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@
77
from libtmux.formats import FORMAT_SEPARATOR
88

99
if t.TYPE_CHECKING:
10-
from typing_extensions import Literal
11-
12-
ListCmd = Literal["list-sessions", "list-windows", "list-panes"]
10+
ListCmd = t.Literal["list-sessions", "list-windows", "list-panes"]
1311
ListExtraArgs = t.Optional[t.Iterable[str]]
1412

1513
from libtmux.server import Server

src/libtmux/pane.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
from . import exc
1818

1919
if t.TYPE_CHECKING:
20-
from typing_extensions import Literal
21-
2220
from .server import Server
2321
from .session import Session
2422
from .window import Window
@@ -158,8 +156,8 @@ def resize_pane(self, *args: t.Any, **kwargs: t.Any) -> "Pane":
158156

159157
def capture_pane(
160158
self,
161-
start: t.Union["Literal['-']", t.Optional[int]] = None,
162-
end: t.Union["Literal['-']", t.Optional[int]] = None,
159+
start: t.Union["t.Literal['-']", t.Optional[int]] = None,
160+
end: t.Union["t.Literal['-']", t.Optional[int]] = None,
163161
) -> t.Union[str, t.List[str]]:
164162
"""
165163
Capture text from pane.
@@ -248,12 +246,12 @@ def send_keys(
248246

249247
@overload
250248
def display_message(
251-
self, cmd: str, get_text: "Literal[True]"
249+
self, cmd: str, get_text: "t.Literal[True]"
252250
) -> t.Union[str, t.List[str]]:
253251
...
254252

255253
@overload
256-
def display_message(self, cmd: str, get_text: "Literal[False]") -> None:
254+
def display_message(self, cmd: str, get_text: "t.Literal[False]") -> None:
257255
...
258256

259257
def display_message(

0 commit comments

Comments
 (0)