Skip to content

Commit 9613ce6

Browse files
authored
n Update to Python 3.13 for 2026.1 #18689
Part of #18591 Summary of the issue: We want to update to Python 3.13 from 3.11 Description of user facing changes: brltty will break Description of developer facing changes: Update python to 3.13.6 remove typing_extensions Description of development approach: Updated all references of python 3.11 to 3.13 Updated usages of TypeAlias to type: https://docs.python.org/3.13/library/typing.html#type-aliases Updated usages of ParamSpec to parameter lists: https://docs.python.org/3.13/library/typing.html#typing.ParamSpec Remove deprecated SupportsLessThan: Add SupportsLessThan to typing and typing_extensions python/typing_extensions#9 (comment)
1 parent f8f4a31 commit 9613ce6

22 files changed

Lines changed: 75 additions & 178 deletions

‎.github/workflows/add-new-language.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
- name: Set up python
3333
uses: actions/setup-python@v5
3434
with:
35-
python-version: '3.11.9'
35+
python-version: '3.13'
3636
architecture: 'x86'
3737

3838
- name: setup uv

‎.github/workflows/fetch-crowdin-translations.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
- name: Set up python
3333
uses: actions/setup-python@v5
3434
with:
35-
python-version: '3.11.9'
35+
python-version: '3.13'
3636
architecture: 'x86'
3737

3838
- name: setup uv

‎.github/workflows/regenerate_english_userDocs_translation_source.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
- name: Set up python
2121
uses: actions/setup-python@v5
2222
with:
23-
python-version: '3.11.9'
23+
python-version: '3.13'
2424
architecture: 'x86'
2525

2626
- name: Install dependencies

‎.github/workflows/testAndPublish.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ env:
3737
SCONS_CACHE_MSVC_CONFIG: ".scons_msvc_cache.json"
3838
defaultArch: x86
3939
supportedArchitectures: '["x86"]'
40-
defaultPythonVersion: '3.11.9'
41-
supportedPythonVersions: '["3.11.9", "3.13.6"]'
40+
defaultPythonVersion: '3.13.6'
41+
supportedPythonVersions: '["3.13.6"]'
4242

4343
jobs:
4444
matrix:

‎.pre-commit-config.yaml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ ci:
1717
submodules: true
1818

1919
default_language_version:
20-
python: python3.11
20+
python: python3.13
2121

2222
repos:
2323
- repo: https://github.com/pre-commit-ci/pre-commit-ci-config
@@ -121,7 +121,7 @@ repos:
121121
- id: uv-lock
122122
name: Verify uv lock file
123123
# Override python interpreter from .python-versions as that is too strict for pre-commit.ci
124-
args: ["-p3.11"]
124+
args: ["-p3.13"]
125125

126126
- repo: local
127127
hooks:

‎.python-versions‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
cpython-3.11.9-windows-x86-none
21
cpython-3.13.6-windows-x86-none

‎projectDocs/dev/createDevEnvironment.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ The following dependencies need to be installed on your system:
4848

4949
#### Python
5050

