11import re
22import sys
3- from .model import Rect , Gaps
4- from . import replies
53from collections import deque
6- from typing import Any , cast , Generic , Literal , Optional , TypeVar , TYPE_CHECKING
4+ from collections .abc import Iterator
5+ from typing import TYPE_CHECKING , Any , Literal , Optional , Self
6+
7+ from . import replies
8+ from .model import Gaps , Rect
79
810if TYPE_CHECKING :
911 from .connection import Connection
1012
11- _Con = TypeVar ('_Con' , bound = 'Con' )
12-
1313
14- class Con ( Generic [ _Con ]) :
14+ class Con :
1515 """A container of a window and child containers gotten from :func:`i3ipc.Connection.get_tree()` or events.
1616
1717 .. seealso:: https://i3wm.org/docs/ipc.html#_tree_reply
@@ -123,7 +123,7 @@ class Con(Generic[_Con]):
123123 representation : str
124124 visible : bool
125125
126- def __init__ (self : _Con , data : dict [str , Any ], parent : _Con , conn : 'Connection' ):
126+ def __init__ (self , data : dict [str , Any ], parent : Self , conn : 'Connection' ):
127127 self .ipc_data = data
128128 self ._conn = conn
129129 self .parent = parent
@@ -142,7 +142,7 @@ def __init__(self: _Con, data: dict[str, Any], parent: _Con, conn: 'Connection')
142142 setattr (self , attr , None )
143143
144144 # XXX in 4.12, marks is an array (old property was a string "mark")
145- if self .marks is None :
145+ if self .marks is None : # type: ignore reportUnnecessaryComparison
146146 self .marks = []
147147 if 'mark' in data and data ['mark' ]:
148148 self .marks .append (data ['mark' ])
@@ -161,15 +161,15 @@ def __init__(self: _Con, data: dict[str, Any], parent: _Con, conn: 'Connection')
161161 self .type = "dockarea"
162162
163163 # set complex properties
164- self .nodes = []
164+ self .nodes : list [ Self ] = []
165165 if 'nodes' in data :
166166 for n in data ['nodes' ]:
167- self .nodes .append (cast ( _Con , self .__class__ (n , self , conn ) ))
167+ self .nodes .append (self .__class__ (n , self , conn ))
168168
169- self .floating_nodes = []
169+ self .floating_nodes : list [ Self ] = []
170170 if 'floating_nodes' in data :
171171 for n in data ['floating_nodes' ]:
172- self .floating_nodes .append (cast ( _Con , self .__class__ (n , self , conn ) ))
172+ self .floating_nodes .append (self .__class__ (n , self , conn ))
173173
174174 self .window_class = None
175175 self .window_instance = None
@@ -201,7 +201,7 @@ def __init__(self: _Con, data: dict[str, Any], parent: _Con, conn: 'Connection')
201201 if 'gaps' in data :
202202 self .gaps = Gaps (data ['gaps' ])
203203
204- def __iter__ (self ):
204+ def __iter__ (self ) -> Iterator [ Self ] :
205205 """Iterate through the descendents of this node (breadth-first tree traversal)
206206 """
207207 queue = deque (self .nodes )
@@ -223,15 +223,15 @@ def is_floating(self) -> bool:
223223 return True
224224 return False
225225
226- def root (self ) -> _Con :
226+ def root (self ) -> Self :
227227 """Gets the root container.
228228
229229 :returns: The root container.
230230 :rtype: :class:`Con`
231231 """
232232
233233 if not self .parent :
234- return cast ( _Con , self )
234+ return self
235235
236236 con = self .parent
237237
@@ -240,7 +240,7 @@ def root(self) -> _Con:
240240
241241 return con
242242
243- def descendants (self ) -> list [_Con ]:
243+ def descendants (self ) -> list [Self ]:
244244 """Gets a list of all child containers for the container in
245245 breadth-first order.
246246
@@ -249,7 +249,7 @@ def descendants(self) -> list[_Con]:
249249 """
250250 return [c for c in self ]
251251
252- def descendents (self ) -> list [_Con ]:
252+ def descendents (self ) -> list [Self ]:
253253 """Gets a list of all child containers for the container in
254254 breadth-first order.
255255
@@ -262,15 +262,15 @@ def descendents(self) -> list[_Con]:
262262 print ('WARNING: descendents is deprecated. Use `descendants()` instead.' , file = sys .stderr )
263263 return self .descendants ()
264264
265- def leaves (self ) -> list [_Con ]:
265+ def leaves (self ) -> list [Self ]:
266266 """Gets a list of leaf child containers for this container in
267267 breadth-first order. Leaf containers normally contain application
268268 windows.
269269
270270 :returns: A list of leaf descendants.
271271 :rtype: list(:class:`Con`)
272272 """
273- leaves = []
273+ leaves : list [ Self ] = []
274274
275275 for c in self :
276276 if not c .nodes and c .type == "con" and c .parent .type != "dockarea" :
@@ -299,21 +299,21 @@ def command_children(self, command: str) -> list[replies.CommandReply]:
299299 :rtype: list(:class:`CommandReply <i3ipc.CommandReply>`)
300300 """
301301
302- commands = []
302+ commands : list [ str ] = []
303303 for c in self .nodes :
304304 commands .append ('[con_id="{}"] {};' .format (c .id , command ))
305305
306306 return self ._conn .command (' ' .join (commands ))
307307
308- def workspaces (self ) -> list [_Con ]:
308+ def workspaces (self ) -> list [Self ]:
309309 """Gets a list of workspace containers for this tree.
310310
311311 :returns: A list of workspace containers.
312312 :rtype: list(:class:`Con`)
313313 """
314- workspaces = []
314+ workspaces : list [ Self ] = []
315315
316- def collect_workspaces (con ):
316+ def collect_workspaces (con : Self ):
317317 if con .type == "workspace" and not con .name .startswith ('__' ):
318318 workspaces .append (con )
319319 return
@@ -324,7 +324,7 @@ def collect_workspaces(con):
324324 collect_workspaces (self .root ())
325325 return workspaces
326326
327- def find_focused (self ) -> Optional [_Con ]:
327+ def find_focused (self ) -> Optional [Self ]:
328328 """Finds the focused container under this container if it exists.
329329
330330 :returns: The focused container if it exists.
@@ -336,7 +336,7 @@ def find_focused(self) -> Optional[_Con]:
336336 except StopIteration :
337337 return None
338338
339- def find_by_id (self , id : int ) -> Optional [_Con ]:
339+ def find_by_id (self , id : int ) -> Optional [Self ]:
340340 """Finds a container with the given container id under this node.
341341
342342 :returns: The container with this container id if it exists.
@@ -348,15 +348,15 @@ def find_by_id(self, id: int) -> Optional[_Con]:
348348 except StopIteration :
349349 return None
350350
351- def find_by_pid (self , pid : int ) -> list [_Con ]:
351+ def find_by_pid (self , pid : int ) -> list [Self ]:
352352 """Finds all the containers under this node with this pid.
353353
354354 :returns: A list of containers with this pid.
355355 :rtype: list(:class:`Con`)
356356 """
357357 return [c for c in self if c .pid == pid ]
358358
359- def find_by_window (self , window : int ) -> Optional [_Con ]:
359+ def find_by_window (self , window : int ) -> Optional [Self ]:
360360 """Finds a container with the given window id under this node.
361361
362362 :returns: The container with this window id if it exists.
@@ -368,7 +368,7 @@ def find_by_window(self, window: int) -> Optional[_Con]:
368368 except StopIteration :
369369 return None
370370
371- def find_by_role (self , pattern : str ) -> list [_Con ]:
371+ def find_by_role (self , pattern : str ) -> list [Self ]:
372372 """Finds all the containers under this node with a window role that
373373 matches the given regex pattern.
374374
@@ -378,7 +378,7 @@ def find_by_role(self, pattern: str) -> list[_Con]:
378378 """
379379 return [c for c in self if c .window_role and re .search (pattern , c .window_role )]
380380
381- def find_named (self , pattern : str ) -> list [_Con ]:
381+ def find_named (self , pattern : str ) -> list [Self ]:
382382 """Finds all the containers under this node with a name that
383383 matches the given regex pattern.
384384
@@ -388,7 +388,7 @@ def find_named(self, pattern: str) -> list[_Con]:
388388 """
389389 return [c for c in self if c .name and re .search (pattern , c .name )]
390390
391- def find_titled (self , pattern : str ) -> list [_Con ]:
391+ def find_titled (self , pattern : str ) -> list [Self ]:
392392 """Finds all the containers under this node with a window title that
393393 matches the given regex pattern.
394394
@@ -398,7 +398,7 @@ def find_titled(self, pattern: str) -> list[_Con]:
398398 """
399399 return [c for c in self if c .window_title and re .search (pattern , c .window_title )]
400400
401- def find_classed (self , pattern : str ) -> list [_Con ]:
401+ def find_classed (self , pattern : str ) -> list [Self ]:
402402 """Finds all the containers under this node with a window class,
403403 or app_id that matches the given regex pattern.
404404
@@ -411,7 +411,7 @@ def find_classed(self, pattern: str) -> list[_Con]:
411411
412412 return x11_windows + wayland_windows
413413
414- def find_instanced (self , pattern : str ) -> list [_Con ]:
414+ def find_instanced (self , pattern : str ) -> list [Self ]:
415415 """Finds all the containers under this node with a window instance that
416416 matches the given regex pattern.
417417
@@ -421,7 +421,7 @@ def find_instanced(self, pattern: str) -> list[_Con]:
421421 """
422422 return [c for c in self if c .window_instance and re .search (pattern , c .window_instance )]
423423
424- def find_marked (self , pattern : str = ".*" ) -> list [_Con ]:
424+ def find_marked (self , pattern : str = ".*" ) -> list [Self ]:
425425 """Finds all the containers under this node with a mark that
426426 matches the given regex pattern.
427427
@@ -432,7 +432,7 @@ def find_marked(self, pattern: str = ".*") -> list[_Con]:
432432 cpattern = re .compile (pattern )
433433 return [c for c in self if any (cpattern .search (mark ) for mark in c .marks )]
434434
435- def find_fullscreen (self ) -> list [_Con ]:
435+ def find_fullscreen (self ) -> list [Self ]:
436436 """Finds all the containers under this node that are in fullscreen
437437 mode.
438438
@@ -441,7 +441,7 @@ def find_fullscreen(self) -> list[_Con]:
441441 """
442442 return [c for c in self if c .type == 'con' and c .fullscreen_mode ]
443443
444- def workspace (self ) -> Optional [_Con ]:
444+ def workspace (self ) -> Optional [Self ]:
445445 """Finds the workspace container for this node if this container is at
446446 or below the workspace level.
447447
@@ -450,7 +450,7 @@ def workspace(self) -> Optional[_Con]:
450450 workspace level.
451451 """
452452 if self .type == 'workspace' :
453- return cast ( _Con , self )
453+ return self
454454
455455 ret = self .parent
456456
@@ -461,7 +461,7 @@ def workspace(self) -> Optional[_Con]:
461461
462462 return ret
463463
464- def scratchpad (self ) -> Optional [_Con ]:
464+ def scratchpad (self ) -> Optional [Self ]:
465465 """Finds the scratchpad container.
466466
467467 :returns: The scratchpad container.
0 commit comments