diff --git a/docs/conf.py b/docs/conf.py index 9f9299da..ae49972d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -10,7 +10,7 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -from typing import Dict +from __future__ import annotations # -- Project information ----------------------------------------------------- @@ -111,7 +111,7 @@ # -- Options for LaTeX output ------------------------------------------------ -latex_elements: Dict[str, str] = { +latex_elements: dict[str, str] = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', diff --git a/gaphas/connector.py b/gaphas/connector.py index 064ed657..0ca8c96b 100644 --- a/gaphas/connector.py +++ b/gaphas/connector.py @@ -1,5 +1,7 @@ +from __future__ import annotations + from functools import singledispatch -from typing import Callable, Optional, Protocol +from typing import Callable, Protocol from gaphas.connections import Connections from gaphas.geometry import intersect_line_line @@ -13,14 +15,14 @@ class ConnectionSinkType(Protocol): item: Item - port: Optional[Port] + port: Port | None def __init__(self, item: Item, distance: float = 10): ... def glue( - self, pos: SupportsFloatPos, secondary_pos: Optional[SupportsFloatPos] = None - ) -> Optional[Pos]: + self, pos: SupportsFloatPos, secondary_pos: SupportsFloatPos | None = None + ) -> Pos | None: ... def constraint(self, item: Item, handle: Handle) -> Constraint: @@ -40,10 +42,10 @@ def __init__(self, item: Item, handle: Handle, connections: Connections): def allow(self, sink): return True - def secondary_handle(self) -> Optional[Handle]: + def secondary_handle(self) -> Handle | None: return None - def glue(self, sink: ConnectionSinkType) -> Optional[Pos]: + def glue(self, sink: ConnectionSinkType) -> Pos | None: """Glue the Connector handle on the sink's port.""" handle = self.handle item = self.item @@ -80,7 +82,7 @@ def connect(self, sink: ConnectionSinkType) -> None: def connect_handle( self, sink: ConnectionSinkType, - callback: Optional[Callable[[Item, Handle, Item, Port], None]] = None, + callback: Callable[[Item, Handle, Item, Port], None] | None = None, ) -> None: """Create constraint between handle of a line and port of connectable item. @@ -110,7 +112,7 @@ def disconnect(self) -> None: @Connector.register(Line) class LineConnector(ItemConnector): - def secondary_handle(self) -> Optional[Handle]: + def secondary_handle(self) -> Handle | None: item = self.item handle = self.handle handles = item.handles() @@ -131,11 +133,11 @@ class ItemConnectionSink: def __init__(self, item: Item, distance: float = 10) -> None: self.item = item self.distance = distance - self.port: Optional[Port] = None + self.port: Port | None = None def glue( - self, pos: SupportsFloatPos, secondary_pos: Optional[SupportsFloatPos] = None - ) -> Optional[Pos]: + self, pos: SupportsFloatPos, secondary_pos: SupportsFloatPos | None = None + ) -> Pos | None: max_dist = self.distance glue_pos = None for p in self.item.ports(): @@ -161,8 +163,8 @@ def constraint(self, item: Item, handle: Handle) -> Constraint: @ConnectionSink.register(Element) class ElementConnectionSink(ItemConnectionSink): def glue( - self, pos: SupportsFloatPos, secondary_pos: Optional[SupportsFloatPos] = None - ) -> Optional[Pos]: + self, pos: SupportsFloatPos, secondary_pos: SupportsFloatPos | None = None + ) -> Pos | None: if glue_pos := super().glue(pos, secondary_pos): return glue_pos diff --git a/gaphas/constraint.py b/gaphas/constraint.py index f8348d5a..d3256125 100644 --- a/gaphas/constraint.py +++ b/gaphas/constraint.py @@ -24,9 +24,10 @@ class and implement `Constraint.solve_for(Variable)` method to update a variable with appropriate value. """ +from __future__ import annotations + import logging import math -from typing import Optional, Tuple from gaphas.position import Position from gaphas.solver import BaseConstraint, Constraint @@ -35,13 +36,14 @@ class and implement `Constraint.solve_for(Variable)` method to update def constraint( - horizontal: Optional[Tuple[Position, Position]] = None, - vertical: Optional[Tuple[Position, Position]] = None, - left_of: Optional[Tuple[Position, Position]] = None, - above: Optional[Tuple[Position, Position]] = None, - line: Optional[Tuple[Position, Tuple[Position, Position]]] = None, + *, + horizontal: tuple[Position, Position] | None = None, + vertical: tuple[Position, Position] | None = None, + left_of: tuple[Position, Position] | None = None, + above: tuple[Position, Position] | None = None, + line: tuple[Position, tuple[Position, Position]] | None = None, delta: float = 0.0, - align: Optional[float] = None, + align: float | None = None, ) -> Constraint: """Utility (factory) method to create item's internal constraint between two positions or between a position and a line. @@ -67,7 +69,7 @@ def constraint( line=(p, l) Keep position ``p`` on line ``l``. """ - cc: Optional[Constraint] + cc: Constraint | None if horizontal: p1, p2 = horizontal cc = EqualsConstraint(p1[1], p2[1], delta) diff --git a/gaphas/cursor.py b/gaphas/cursor.py index 68a6d95c..14e10d58 100644 --- a/gaphas/cursor.py +++ b/gaphas/cursor.py @@ -1,5 +1,7 @@ +from __future__ import annotations + from functools import singledispatch -from typing import Optional +from typing import Union from gaphas.connector import Handle from gaphas.item import Element, Item, Line @@ -9,7 +11,7 @@ @singledispatch -def cursor(item: Optional[Item], handle: Optional[Handle], pos: Pos) -> str: +def cursor(item: Union[Item, None], handle: Union[Handle, None], pos: Pos) -> str: return DEFAULT_CURSOR @@ -17,7 +19,7 @@ def cursor(item: Optional[Item], handle: Optional[Handle], pos: Pos) -> str: @cursor.register -def element_hover(item: Element, handle: Optional[Handle], pos: Pos) -> str: +def element_hover(item: Element, handle: Union[Handle, None], pos: Pos) -> str: if handle: index = item.handles().index(handle) return ELEMENT_CURSORS[index] if index < 4 else DEFAULT_CURSOR @@ -28,5 +30,5 @@ def element_hover(item: Element, handle: Optional[Handle], pos: Pos) -> str: @cursor.register -def line_hover(item: Line, handle: Optional[Handle], pos: Pos) -> str: +def line_hover(item: Line, handle: Union[Handle, None], pos: Pos) -> str: return LINE_CURSOR if handle else DEFAULT_CURSOR diff --git a/gaphas/geometry.py b/gaphas/geometry.py index f81479b1..72a4a3a8 100644 --- a/gaphas/geometry.py +++ b/gaphas/geometry.py @@ -8,10 +8,10 @@ from __future__ import annotations from math import sqrt -from typing import Iterator, Tuple +from collections.abc import Iterator -Point = Tuple[float, float] # x, y -Rect = Tuple[float, float, float, float] # x, y, width, height +Point = tuple[float, float] # x, y +Rect = tuple[float, float, float, float] # x, y, width, height class Rectangle: diff --git a/gaphas/matrix.py b/gaphas/matrix.py index c477e639..734c7d99 100644 --- a/gaphas/matrix.py +++ b/gaphas/matrix.py @@ -9,11 +9,11 @@ from __future__ import annotations -from typing import Callable, SupportsFloat, Tuple +from typing import Callable, SupportsFloat import cairo -MatrixTuple = Tuple[float, float, float, float, float, float] +Matrixtuple = tuple[float, float, float, float, float, float] class Matrix: @@ -34,31 +34,31 @@ def __init__( matrix: cairo.Matrix | None = None, ) -> None: self._matrix = matrix or cairo.Matrix(xx, yx, xy, yy, x0, y0) - self._handlers: set[Callable[[Matrix, MatrixTuple], None]] = set() + self._handlers: set[Callable[[Matrix, Matrixtuple], None]] = set() def add_handler( self, - handler: Callable[[Matrix, MatrixTuple], None], + handler: Callable[[Matrix, Matrixtuple], None], ) -> None: self._handlers.add(handler) def remove_handler( self, - handler: Callable[[Matrix, MatrixTuple], None], + handler: Callable[[Matrix, Matrixtuple], None], ) -> None: self._handlers.discard(handler) - def notify(self, old: MatrixTuple) -> None: + def notify(self, old: Matrixtuple) -> None: for handler in self._handlers: handler(self, old) def invert(self) -> None: - old: MatrixTuple = self.tuple() + old: Matrixtuple = self.tuple() self._matrix.invert() self.notify(old) def rotate(self, radians: float) -> None: - old: MatrixTuple = self.tuple() + old: Matrixtuple = self.tuple() self._matrix.rotate(radians) self.notify(old) @@ -68,7 +68,7 @@ def scale(self, sx: float, sy: float) -> None: self.notify(old) def translate(self, tx: float, ty: float) -> None: - old: MatrixTuple = self.tuple() + old: Matrixtuple = self.tuple() self._matrix.translate(tx, ty) self.notify(old) @@ -116,7 +116,7 @@ def inverse(self) -> Matrix: m.invert() return m - def tuple(self) -> MatrixTuple: + def tuple(self) -> Matrixtuple: return tuple(self) # type: ignore[arg-type, return-value] def to_cairo(self) -> cairo.Matrix: @@ -135,7 +135,7 @@ def __mul__(self, other: Matrix) -> Matrix: return Matrix(matrix=self._matrix * other._matrix) def __imul__(self, other: Matrix) -> Matrix: - old: MatrixTuple = self.tuple() + old: Matrixtuple = self.tuple() self._matrix *= other._matrix self.notify(old) return self diff --git a/gaphas/painter/chain.py b/gaphas/painter/chain.py index 1cbec251..7452e990 100644 --- a/gaphas/painter/chain.py +++ b/gaphas/painter/chain.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Collection +from collections.abc import Collection from cairo import Context as CairoContext diff --git a/gaphas/painter/freehand.py b/gaphas/painter/freehand.py index 9d4bfe29..f35ffd6a 100644 --- a/gaphas/painter/freehand.py +++ b/gaphas/painter/freehand.py @@ -11,7 +11,7 @@ """ from math import sqrt from random import Random -from typing import Collection +from collections.abc import Collection from cairo import Context as CairoContext diff --git a/gaphas/painter/itempainter.py b/gaphas/painter/itempainter.py index d2fde979..acdc3ad4 100644 --- a/gaphas/painter/itempainter.py +++ b/gaphas/painter/itempainter.py @@ -1,4 +1,6 @@ -from typing import Collection, Optional +from __future__ import annotations + +from collections.abc import Collection from cairo import LINE_JOIN_ROUND from cairo import Context as CairoContext @@ -8,7 +10,7 @@ class ItemPainter: - def __init__(self, selection: Optional[Selection] = None) -> None: + def __init__(self, selection: Selection | None = None) -> None: self.selection = selection or Selection() def paint_item(self, item: Item, cairo: CairoContext) -> None: diff --git a/gaphas/quadtree.py b/gaphas/quadtree.py index 8774e5c0..a06ece15 100644 --- a/gaphas/quadtree.py +++ b/gaphas/quadtree.py @@ -20,11 +20,11 @@ from __future__ import annotations import operator -from typing import Callable, Generic, Iterable, Tuple, TypeVar +from typing import Callable, Generic, Iterable, TypeVar -from gaphas.geometry import rectangle_contains, rectangle_intersects +from gaphas.geometry import rectangle_contains, rectangle_intersects, Rect -Bounds = Tuple[float, float, float, float] # x, y, width, height +Bounds = Rect T = TypeVar("T") D = TypeVar("D") diff --git a/gaphas/segment.py b/gaphas/segment.py index 7ee02a3d..0d6fea9a 100644 --- a/gaphas/segment.py +++ b/gaphas/segment.py @@ -1,7 +1,8 @@ """Allow for easily adding segments to lines.""" +from __future__ import annotations from functools import singledispatch -from typing import Optional +from typing import Union from gaphas.connector import Handle, LinePort from gaphas.cursor import DEFAULT_CURSOR, LINE_CURSOR, cursor, line_hover @@ -211,7 +212,7 @@ def paint(self, _items, cairo): @cursor.register -def line_segment_hover(item: Line, handle: Optional[Handle], pos: Pos) -> str: +def line_segment_hover(item: Line, handle: Union[Handle, None], pos: Pos) -> str: if not handle: handles = item.handles() if any( diff --git a/gaphas/selection.py b/gaphas/selection.py index 8d744ad7..7fa89617 100644 --- a/gaphas/selection.py +++ b/gaphas/selection.py @@ -1,4 +1,6 @@ -from typing import Callable, Collection, Optional, Set +from __future__ import annotations + +from collections.abc import Callable, Collection from gaphas.item import Item @@ -6,20 +8,20 @@ class Selection: def __init__(self): super().__init__() - self._selected_items: Set[Item] = set() - self._focused_item: Optional[Item] = None - self._hovered_item: Optional[Item] = None - self._handlers: Set[Callable[[Optional[Item]], None]] = set() + self._selected_items: set[Item] = set() + self._focused_item: Item | None = None + self._hovered_item: Item | None = None + self._handlers: set[Callable[[Item | None], None]] = set() - def add_handler(self, handler: Callable[[Optional[Item]], None]) -> None: + def add_handler(self, handler: Callable[[Item | None], None]) -> None: """Add a callback handler, triggered when a constraint is resolved.""" self._handlers.add(handler) - def remove_handler(self, handler: Callable[[Optional[Item]], None]) -> None: + def remove_handler(self, handler: Callable[[Item | None], None]) -> None: """Remove a previously assigned handler.""" self._handlers.discard(handler) - def notify(self, item: Optional[Item]) -> None: + def notify(self, item: Item | None) -> None: for handler in self._handlers: handler(item) @@ -57,11 +59,11 @@ def unselect_all(self) -> None: self.focused_item = None @property - def focused_item(self) -> Optional[Item]: + def focused_item(self) -> Item | None: return self._focused_item @focused_item.setter - def focused_item(self, item: Optional[Item]) -> None: + def focused_item(self, item: Item | None) -> None: if item: self.select_items(item) @@ -70,11 +72,11 @@ def focused_item(self, item: Optional[Item]) -> None: self.notify(item) @property - def hovered_item(self) -> Optional[Item]: + def hovered_item(self) -> Item | None: return self._hovered_item @hovered_item.setter - def hovered_item(self, item: Optional[Item]) -> None: + def hovered_item(self, item: Item | None) -> None: if item is not self._hovered_item: self._hovered_item = item self.notify(item) diff --git a/gaphas/solver/solver.py b/gaphas/solver/solver.py index 414080cb..5872eabb 100644 --- a/gaphas/solver/solver.py +++ b/gaphas/solver/solver.py @@ -32,8 +32,10 @@ (`constraint.Constraint.solve_for()` method) changing appropriate variables to make the constraint valid again. """ +from __future__ import annotations + import functools -from typing import Callable, Collection, List, Optional, Set +from collections.abc import Callable, Collection from gaphas.solver.constraint import Constraint, ContainsConstraints @@ -46,11 +48,11 @@ class Solver: def __init__(self, resolve_limit: int = 16) -> None: # a dict of constraint -> name/variable mappings - self._constraints: Set[Constraint] = set() - self._marked_cons: List[Constraint] = [] + self._constraints: set[Constraint] = set() + self._marked_cons: list[Constraint] = [] self._solving = False self._resolve_limit = resolve_limit - self._handlers: Set[Callable[[Constraint], None]] = set() + self._handlers: set[Callable[[Constraint], None]] = set() def add_handler(self, handler: Callable[[Constraint], None]) -> None: """Add a callback handler, triggered when a constraint is resolved.""" @@ -147,7 +149,7 @@ def solve(self) -> None: # sourcery skip: while-to-for def find_containing_constraint( constraint: Constraint, constraints: Collection[Constraint] -) -> Optional[Constraint]: +) -> Constraint | None: if constraint in constraints: return constraint diff --git a/gaphas/table.py b/gaphas/table.py index 36e44f14..3d971d73 100644 --- a/gaphas/table.py +++ b/gaphas/table.py @@ -1,29 +1,26 @@ """Table is a storage class that can be used to store information, like one would in a database table, with indexes on the desired "columns.".""" - +from __future__ import annotations from contextlib import suppress from functools import reduce from typing import ( - Dict, Generic, Iterator, Protocol, Sequence, - Set, - Tuple, Type, TypeVar, runtime_checkable, ) -T = TypeVar("T", bound=Tuple, covariant=True) +T = TypeVar("T", bound=tuple, covariant=True) @runtime_checkable class NamedTupleish(Protocol): - _fields: Tuple[str, ...] + _fields: tuple[str, ...] - def _make(self, *args: object) -> Tuple[object, ...]: + def _make(self, *args: object) -> tuple[object, ...]: ... @@ -48,7 +45,7 @@ def __init__(self, columns: Type[T], indexes: Sequence[int]) -> None: self._fields: Sequence[str] = fields # create data structure, which acts as cache - self._index: Dict[str, Dict[object, Set[object]]] = {n: {} for n in fields} + self._index: dict[str, dict[object, set[object]]] = {n: {} for n in fields} @property def columns(self) -> Type[T]: diff --git a/gaphas/tool/itemtool.py b/gaphas/tool/itemtool.py index 849635b8..5c02876c 100644 --- a/gaphas/tool/itemtool.py +++ b/gaphas/tool/itemtool.py @@ -1,5 +1,6 @@ +from __future__ import annotations + import logging -from typing import Optional, Tuple, Union from gi.repository import Gdk, Gtk @@ -86,7 +87,7 @@ def on_drag_begin(gesture, start_x, start_y, drag_state): def find_item_and_handle_at_point( view: GtkView, pos: Pos -) -> Tuple[Optional[Item], Optional[Handle]]: +) -> tuple[Item | None, Handle | None]: item, handle = handle_at_point(view, pos) return item or next(item_at_point(view, pos), None), handle # type: ignore[call-overload] @@ -135,7 +136,7 @@ def order_handles(handles): def handle_at_point( view: GtkView, pos: Pos, distance: int = 6 -) -> Union[Tuple[Item, Handle], Tuple[None, None]]: +) -> tuple[Item, Handle] | tuple[None, None]: """Look for a handle at ``pos`` and return the tuple (item, handle).""" def find(item): diff --git a/gaphas/tool/placement.py b/gaphas/tool/placement.py index 1d1a3213..cfd2e568 100644 --- a/gaphas/tool/placement.py +++ b/gaphas/tool/placement.py @@ -1,4 +1,6 @@ -from typing import Callable, Optional +from __future__ import annotations + +from collections.abc import Callable from gi.repository import Gtk @@ -23,7 +25,7 @@ class PlacementState: def __init__(self, factory: FactoryType, handle_index: int): self.factory = factory self.handle_index = handle_index - self.moving: Optional[MoveType] = None + self.moving: MoveType | None = None def on_drag_begin(gesture, start_x, start_y, placement_state): diff --git a/gaphas/tool/rubberband.py b/gaphas/tool/rubberband.py index 04b92831..0782c1c9 100644 --- a/gaphas/tool/rubberband.py +++ b/gaphas/tool/rubberband.py @@ -1,4 +1,4 @@ -from typing import Collection +from collections.abc import Collection from cairo import Context as CairoContext from gi.repository import Gtk diff --git a/gaphas/tree.py b/gaphas/tree.py index 0b7dedcc..d912c106 100644 --- a/gaphas/tree.py +++ b/gaphas/tree.py @@ -1,6 +1,8 @@ """Simple class containing the tree structure for the canvas items.""" +from __future__ import annotations + from contextlib import suppress -from typing import Dict, Generic, Iterable, List, Optional, Sequence, TypeVar, Union +from typing import Generic, Iterable, Sequence, TypeVar T = TypeVar("T") @@ -16,19 +18,19 @@ class Tree(Generic[T]): def __init__(self) -> None: # List of nodes in the tree, sorted in the order they ought to be # rendered - self._nodes: List[T] = [] + self._nodes: list[T] = [] # Per entry a list of children is maintained. - self._children: Dict[Union[T, None], List[T]] = {None: []} + self._children: dict[T | None, list[T]] = {None: []} # For easy and fast lookups, also maintain a child -> parent mapping - self._parents: Dict[T, T] = {} + self._parents: dict[T, T] = {} @property def nodes(self) -> Sequence[T]: return list(self._nodes) - def get_parent(self, node: T) -> Optional[T]: + def get_parent(self, node: T) -> T | None: """Return the parent item of ``node``. >>> tree = Tree() @@ -39,7 +41,7 @@ def get_parent(self, node: T) -> Optional[T]: """ return self._parents.get(node) - def get_children(self, node: Optional[T]) -> Iterable[T]: + def get_children(self, node: T | None) -> Iterable[T]: """Return all child objects of ``node``. >>> tree = Tree() @@ -53,7 +55,7 @@ def get_children(self, node: Optional[T]) -> Iterable[T]: """ return self._children[node] - def get_siblings(self, node: T) -> List[T]: + def get_siblings(self, node: T) -> list[T]: """Get all siblings of ``node``, including ``node``. >>> tree = Tree() @@ -150,7 +152,7 @@ def order(self, items: Iterable[T]) -> Iterable[T]: return (n for n in self._nodes if n in items_set) def _add_to_nodes( - self, node: T, parent: Optional[T], index: Optional[int] = None + self, node: T, parent: T | None, index: int | None = None ) -> None: """Helper method to place nodes on the right location in the nodes list Called only from add() and move()""" @@ -175,9 +177,7 @@ def _add_to_nodes( else: nodes.insert(nodes.index(atnode), node) - def _add( - self, node: T, parent: Optional[T] = None, index: Optional[int] = None - ) -> None: + def _add(self, node: T, parent: T | None = None, index: int | None = None) -> None: """Helper method for both add() and move().""" assert node not in self._nodes @@ -195,9 +195,7 @@ def _add( if parent: self._parents[node] = parent - def add( - self, node: T, parent: Optional[T] = None, index: Optional[int] = None - ) -> None: + def add(self, node: T, parent: T | None = None, index: int | None = None) -> None: """Add node to the tree. parent is the parent node, which may be None if the item should be added to the root item. @@ -225,7 +223,7 @@ def remove(self, node: T) -> None: self.remove(c) self._remove(node) - def _reparent_nodes(self, node: T, parent: Optional[T]) -> None: + def _reparent_nodes(self, node: T, parent: T | None) -> None: """Helper for move(). The _children and _parent trees can be left intact as far as @@ -237,7 +235,7 @@ def _reparent_nodes(self, node: T, parent: Optional[T]) -> None: for c in self._children[node]: self._reparent_nodes(c, node) - def move(self, node: T, parent: Optional[T], index: Optional[int] = None) -> None: + def move(self, node: T, parent: T | None, index: int | None = None) -> None: """Set new parent for a ``node``. ``Parent`` can be ``None``, indicating it's added to the top. diff --git a/gaphas/types.py b/gaphas/types.py index fea4a984..336e378e 100644 --- a/gaphas/types.py +++ b/gaphas/types.py @@ -1,11 +1,11 @@ from __future__ import annotations -from typing import Protocol, SupportsFloat, Tuple, TypeVar +from typing import Protocol, SupportsFloat, TypeVar # A primitive position, tuple ``(x, y)`` # Pos = Tuple[Union[float, SupportsFloat], Union[float, SupportsFloat]] -Pos = Tuple[float, float] -SupportsFloatPos = Tuple[SupportsFloat, SupportsFloat] +Pos = tuple[float, float] +SupportsFloatPos = tuple[SupportsFloat, SupportsFloat] GetT = TypeVar("GetT", covariant=True) SetT = TypeVar("SetT", contravariant=True) diff --git a/gaphas/view/gtkview.py b/gaphas/view/gtkview.py index 35835558..504ff309 100644 --- a/gaphas/view/gtkview.py +++ b/gaphas/view/gtkview.py @@ -1,7 +1,7 @@ """This module contains everything to display a model on a screen.""" from __future__ import annotations -from typing import Collection, Iterable +from collections.abc import Collection, Iterable import cairo from gi.repository import Graphene, GLib, GObject, Gtk diff --git a/gaphas/view/scrolling.py b/gaphas/view/scrolling.py index 8e320542..aba84084 100644 --- a/gaphas/view/scrolling.py +++ b/gaphas/view/scrolling.py @@ -1,4 +1,6 @@ -from typing import Callable, Optional +from __future__ import annotations + +from typing import Callable from gi.repository import Gtk @@ -11,10 +13,10 @@ class Scrolling: def __init__(self, scrolling_updated: Callable[[Matrix], None]) -> None: self._scrolling_updated = scrolling_updated - self.hadjustment: Optional[Gtk.Adjustment] = None - self.vadjustment: Optional[Gtk.Adjustment] = None - self.hscroll_policy: Optional[Gtk.ScrollablePolicy] = None - self.vscroll_policy: Optional[Gtk.ScrollablePolicy] = None + self.hadjustment: Gtk.Adjustment | None = None + self.vadjustment: Gtk.Adjustment | None = None + self.hscroll_policy: Gtk.ScrollablePolicy | None = None + self.vscroll_policy: Gtk.ScrollablePolicy | None = None self._hadjustment_handler_id = 0 self._vadjustment_handler_id = 0 self._last_hvalue = 0 @@ -58,7 +60,7 @@ def set_property(self, prop, value): else: raise AttributeError(f"Unknown property {prop.name}") - def update_adjustments(self, width, height, bounds): + def update_adjustments(self, width: int, height: int, bounds: Rectangle) -> None: """Update scroll bar values (adjustments in GTK), and reset the scroll value to 0. diff --git a/tests/test_decorators.py b/tests/test_decorators.py index f6fa6d0a..62f1d8ee 100644 --- a/tests/test_decorators.py +++ b/tests/test_decorators.py @@ -1,6 +1,7 @@ +from __future__ import annotations + import functools import time -from typing import List import pytest from gi.repository import GLib @@ -62,7 +63,7 @@ def test_in_main_context(): def test_function_is_called_when_not_in_main_loop(): - called: List[str] = [] + called: list[str] = [] async_function(called, "called") @@ -70,7 +71,7 @@ def test_function_is_called_when_not_in_main_loop(): def test_generator_is_called_when_not_in_main_loop(): - called: List[str] = [] + called: list[str] = [] for _ in generator_function(called, ["one", "two"]): pass @@ -80,7 +81,7 @@ def test_generator_is_called_when_not_in_main_loop(): @in_main_context def test_function_is_not_called_directly_in_main_loop(): - called: List[str] = [] + called: list[str] = [] async_function(called, "called") @@ -88,7 +89,7 @@ def test_function_is_not_called_directly_in_main_loop(): def test_function_is_called_from_main_loop(): - called: List[str] = [] + called: list[str] = [] @in_main_context def fn(): @@ -101,7 +102,7 @@ def fn(): def test_single_function_is_called_once(): - called: List[str] = [] + called: list[str] = [] @in_main_context def fn(): @@ -134,7 +135,7 @@ def fn(): def test_timeout_function(): - called: List[str] = [] + called: list[str] = [] @in_main_context def fn(): @@ -151,7 +152,7 @@ def fn(): def test_run_generator_to_completion(): - called: List[str] = [] + called: list[str] = [] @in_main_context def fn(): @@ -164,7 +165,7 @@ def fn(): def test_run_first_generator_to_completion(): - called: List[str] = [] + called: list[str] = [] @in_main_context def fn():