Skip to content

Commit

Permalink
build: drop 3.8 and add 3.13 (#224)
Browse files Browse the repository at this point in the history
  • Loading branch information
tlambert03 authored Nov 15, 2024
1 parent eda2b2f commit d69a665
Show file tree
Hide file tree
Showing 22 changed files with 60 additions and 72 deletions.
17 changes: 2 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,15 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.10", "3.12"]
python-version: ["3.9", "3.10", "3.12", "3.13"]
os: [ubuntu-latest, macos-latest, windows-latest]
pydantic: [""]
exclude:
- python-version: "3.8"
os: "macos-latest"
include:
- python-version: "3.8"
os: "macos-13"
- python-version: "3.9"
os: "macos-13"
- python-version: "3.11"
os: "ubuntu-latest"
- python-version: "3.12"
os: "ubuntu-latest"
pydantic: "'pydantic<2'"
- python-version: "3.8"
os: "ubuntu-latest"
pydantic: "'pydantic<2'"

test-qt:
uses: pyapp-kit/workflows/.github/workflows/test-pyrepo.yml@v2
Expand All @@ -58,9 +48,6 @@ jobs:
fail-fast: false
matrix:
include:
- python-version: "3.8"
os: "ubuntu-latest"
qt: "PyQt5==5.12"
- python-version: "3.10"
os: "ubuntu-latest"
qt: "PyQt5~=5.15.0"
Expand All @@ -82,7 +69,7 @@ jobs:
- python-version: "3.11"
os: "ubuntu-latest"
qt: "PySide6~=6.6.0"
- python-version: "3.11"
- python-version: "3.13"
os: "ubuntu-latest"
qt: pyqt6
- python-version: "3.10"
Expand Down
3 changes: 1 addition & 2 deletions demo/model_app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from pathlib import Path
from typing import List

from qtpy.QtCore import QFile, QFileInfo, QSaveFile, Qt, QTextStream
from qtpy.QtWidgets import QApplication, QFileDialog, QMessageBox, QTextEdit
Expand Down Expand Up @@ -160,7 +159,7 @@ class CommandId:

ABOUT_ICON_PATH = Path(__file__).parent / "images" / "about.svg"

ACTIONS: List[types.Action] = [
ACTIONS: list[types.Action] = [
types.Action(
id="new_file",
icon="fa6-solid:file-circle-plus",
Expand Down
4 changes: 1 addition & 3 deletions demo/multi_file/actions.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from typing import List

from app_model.types import Action, KeyBindingRule, KeyCode, KeyMod, MenuRule

from . import functions
from .constants import CommandId, MenuId

ACTIONS: List[Action] = [
ACTIONS: list[Action] = [
Action(
id=CommandId.OPEN,
title="Open",
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ build-backend = "hatchling.build"
name = "app-model"
description = "Generic application schema implemented in python"
readme = "README.md"
requires-python = ">=3.8"
requires-python = ">=3.9"
license = { text = "BSD 3-Clause License" }
authors = [{ email = "[email protected]" }, { name = "Talley Lambert" }]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Desktop Environment",
"Topic :: Software Development",
"Topic :: Software Development :: User Interfaces",
Expand Down Expand Up @@ -81,7 +81,7 @@ src_paths = ["src/app_model", "tests"]
[tool.ruff]
line-length = 88
src = ["src", "tests"]
target-version = "py38"
target-version = "py39"

[tool.ruff.lint]
pydocstyle = { convention = "numpy" }
Expand Down
19 changes: 7 additions & 12 deletions src/app_model/_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,12 @@
import contextlib
import os
import sys
from collections.abc import Iterable, MutableMapping
from typing import (
TYPE_CHECKING,
ClassVar,
Dict,
Iterable,
List,
Literal,
MutableMapping,
Optional,
Tuple,
Type,
overload,
)

Expand Down Expand Up @@ -85,17 +80,17 @@ class Application:
"""

destroyed = Signal(str)
_instances: ClassVar[Dict[str, Application]] = {}
_instances: ClassVar[dict[str, Application]] = {}

def __init__(
self,
name: str,
*,
raise_synchronous_exceptions: bool = False,
commands_reg_class: Type[CommandsRegistry] = CommandsRegistry,
menus_reg_class: Type[MenusRegistry] = MenusRegistry,
keybindings_reg_class: Type[KeyBindingsRegistry] = KeyBindingsRegistry,
injection_store_class: Type[ino.Store] = ino.Store,
commands_reg_class: type[CommandsRegistry] = CommandsRegistry,
menus_reg_class: type[MenusRegistry] = MenusRegistry,
keybindings_reg_class: type[KeyBindingsRegistry] = KeyBindingsRegistry,
injection_store_class: type[ino.Store] = ino.Store,
context: Context | MutableMapping | None = None,
) -> None:
self._name = name
Expand Down Expand Up @@ -131,7 +126,7 @@ def __init__(

self.injection_store.on_unannotated_required_args = "ignore"

self._disposers: List[Tuple[str, DisposeCallable]] = []
self._disposers: list[tuple[str, DisposeCallable]] = []

@property
def raise_synchronous_exceptions(self) -> bool:
Expand Down
4 changes: 3 additions & 1 deletion src/app_model/backends/qt/_qaction.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

import contextlib
from typing import TYPE_CHECKING, ClassVar, Mapping
from typing import TYPE_CHECKING, ClassVar
from weakref import WeakValueDictionary

from app_model import Application
Expand All @@ -12,6 +12,8 @@
from ._util import to_qicon

if TYPE_CHECKING:
from collections.abc import Mapping

from PyQt6.QtGui import QAction
from qtpy.QtCore import QObject
from typing_extensions import Self
Expand Down
4 changes: 3 additions & 1 deletion src/app_model/backends/qt/_qkeymap.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import operator
from functools import reduce
from typing import TYPE_CHECKING, Mapping, MutableMapping
from typing import TYPE_CHECKING

from qtpy import API, QT_VERSION
from qtpy.QtCore import QCoreApplication, Qt
Expand All @@ -19,6 +19,8 @@
from app_model.types._constants import OperatingSystem

if TYPE_CHECKING:
from collections.abc import Mapping, MutableMapping

from qtpy.QtCore import QKeyCombination

try:
Expand Down
5 changes: 4 additions & 1 deletion src/app_model/backends/qt/_qmainwindow.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import Collection, Mapping, Sequence
from typing import TYPE_CHECKING

from qtpy.QtCore import Qt
from qtpy.QtWidgets import QMainWindow, QWidget
Expand All @@ -9,6 +9,9 @@

from ._qmenu import QModelMenuBar, QModelToolBar

if TYPE_CHECKING:
from collections.abc import Collection, Mapping, Sequence


class QModelMainWindow(QMainWindow):
"""QMainWindow with app-model support."""
Expand Down
3 changes: 2 additions & 1 deletion src/app_model/backends/qt/_qmenu.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from __future__ import annotations

import contextlib
from typing import TYPE_CHECKING, Collection, Iterable, Mapping, Sequence, cast
from collections.abc import Collection, Iterable, Mapping, Sequence
from typing import TYPE_CHECKING, cast

from qtpy.QtWidgets import QMenu, QMenuBar, QToolBar

Expand Down
4 changes: 3 additions & 1 deletion src/app_model/expressions/_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import os
import sys
from collections import ChainMap
from contextlib import contextmanager
from typing import TYPE_CHECKING, Any, Callable, ChainMap, Iterator, MutableMapping
from typing import TYPE_CHECKING, Any, Callable
from weakref import finalize

from psygnal import Signal

if TYPE_CHECKING:
from collections.abc import Iterator, MutableMapping
from types import FrameType
from typing import TypedDict

Expand Down
2 changes: 1 addition & 1 deletion src/app_model/expressions/_context_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
ClassVar,
Generic,
Literal,
MutableMapping,
NamedTuple,
TypeVar,
overload,
Expand All @@ -19,6 +18,7 @@

if TYPE_CHECKING:
import builtins
from collections.abc import MutableMapping

T = TypeVar("T")
A = TypeVar("A")
Expand Down
12 changes: 3 additions & 9 deletions src/app_model/expressions/_expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@
Any,
Callable,
Generic,
Iterator,
Mapping,
Sequence,
SupportsIndex,
Type,
TypeVar,
Union,
cast,
Expand All @@ -29,6 +25,7 @@
V = TypeVar("V", bound=ConstType)

if TYPE_CHECKING:
from collections.abc import Iterator, Mapping, Sequence
from types import CodeType

from pydantic.annotated_handlers import GetCoreSchemaHandler
Expand Down Expand Up @@ -507,10 +504,7 @@ class Set(Expr, ast.Set):
`elts` is a list of expressions.
"""

def __init__(
self, elts: Sequence[Expr], ctx: ast.expr_context = LOAD, **kwargs: Any
) -> None:
kwargs["ctx"] = ctx
def __init__(self, elts: Sequence[Expr], **kwargs: Any) -> None:
super().__init__(elts=[Expr._cast(e) for e in elts], **kwargs)


Expand Down Expand Up @@ -643,7 +637,7 @@ def visit_IfExp(self, node: ast.IfExp) -> Any:
self.write(node.body, " if ", node.test, " else ", node.orelse)


OpType = Union[Type[ast.operator], Type[ast.cmpop], Type[ast.boolop], Type[ast.unaryop]]
OpType = Union[type[ast.operator], type[ast.cmpop], type[ast.boolop], type[ast.unaryop]]
_OPS: dict[OpType, str] = {
# ast.boolop
ast.Or: "or",
Expand Down
4 changes: 3 additions & 1 deletion src/app_model/registries/_commands_reg.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from __future__ import annotations

from concurrent.futures import Future, ThreadPoolExecutor
from typing import TYPE_CHECKING, Any, Callable, Generic, Iterator, TypeVar, cast
from typing import TYPE_CHECKING, Any, Callable, Generic, TypeVar, cast

from in_n_out import Store
from psygnal import Signal

# maintain runtime compatibility with older typing_extensions
if TYPE_CHECKING:
from collections.abc import Iterator

from typing_extensions import ParamSpec

from app_model.types import Action, DisposeCallable
Expand Down
3 changes: 2 additions & 1 deletion src/app_model/registries/_keybindings_reg.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from app_model.types import KeyBinding

if TYPE_CHECKING:
from typing import Iterator, TypeVar
from collections.abc import Iterator
from typing import TypeVar

from app_model import expressions
from app_model.types import Action, DisposeCallable, KeyBindingRule
Expand Down
4 changes: 3 additions & 1 deletion src/app_model/registries/_menus_reg.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from __future__ import annotations

from typing import TYPE_CHECKING, Any, Callable, Final, Iterable, Iterator
from typing import TYPE_CHECKING, Any, Callable, Final

from psygnal import Signal

from app_model.types import MenuItem

if TYPE_CHECKING:
from collections.abc import Iterable, Iterator

from app_model.types import Action, DisposeCallable, MenuOrSubmenu

MenuId = str
Expand Down
6 changes: 3 additions & 3 deletions src/app_model/types/_action.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import TYPE_CHECKING, Callable, Generic, List, Optional, TypeVar, Union
from typing import TYPE_CHECKING, Callable, Generic, Optional, TypeVar, Union

from pydantic_compat import Field, field_validator

Expand Down Expand Up @@ -39,13 +39,13 @@ class Action(CommandRule, Generic[P, R]):
"`{obj.__module__}:{obj.__qualname__}` "
"(e.g. `my_package.a_module:some_function`)",
)
menus: Optional[List[MenuRule]] = Field(
menus: Optional[list[MenuRule]] = Field(
None,
description="(Optional) Menus to which this action should be added. Note that "
"menu items in the sequence may be supplied as a plain string, which will "
"be converted to a `MenuRule` with the string as the `id` field.",
)
keybindings: Optional[List[KeyBindingRule]] = Field(
keybindings: Optional[list[KeyBindingRule]] = Field(
None,
description="(Optional) Default keybinding(s) that will trigger this command.",
)
Expand Down
3 changes: 2 additions & 1 deletion src/app_model/types/_icon.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Any, Callable, Generator, Optional, TypedDict, Union
from collections.abc import Generator
from typing import Any, Callable, Optional, TypedDict, Union

from pydantic_compat import Field, model_validator

Expand Down
4 changes: 2 additions & 2 deletions src/app_model/types/_keybinding_rule.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Callable, Optional, Type, TypedDict, TypeVar, Union
from typing import Any, Callable, Optional, TypedDict, TypeVar, Union

from pydantic_compat import PYDANTIC2, Field, model_validator

Expand Down Expand Up @@ -69,7 +69,7 @@ def _bind_to_current_platform(self) -> Optional[KeyEncoding]:
@model_validator(mode="wrap")
@classmethod
def _model_val(
cls: Type[M], v: Any, handler: Callable[[Any], M]
cls: type[M], v: Any, handler: Callable[[Any], M]
) -> "KeyBindingRule":
if isinstance(v, StandardKeyBinding):
return v.to_keybinding_rule()
Expand Down
Loading

0 comments on commit d69a665

Please sign in to comment.