51-
[Python](https://www.python.org/), version 3.11.9, 32 bit.
51+
[Python](https://www.python.org/), version 3.13.6, 32 bit.
5252
Install the python version listed in [.python-versions](../../.python-versions)
5353

5454
#### uv

‎pyproject.toml‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ description = "NonVisual Desktop Access (NVDA)"
99
maintainers = [
1010
{name = "NV Access", email = "info@nvaccess.org"},
1111
]
12-
requires-python = ">=3.11,<3.14"
12+
requires-python = ">=3.13,<3.14"
1313
classifiers = [
1414
"Development Status :: 5 - Production/Stable",
1515
"Intended Audience :: End Users/Desktop",
@@ -33,8 +33,6 @@ dependencies = [
3333
"schedule==1.2.2",
3434
# NVDA_DMP requires diff-match-patch
3535
"fast-diff-match-patch==2.1.0",
36-
# typing_extensions are required for specifying default value for `TypeVar` prior to Python 3.13 (see PEP 696)
37-
"typing-extensions==4.12.2",
3836
# pycaw is a Core Audio Windows Library used for sound split
3937
"pycaw==20240210",
4038
# Sanitize HTML for browsable messages and documentation output to prevent XSS from translators

‎source/UIAHandler/_remoteOps/remoteFuncWrapper.py‎

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,20 @@
11
# A part of NonVisual Desktop Access (NVDA)
22
# This file is covered by the GNU General Public License.
33
# See the file COPYING for more details.
4-
# Copyright (C) 2023-2024 NV Access Limited
4+
# Copyright (C) 2023-2025 NV Access Limited
55

66

7-
from __future__ import annotations
7+
from collections.abc import Callable
88
from typing import (
99
Generator,
1010
ContextManager,
11-
Callable,
1211
Concatenate,
13-
ParamSpec,
14-
TypeVar,
1512
)
1613
import functools
1714
import contextlib
1815
from . import builder
1916

20-
21-
_remoteFunc_self = TypeVar("_remoteFunc_self", bound=builder._RemoteBase)
22-
_remoteFunc_paramSpec = ParamSpec("_remoteFunc_paramSpec")
23-
_remoteFunc_return = TypeVar("_remoteFunc_return")
17+
_remoteFunc_self = builder._RemoteBase
2418

2519

2620
class _BaseRemoteFuncWrapper:
@@ -29,13 +23,13 @@ def generateArgsKwargsString(self, *args, **kwargs) -> str:
2923
kwargsString = ", ".join(f"{key}={repr(val)}" for key, val in kwargs.items())
3024
return f"({', '.join([argsString, kwargsString])})"
3125

32-
def _execRawFunc(
26+
def _execRawFunc[**P, R](
3327
self,
34-
func: Callable[Concatenate[_remoteFunc_self, _remoteFunc_paramSpec], _remoteFunc_return],
28+
func: Callable[Concatenate[_remoteFunc_self, P], R],
3529
funcSelf: _remoteFunc_self,
36-
*args: _remoteFunc_paramSpec.args,
37-
**kwargs: _remoteFunc_paramSpec.kwargs,
38-
) -> _remoteFunc_return:
30+
*args: P.args,
31+
**kwargs: P.kwargs,
32+
) -> R:
3933
main = funcSelf.rob.getInstructionList("main")
4034
main.addComment(
4135
f"Entering {func.__qualname__}{self.generateArgsKwargsString(*args, **kwargs)}",
@@ -44,16 +38,16 @@ def _execRawFunc(
4438
main.addComment(f"Exiting {func.__qualname__}")
4539
return res
4640

47-
def __call__(
41+
def __call__[**P, R](
4842
self,
49-
func: Callable[Concatenate[_remoteFunc_self, _remoteFunc_paramSpec], _remoteFunc_return],
50-
) -> Callable[Concatenate[_remoteFunc_self, _remoteFunc_paramSpec], _remoteFunc_return]:
43+
func: Callable[Concatenate[_remoteFunc_self, P], R],
44+
) -> Callable[Concatenate[_remoteFunc_self, P], R]:
5145
@functools.wraps(func)
5246
def wrapper(
5347
funcSelf: _remoteFunc_self,
54-
*args: _remoteFunc_paramSpec.args,
55-
**kwargs: _remoteFunc_paramSpec.kwargs,
56-
) -> _remoteFunc_return:
48+
*args: P.args,
49+
**kwargs: P.kwargs,
50+
) -> R:
5751
return self._execRawFunc(func, funcSelf, *args, **kwargs)
5852

5953
return wrapper
@@ -65,40 +59,40 @@ class RemoteMethodWrapper(_BaseRemoteFuncWrapper):
6559
def __init__(self, mutable: bool = False):
6660
self._mutable = mutable
6761

68-
def _execRawFunc(
62+
def _execRawFunc[**P, R](
6963
self,
70-
func: Callable[Concatenate[_remoteFunc_self, _remoteFunc_paramSpec], _remoteFunc_return],
64+
func: Callable[Concatenate[_remoteFunc_self, P], R],
7165
funcSelf: _remoteFunc_self,
72-
*args: _remoteFunc_paramSpec.args,
73-
**kwargs: _remoteFunc_paramSpec.kwargs,
74-
) -> _remoteFunc_return:
66+
*args: P.args,
67+
**kwargs: P.kwargs,
68+
) -> R:
7569
if self._mutable and not funcSelf._mutable:
7670
raise RuntimeError(f"{funcSelf.__class__.__name__} is not mutable")
7771
return super()._execRawFunc(func, funcSelf, *args, **kwargs)
7872

7973

8074
class RemoteContextManager(_BaseRemoteFuncWrapper):
81-
def __call__(
75+
def __call__[**P, R](
8276
self,
8377
func: Callable[
84-
Concatenate[_remoteFunc_self, _remoteFunc_paramSpec],
85-
Generator[_remoteFunc_return, None, None],
78+
Concatenate[_remoteFunc_self, P],
79+
Generator[R, None, None],
8680
],
87-
) -> Callable[Concatenate[_remoteFunc_self, _remoteFunc_paramSpec], ContextManager[_remoteFunc_return]]:
81+
) -> Callable[Concatenate[_remoteFunc_self, P], ContextManager[R]]:
8882
contextFunc = contextlib.contextmanager(func)
8983
return super().__call__(contextFunc)
9084

9185
@contextlib.contextmanager
92-
def _execRawFunc(
86+
def _execRawFunc[**P, R](
9387
self,
9488
func: Callable[
95-
Concatenate[_remoteFunc_self, _remoteFunc_paramSpec],
96-
ContextManager[_remoteFunc_return],
89+
Concatenate[_remoteFunc_self, P],
90+
ContextManager[R],
9791
],
9892
funcSelf: _remoteFunc_self,
99-
*args: _remoteFunc_paramSpec.args,
100-
**kwargs: _remoteFunc_paramSpec.kwargs,
101-
) -> Generator[_remoteFunc_return, None, None]:
93+
*args: P.args,
94+
**kwargs: P.kwargs,
95+
) -> Generator[R, None, None]:
10296
main = funcSelf.rob.getInstructionList("main")
10397
main.addComment(
10498
f"Entering context manager {func.__qualname__}{self.generateArgsKwargsString(*args, **kwargs)}",

‎source/UIAHandler/_remoteOps/remoteTypes/__init__.py‎

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
# A part of NonVisual Desktop Access (NVDA)
22
# This file is covered by the GNU General Public License.
33
# See the file COPYING for more details.
4-
# Copyright (C) 2023-2024 NV Access Limited
4+
# Copyright (C) 2023-2025 NV Access Limited
55

66

77
from __future__ import annotations
88
from typing import (
99
Type,
10-
Any,
1110
Self,
12-
ParamSpec,
1311
Iterable,
1412
Generic,
1513
TypeVar,
@@ -40,11 +38,6 @@
4038
from .. import operation
4139

4240

43-
_remoteFunc_self = TypeVar("_remoteFunc_self", bound=builder._RemoteBase)
44-
_remoteFunc_paramSpec = ParamSpec("_remoteFunc_paramSpec")
45-
_remoteFunc_return = TypeVar("_remoteFunc_return")
46-
47-
4841
LocalTypeVar = TypeVar("LocalTypeVar")
4942

5043

0 commit comments

Comments
 (0)