diff --git a/.github/actionlint.yml b/.github/actionlint.yml deleted file mode 100644 index 8452f9afff2..00000000000 --- a/.github/actionlint.yml +++ /dev/null @@ -1,4 +0,0 @@ -paths: - .github/workflows/testAndPublish.yml: - ignore: - - 'step must run script with "run" section or run action with "uses" section' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7fb9b24c708..c1c311963a0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -97,8 +97,8 @@ repos: ) ) -- repo: https://github.com/rhysd/actionlint - rev: v1.7.12 +- repo: https://github.com/kjanat/actionlint + rev: v1.12.0 hooks: # Lint GitHub Actions workflow files. - id: actionlint @@ -114,7 +114,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Matches Ruff version in pyproject. - rev: v0.15.9 + rev: v0.16.3 hooks: - id: ruff name: lint with ruff @@ -134,7 +134,7 @@ repos: args: ["-p3.13"] - repo: https://github.com/DavidAnson/markdownlint-cli2 - rev: v0.22.0 + rev: v0.23.2 hooks: - id: markdownlint-cli2 name: Lint markdown files @@ -143,7 +143,7 @@ repos: - repo: https://github.com/astral-sh/ty-pre-commit # Matches ty version in pyproject. - rev: v0.0.60 + rev: v0.0.73 hooks: - id: ty name: type check with ty diff --git a/appx/sconscript b/appx/sconscript index ab30388576a..f081abc07ac 100644 --- a/appx/sconscript +++ b/appx/sconscript @@ -4,7 +4,7 @@ # This file may be used under the terms of the GNU General Public License, version 2 or later, as modified by the NVDA license. # For full terms and any additional permissions, see the NVDA license file: https://github.com/nvaccess/nvda/blob/master/copying.txt -import subprocess +import subprocess # noqa: I001 import buildVersion import versionInfo import os @@ -41,7 +41,7 @@ def getCertPublisher(env): packageName = "NVAccessLimited.NVDANonVisualDesktopAccess" -packageVersion = "%s.%s.%s.%s" % ( +packageVersion = "%s.%s.%s.%s" % ( # noqa: UP031 buildVersion.version_year, buildVersion.version_major, env["version_build"], @@ -99,7 +99,7 @@ appxContent = env.Command( Copy("${TARGET}\\appx_images", "${SOURCES[1]}"), Copy("${TARGET}\\AppxManifest.xml", "${SOURCES[2]}"), ] - + [Delete("${TARGET}/%s" % excludeFile) for excludeFile in excludedDistFiles], + + [Delete("${TARGET}/%s" % excludeFile) for excludeFile in excludedDistFiles], # noqa: UP031 ) # Ensure that it is always copied as we can't tell if dist changed env.AlwaysBuild(appxContent) diff --git a/ci/scripts/crowdinSync.py b/ci/scripts/crowdinSync.py index 0945099433d..13dd4346709 100644 --- a/ci/scripts/crowdinSync.py +++ b/ci/scripts/crowdinSync.py @@ -5,7 +5,7 @@ # For more details see: https://www.gnu.org/licenses/gpl-2.0.html -import argparse +import argparse # noqa: I001 import os import requests diff --git a/ci/scripts/mozillaSyms.py b/ci/scripts/mozillaSyms.py index 763d254bf46..49058eadf01 100644 --- a/ci/scripts/mozillaSyms.py +++ b/ci/scripts/mozillaSyms.py @@ -6,7 +6,7 @@ To update the list of symbols uploaded to Mozilla, see the DLL_NAMES constant below. """ -import os +import os # noqa: I001 import subprocess import sys import zipfile @@ -55,16 +55,16 @@ def check_output(command): def processFile(path): - print("dump_syms %s" % path) + print("dump_syms %s" % path) # noqa: UP031 try: stdout = check_output([DUMP_SYMS, path]) except ProcError as e: - print('Error: running "%s %s": %s' % (DUMP_SYMS, path, e.stderr)) + print('Error: running "%s %s": %s' % (DUMP_SYMS, path, e.stderr)) # noqa: UP031 return None, None, None bits = stdout.splitlines()[0].split(" ", 4) if len(bits) != 5: return None, None, None - _, platform, cpu_arch, debug_id, debug_file = bits + _, platform, cpu_arch, debug_id, debug_file = bits # noqa: RUF059 # debug_file will have a .pdb extension; e.g. nvdaHelperRemote.dll.pdb. # The output file format should have a .sym extension instead. # Strip .pdb and add .sym. @@ -78,13 +78,13 @@ def generate(): count = 0 with zipfile.ZipFile(ZIP_FILE, "w", zipfile.ZIP_DEFLATED) as zf: for f in DLL_FILES: - filename, contents, debug_filename = processFile(f) + filename, contents, debug_filename = processFile(f) # noqa: RUF059 if not (filename and contents): print("Error dumping symbols") raise RuntimeError zf.writestr(filename, contents) count += 1 - print("Added %d files to %s" % (count, ZIP_FILE)) + print("Added %d files to %s" % (count, ZIP_FILE)) # noqa: UP031 def upload(): @@ -98,12 +98,12 @@ def upload(): try: r = requests.post( URL, - files={"symbols.zip": open(ZIP_FILE, "rb")}, + files={"symbols.zip": open(ZIP_FILE, "rb")}, # noqa: SIM115 headers={"Auth-Token": os.getenv("mozillaSymsAuthToken")}, allow_redirects=False, ) break # success - except Exception as e: + except Exception as e: # noqa: BLE001 print(f"Attempt {i + 1} failed: {e!r}") errors.append(repr(e)) else: # no break in for loop @@ -113,10 +113,10 @@ def upload(): if 200 <= r.status_code < 300: print("Uploaded successfully!") elif r.status_code < 400: - print("Error: bad auth token? (%d)" % r.status_code) + print("Error: bad auth token? (%d)" % r.status_code) # noqa: UP031 raise RuntimeError else: - print("Error: %d" % r.status_code) + print("Error: %d" % r.status_code) # noqa: UP031 print(r.text) raise RuntimeError return 0 diff --git a/cldrDict_sconscript b/cldrDict_sconscript index 119dea76ab1..80fc6a82a67 100644 --- a/cldrDict_sconscript +++ b/cldrDict_sconscript @@ -10,8 +10,8 @@ import typing if typing.TYPE_CHECKING: import SCons from SCons import ( - Dir, - Import, + Dir, # noqa: TC004 + Import, # noqa: TC004 ) sourceDir: "SCons.Node.FS.Dir" diff --git a/nvdaHelper/archBuild_sconscript b/nvdaHelper/archBuild_sconscript index e8415492c77..ebc72bf46de 100644 --- a/nvdaHelper/archBuild_sconscript +++ b/nvdaHelper/archBuild_sconscript @@ -22,11 +22,14 @@ def clsidStringToCLSIDDefine(clsidString): Into a c-style struct initializer for initializing a GUID (I.e. "{0xabcdef12,0xabcd,0xabcd,{0xab,0xcd,0xab,0xcd,0xef,0x12,0x34,0x56}}") """ d = clsidString[1:-1].replace("-", "") - return "{%s,%s,%s,%s}" % ( - "0x" + d[0:8], - "0x" + d[8:12], - "0x" + d[12:16], - "{%s}" % (",".join("0x" + d[x : x + 2] for x in range(16, 32, 2))), + return ( + "{%s,%s,%s,%s}" # noqa: UP031 + % ( + "0x" + d[0:8], + "0x" + d[8:12], + "0x" + d[12:16], + "{%s}" % (",".join("0x" + d[x : x + 2] for x in range(16, 32, 2))), # noqa: UP031 + ) ) diff --git a/nvdaHelper/cppjieba/sconscript b/nvdaHelper/cppjieba/sconscript index 2c2ec41b83a..db68f807f6d 100644 --- a/nvdaHelper/cppjieba/sconscript +++ b/nvdaHelper/cppjieba/sconscript @@ -3,7 +3,7 @@ # This file may be used under the terms of the GNU General Public License, version 2 or later, as modified by the NVDA license. # For full terms and any additional permissions, see the NVDA license file: https://github.com/nvaccess/nvda/blob/master/copying.txt -import typing # noqa: E402 +import typing Import( [ @@ -12,7 +12,7 @@ Import( "sourceDir", ] ) -thirdPartyEnv: Environment = thirdPartyEnv +thirdPartyEnv: Environment = thirdPartyEnv # noqa: PLW0127 env: Environment = typing.cast(Environment, thirdPartyEnv.Clone()) cppjiebaPath = Dir("#include/cppjieba") diff --git a/nvdaHelper/detours/sconscript b/nvdaHelper/detours/sconscript index d0f0406c3b0..4430151c448 100644 --- a/nvdaHelper/detours/sconscript +++ b/nvdaHelper/detours/sconscript @@ -1,9 +1,9 @@ #!/usr/bin/env python3 Import(["thirdPartyEnv"]) -import typing # noqa: E402 +import typing -thirdPartyEnv: Environment = thirdPartyEnv +thirdPartyEnv: Environment = thirdPartyEnv # noqa: PLW0127 env: Environment = typing.cast(Environment, thirdPartyEnv.Clone()) detoursPath = Dir("#include/detours") diff --git a/nvdaHelper/espeak/sconscript b/nvdaHelper/espeak/sconscript index dd2750fe4fc..18838e53c78 100644 --- a/nvdaHelper/espeak/sconscript +++ b/nvdaHelper/espeak/sconscript @@ -4,7 +4,7 @@ # See the file COPYING for more details. # Copyright (C) 2011-2026 NV Access Limited -import ctypes.wintypes +import ctypes.wintypes # noqa: I001 import enum import os import ctypes @@ -1006,7 +1006,7 @@ def espeak_compileDict_buildAction( exit status to indicate an unsuccessful build." """ if len(target) != 1: - targetStrings = list((str(t) for t in target)) + targetStrings = list(str(t) for t in target) # noqa: C400 raise ValueError(f"Unexpected number of targets: {targetStrings}") target = target[0] @@ -1136,7 +1136,7 @@ phonemeData = env.espeak_compilePhonemeData(espeakRepo.Dir("espeak-ng-data"), es env.Depends(phonemeData, espeakLib) for i in phonemeData: iDir = espeakRepo.Dir("espeak-ng-data").abspath - l = len(iDir) + 1 # noqa: E741 + l = len(iDir) + 1 fileName = i.abspath[l:] env.InstallAs(os.path.join(synthDriversDir.Dir("espeak-ng-data").abspath, fileName), i) @@ -1167,7 +1167,7 @@ for dictFileName, (langCode, inputFiles) in espeakDictionaryCompileList.items(): dictFile = env.Command( target=dictFilePath, - source=list((dictSourcePath.File(f) for f in inputFiles)), + source=list(dictSourcePath.File(f) for f in inputFiles), # noqa: C400 action=espeak_compileDict_buildAction, ) diff --git a/nvdaHelper/ia2_sconscript b/nvdaHelper/ia2_sconscript index 90ea1f69515..174bbf38e94 100644 --- a/nvdaHelper/ia2_sconscript +++ b/nvdaHelper/ia2_sconscript @@ -18,21 +18,20 @@ import re Import("env") # We want a single merged IDL, rather than the separate IDL files in the IA2 source. -RE_IDL_IMPORT = re.compile(r'import "[A-Z].*$', re.M) +RE_IDL_IMPORT = re.compile(r'import "[A-Z].*$', re.MULTILINE) def buildMergedIdl(target, source, env): - outFile = open(str(target[0]), "w") + outFile = open(str(target[0]), "w") # noqa: SIM115 # The first source is a header and should be included unmodified. - inFile = open(str(source[0]), "r") + inFile = open(str(source[0]), "r") # noqa: SIM115 outFile.write(inFile.read()) outFile.write("\n") for idl in source[1:]: # This source should be included with import statements removed. - inFile = open(str(idl), "r") + inFile = open(str(idl), "r") # noqa: SIM115 outFile.write(RE_IDL_IMPORT.sub("", inFile.read())) outFile.write("\n") - return None idlDir = env.Dir("#include/ia2/api") diff --git a/nvdaHelper/liblouis/sconscript b/nvdaHelper/liblouis/sconscript index 0f882ffc956..dc7c2fe1d30 100644 --- a/nvdaHelper/liblouis/sconscript +++ b/nvdaHelper/liblouis/sconscript @@ -4,7 +4,7 @@ # This file may be used under the terms of the GNU General Public License, version 2 or later, as modified by the NVDA license. # For full terms and any additional permissions, see the NVDA license file: https://github.com/nvaccess/nvda/blob/master/copying.txt -import os +import os # noqa: I001 import re import typing from SCons.Environment import Environment @@ -16,8 +16,8 @@ Import( "sourceDir", ], ) -sourceDir: Base = sourceDir -thirdPartyEnv: Environment = thirdPartyEnv +sourceDir: Base = sourceDir # noqa: PLW0127 +thirdPartyEnv: Environment = thirdPartyEnv # noqa: PLW0127 env: Environment = typing.cast(Environment, thirdPartyEnv.Clone()) louisRootDir = env.Dir("#include/liblouis") @@ -69,7 +69,7 @@ env.Append( # reserved ISO C names (like strdup) in favour of non-portable conforming # variants that start with an '_'. This removes those deprecation warnings. */ "_CRT_NONSTDC_NO_DEPRECATE", - ("PACKAGE_VERSION", r"\"%s\"" % getLouisVersion()), + ("PACKAGE_VERSION", r"\"%s\"" % getLouisVersion()), # noqa: UP031 "WIDECHARS_ARE_UCS4", # Tell liblouis.h that we're exporting liblouis dll functions, not importing them. "_EXPORTING", @@ -96,7 +96,7 @@ sourceFiles = [ "metadata.c", "utils.c", ] -objs = [env.Object("%s.obj" % f, louisSourceDir.File(f)) for f in sourceFiles] +objs = [env.Object("%s.obj" % f, louisSourceDir.File(f)) for f in sourceFiles] # noqa: UP031 louisLib = env.SharedLibrary("liblouis", objs) if signExec: env.AddPostAction(louisLib[0], [signExec]) diff --git a/nvdaHelper/localWin10/sconscript b/nvdaHelper/localWin10/sconscript index b04cf33527d..894582eca20 100644 --- a/nvdaHelper/localWin10/sconscript +++ b/nvdaHelper/localWin10/sconscript @@ -21,7 +21,7 @@ Import( # Ignoring Flake8 F821: 'undefined name' due to nonstandard SCons import -env = env.Clone() # noqa: F821 +env = env.Clone() localWin10Lib = env.SharedLibrary( target="nvdaHelperLocalWin10", @@ -38,7 +38,7 @@ localWin10Lib = env.SharedLibrary( "WindowsApp", # Ignoring Flake8 F821: 'undefined name' due to nonstandard SCons import localLib[2], - ], # noqa: F821 + ], ) Return(["localWin10Lib"]) diff --git a/projectDocs/dev/developerGuide/conf.py b/projectDocs/dev/developerGuide/conf.py index 57dd01b44c8..19cf72a6e52 100644 --- a/projectDocs/dev/developerGuide/conf.py +++ b/projectDocs/dev/developerGuide/conf.py @@ -18,18 +18,18 @@ # used for developer documentation build, "ImportError: Typelib different than module" is raised # by comTypes. # This patch causes the error to be ignored, which matches the behavior at runtime. -import monkeyPatches.comtypesMonkeyPatches # noqa: E402 +import monkeyPatches.comtypesMonkeyPatches monkeyPatches.comtypesMonkeyPatches.replace_check_version() monkeyPatches.comtypesMonkeyPatches.appendComInterfacesToGenSearchPath() # Initialize languageHandler so that sphinx is able to deal with translatable strings. -import languageHandler # noqa: E402 +import languageHandler languageHandler.setLanguage("en") # Initialize globalVars.appArgs to something sensible. -import globalVars # noqa: E402 +import globalVars # noqa: I001 # Set an empty config path @@ -44,8 +44,8 @@ # Import NVDA's versionInfo module. -import buildVersion # noqa: E402 -import versionInfo # noqa: E402 +import buildVersion +import versionInfo # Set a suitable updateVersionType for the updateCheck module to be imported buildVersion.updateVersionType = "stable" @@ -107,9 +107,9 @@ # Perform some manual mocking of specific objects. # autodoc can only mock modules, not objects. -from sphinx.ext.autodoc._dynamic._mock import _make_subclass # noqa: E402 +from sphinx.ext.autodoc._dynamic._mock import _make_subclass # noqa: I001 -import config # noqa: E402 +import config # Mock an instance of the configuration manager. config.conf = _make_subclass("conf", "config")() diff --git a/pyproject.toml b/pyproject.toml index 7a096ae7bae..5b45c3e03a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -116,6 +116,15 @@ max-complexity = 15 ignore = [ # indentation contains tabs "W191", + # lower snake case module names, we use lowerCamelCase instead + "N999", + # Linux executable warning that precommit.ci picks up due to linux runners + "EXE001", + "EXE002", +] +extend-unsafe-fixes = [ + # Sort imports + "I001", ] logger-objects = ["logHandler.log"] @@ -407,10 +416,10 @@ dev = [ "uv==0.12.5", ] lint = [ - "ruff==0.15.9", - "prek==0.4.4", - "pyright[nodejs]==1.1.407", - "ty==0.0.60", + "ruff==0.16.3", + "prek==0.4.14", + "pyright[nodejs]==1.1.411", + "ty==0.0.73", ] license-check = [ "licensecheck==2026.0.8", diff --git a/runtime-builders/synthDriverHost32/buildVersionLoader.py b/runtime-builders/synthDriverHost32/buildVersionLoader.py index dad099ede06..6ba6d79308f 100644 --- a/runtime-builders/synthDriverHost32/buildVersionLoader.py +++ b/runtime-builders/synthDriverHost32/buildVersionLoader.py @@ -4,7 +4,7 @@ # See the file COPYING for more details. -import sys +import sys # noqa: I001 # This file wraps buildVersion.py from NVDA's own source directory, @@ -12,7 +12,7 @@ sys.path.insert(0, "../../source") try: - from buildVersion import ( + from buildVersion import ( # noqa: I001 version_detailed, formatBuildVersionString, name, @@ -23,9 +23,9 @@ del sys.path[0] __all__ = [ - "version_detailed", "formatBuildVersionString", "name", "publisher", "version", + "version_detailed", ] diff --git a/runtime-builders/synthDriverHost32/setup-runtime.py b/runtime-builders/synthDriverHost32/setup-runtime.py index d74991bc57e..b519f076313 100644 --- a/runtime-builders/synthDriverHost32/setup-runtime.py +++ b/runtime-builders/synthDriverHost32/setup-runtime.py @@ -3,7 +3,7 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -import os +import os # noqa: I001 import importlib import fnmatch from glob import glob @@ -25,8 +25,8 @@ sys.path.insert(0, nvdaSourceDir) -import gettext # noqa: E402 -from buildVersion import ( # noqa: E402 +import gettext # noqa: I001 +from buildVersion import ( formatBuildVersionString, name, publisher, @@ -43,14 +43,14 @@ # versionInfo names must be imported after Gettext # Suppress E402 (module level import not at top of file) -from versionInfo import ( # noqa: E402 +from versionInfo import ( # noqa: I001 copyright as NVDAcopyright, # copyright is a reserved python keyword description, ) -from py2exe import freeze # noqa: E402 -from py2exe.dllfinder import DllFinder # noqa: E402 +from py2exe import freeze +from py2exe.dllfinder import DllFinder RT_MANIFEST = 24 manifestTemplateFilePath = os.path.join(nvdaSourceDir, "manifest.template.xml") diff --git a/sconstruct b/sconstruct index 201bfa5085a..c760e7e77ad 100755 --- a/sconstruct +++ b/sconstruct @@ -6,7 +6,7 @@ # This file may be used under the terms of the GNU General Public License, version 2 or later. # For more details see: https://www.gnu.org/licenses/gpl-2.0.html -import multiprocessing +import multiprocessing # noqa: I001 import os import platform import sys @@ -23,8 +23,8 @@ if not virtualEnv or not uv or Path.cwd() != Path(virtualEnv).parent: ) sys.exit(1) -import time # noqa: E402 -import importlib.util # noqa: E402 +import time # noqa: I001 +import importlib.util def recursiveCopy(env, targetDir, sourceDir): @@ -43,12 +43,12 @@ def recursiveCopy(env, targetDir, sourceDir): # Import NVDA's versionInfo module. -import gettext # noqa: E402 +import gettext gettext.install("nvda") sys.path.append("source") -import buildVersion # noqa: E402 -import versionInfo # noqa: E402 +import buildVersion +import versionInfo del sys.path[-1] @@ -156,7 +156,7 @@ env.AddMethod(recursiveCopy) # Check for any unknown variables unknown = vars.UnknownVariables().keys() if len(unknown) > 0: - print("Unknown commandline variables: %s" % unknown) + print("Unknown commandline variables: %s" % unknown) # noqa: UP031 Exit(1) env["copyright"] = versionInfo.copyright @@ -260,7 +260,7 @@ projectRCSubstDict = { "%copyright%": env["copyright"], "%publisher%": env["publisher"], "%version%": env["version"], - "%productName%": "%s (%s)" % (buildVersion.name, versionInfo.longName), + "%productName%": "%s (%s)" % (buildVersion.name, versionInfo.longName), # noqa: UP031 } resFile = env.RES( target="build/nvda.res", @@ -394,16 +394,11 @@ def NVDADistGenerator(target, source, env, for_signature): # Any '\n' characters written are translated to the system default line separator, os.linesep. action = [ lambda target, source, env: ( - open(buildVersionFn, "w", encoding="utf-8").write( - "version = {version!r}\n" - "publisher = {publisher!r}\n" - "updateVersionType = {updateVersionType!r}\n" - "version_build = {version_build!r}\n".format( - version=version, - publisher=publisher, - updateVersionType=updateVersionType, - version_build=version_build, - ), + open(buildVersionFn, "w", encoding="utf-8").write( # noqa: SIM115 + f"version = {version!r}\n" + f"publisher = {publisher!r}\n" + f"updateVersionType = {updateVersionType!r}\n" + f"version_build = {version_build!r}\n", ) # In Python 3 write returns the number of characters written, # which scons treats as an error code. @@ -460,7 +455,7 @@ def ZipArchiveAction(target, source, env): arcName = arcName.replace(".." + os.path.sep, "") return "" if arcName == "." else arcName else: - getArcName = lambda origName: "" if origName == "." else origName # noqa: E731 + getArcName = lambda origName: "" if origName == "." else origName # Nasty hack to make zipfile use best compression, since it isn't configurable. # Tried setting memlevel to 9 as well, but it made compression slightly worse. @@ -508,7 +503,7 @@ uninstGen = env.Command( '/DVERSION_MAJOR="$version_major"', '/DVERSION_MINOR="$version_minor"', '/DVERSION_BUILD="$version_build"', - "/DUNINSTEXE=%s" % uninstFile.abspath, + "/DUNINSTEXE=%s" % uninstFile.abspath, # noqa: UP031 "/DINSTEXE=${TARGET.abspath}", "$SOURCE", ], @@ -533,7 +528,7 @@ env.Clean(dist, dist) env.Clean([dist], buildDir) launcher = env.Command( - outputDir.File("%s.exe" % outFilePrefix), + outputDir.File("%s.exe" % outFilePrefix), # noqa: UP031 ["launcher/nvdaLauncher.nsi", dist], [ [ @@ -557,7 +552,7 @@ if certFile or apiSigningToken: env.Alias("launcher", launcher) clientArchive = env.ZipArchive( - outputDir.File("%s_controllerClient.zip" % outFilePrefix), + outputDir.File("%s_controllerClient.zip" % outFilePrefix), # noqa: UP031 clientDir, relativeTo=clientDir, ) @@ -575,7 +570,7 @@ outputHeadingStylesFile = env.Command( ) outputLogoFile = env.Command(outputDir.File("favicon.ico"), logo, Copy("$TARGET", "$SOURCE")) changesFile = env.Command( - outputDir.File("%s_changes.html" % outFilePrefix), + outputDir.File("%s_changes.html" % outFilePrefix), # noqa: UP031 userDocsDir.File("en/changes.html"), Copy("$TARGET", "$SOURCE"), ) @@ -643,11 +638,11 @@ def makePot(target, source, env): # Tweak the headers. potFn = str(target[0]) - tmpFn = "%s.tmp" % potFn + tmpFn = "%s.tmp" % potFn # noqa: UP031 with open(potFn, "rt", encoding="utf-8") as inp, open(tmpFn, "wt", encoding="utf-8") as out: for lineNum, line in enumerate(inp): if lineNum == 1: - line = "# %s\n" % versionInfo.copyright + line = "# %s\n" % versionInfo.copyright # noqa: UP031 elif lineNum == 2: # Delete line. continue @@ -673,7 +668,7 @@ potSourceFiles = [ if not ( # Exclude comInterfaces, since these don't contain translatable strings # and they cause unknown encoding warnings. - recurseDirs.startswith(r"source\comInterfaces") + recurseDirs.startswith(r"source\comInterfaces") # noqa: PIE810 # Exclude userConfig folder which does not contain NVDA code but may contain gettext call without # translator comments in add-ons or scratchpad, triggering false positive for checkpot script. or recurseDirs.startswith(r"source\userConfig") @@ -691,7 +686,7 @@ env.Alias("pot", pot) symbolsList = [] symbolsList.extend(env.Glob(os.path.join(sourceLibDir.path, "*.pdb"))) symbolsList.extend(env.Glob(os.path.join(sourceLibDir64.path, "*.pdb"))) -symbolsArchive = env.ZipArchive(outputDir.File("%s_debugSymbols.zip" % outFilePrefix), symbolsList) +symbolsArchive = env.ZipArchive(outputDir.File("%s_debugSymbols.zip" % outFilePrefix), symbolsList) # noqa: UP031 env.Alias("symbolsArchive", symbolsArchive) appx_storeSubmission = env.SConscript( diff --git a/site_scons/site_tools/doxygen.py b/site_scons/site_tools/doxygen.py index 3385989340c..3753bd317ac 100644 --- a/site_scons/site_tools/doxygen.py +++ b/site_scons/site_tools/doxygen.py @@ -19,7 +19,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -import os +import os # noqa: I001 import os.path import glob from fnmatch import fnmatch @@ -34,12 +34,12 @@ def fetchDoxygenPath(): r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\doxygen_is1", access=winreg.KEY_READ | winreg.KEY_WOW64_64KEY, ) as doxygenKey: - doxygenPath = '"%s"' % os.path.join( + doxygenPath = '"%s"' % os.path.join( # noqa: UP031 winreg.QueryValueEx(doxygenKey, "InstallLocation")[0], "Bin", "doxygen.exe", ) - except WindowsError: + except OSError: return "doxygen" return doxygenPath @@ -82,9 +82,9 @@ def append_data(data, key, new_data, token): else: if token == "+=": if key not in data: - data[key] = list() + data[key] = list() # noqa: C408 elif token == "=": - data[key] = list() + data[key] = list() # noqa: C408 else: append_data(data, key, new_data, token) new_data = True @@ -162,7 +162,7 @@ def DoxySourceScan(node, env, path): file_patterns = data.get("FILE_PATTERNS", default_file_patterns) exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns) - for node in data.get("INPUT", []): + for node in data.get("INPUT", []): # noqa: PLR1704 if os.path.isfile(node): sources.append(node) elif os.path.isdir(node): @@ -186,7 +186,7 @@ def DoxySourceScan(node, env, path): sources.append(filename) else: for pattern in file_patterns: - sources.extend(glob.glob("/".join([node, pattern]))) + sources.extend(glob.glob("/".join([node, pattern]))) # noqa: FLY002 sources = [env.File(path) for path in sources] return sources diff --git a/site_scons/site_tools/gettextTool.py b/site_scons/site_tools/gettextTool.py index 8d21f84ba54..ac11b906a3b 100644 --- a/site_scons/site_tools/gettextTool.py +++ b/site_scons/site_tools/gettextTool.py @@ -26,7 +26,7 @@ def generate(env): env["BUILDERS"]["gettextMoFile"] = env.Builder( action=env.Action( [[MSGFMT, "-o", "$TARGET", "$SOURCE"]], - lambda t, s, e: "Compiling gettext template %s" % s[0].path, + lambda t, s, e: "Compiling gettext template %s" % s[0].path, # noqa: UP031 ), suffix=".mo", src_suffix=".po", diff --git a/site_scons/site_tools/msrpc.py b/site_scons/site_tools/msrpc.py index 3ecdb6e414f..bba6d82dbdf 100644 --- a/site_scons/site_tools/msrpc.py +++ b/site_scons/site_tools/msrpc.py @@ -21,12 +21,12 @@ # This build emitter tells the builder that a header file, a client stub c file, and a server stub c file will be generated def MSRPCStubs_buildEmitter(target, source, env): - base, ext = Util.splitext(str(target[0] if len(target) > 0 else source[0])) - newTargets = ["%s.h" % base] + base, ext = Util.splitext(str(target[0] if len(target) > 0 else source[0])) # noqa: RUF059 + newTargets = ["%s.h" % base] # noqa: UP031 if not env["MSRPCStubs_noServer"]: - newTargets.append("%s_S.c" % base) + newTargets.append("%s_S.c" % base) # noqa: UP031 if not env["MSRPCStubs_noClient"]: - newTargets.append("%s_C.c" % base) + newTargets.append("%s_C.c" % base) # noqa: UP031 return (newTargets, source) @@ -35,7 +35,7 @@ def MSRPCStubs_builder_actionGenerator(target, source, env, for_signature): for src in source: src = str(src) if src.endswith(".acf"): - sources.append("/acf %s" % src) + sources.append("/acf %s" % src) # noqa: UP031 else: sources.append(src) sources = " ".join(sources) @@ -43,28 +43,28 @@ def MSRPCStubs_builder_actionGenerator(target, source, env, for_signature): for tg in target: tg = str(tg) if tg.endswith(".h"): - targets.append("/header %s" % tg) + targets.append("/header %s" % tg) # noqa: UP031 elif tg.endswith("_S.c"): - targets.append("/sstub %s" % tg) + targets.append("/sstub %s" % tg) # noqa: UP031 elif tg.endswith("_C.c"): - targets.append("/cstub %s" % tg) + targets.append("/cstub %s" % tg) # noqa: UP031 else: - raise ValueError("Don't know what to do with %s" % tg) + raise ValueError("Don't know what to do with %s" % tg) # noqa: UP031 targets = " ".join(targets) noServer = "/server none" if env.get("MSRPCStubs_noServer", False) else "" noClient = "/client none" if env.get("MSRPCStubs_noClient", False) else "" prefix = env.get("MSRPCStubs_prefix", "") if prefix: - prefix = "/prefix all %s" % prefix + prefix = "/prefix all %s" % prefix # noqa: UP031 serverPrefix = env.get("MSRPCStubs_serverPrefix", "") if serverPrefix: - serverPrefix = "/prefix server %s" % serverPrefix + serverPrefix = "/prefix server %s" % serverPrefix # noqa: UP031 clientPrefix = env.get("MSRPCStubs_clientPrefix", "") if clientPrefix: - clientPrefix = "/prefix client %s" % clientPrefix + clientPrefix = "/prefix client %s" % clientPrefix # noqa: UP031 - return " ".join( + return " ".join( # noqa: FLY002 ["${MIDL}", "${MIDLFLAGS}", noServer, noClient, prefix, serverPrefix, clientPrefix, targets, sources], ) diff --git a/site_scons/site_tools/recursiveInstall.py b/site_scons/site_tools/recursiveInstall.py index f06fdb44de3..5538fd6c42d 100644 --- a/site_scons/site_tools/recursiveInstall.py +++ b/site_scons/site_tools/recursiveInstall.py @@ -53,7 +53,7 @@ def RecursiveInstall(env, target, dir): dir = env.Dir(dir).abspath target = env.Dir(target).abspath - l = len(dir) + 1 # noqa: E741 + l = len(dir) + 1 relnodes = [n.abspath[l:] for n in nodes] diff --git a/source/COMRegistrationFixes/__init__.py b/source/COMRegistrationFixes/__init__.py index bac4916fd86..e33cbe2ba60 100644 --- a/source/COMRegistrationFixes/__init__.py +++ b/source/COMRegistrationFixes/__init__.py @@ -10,7 +10,7 @@ https://github.com/nvaccess/nvda/issues/12560 """ -import os +import os # noqa: I001 import subprocess import winVersion import globalVars diff --git a/source/IAccessibleHandler/__init__.py b/source/IAccessibleHandler/__init__.py index 79e83ec8e5d..81e56032562 100644 --- a/source/IAccessibleHandler/__init__.py +++ b/source/IAccessibleHandler/__init__.py @@ -3,7 +3,7 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -import typing +import typing # noqa: I001 from winBindings import user32 @@ -13,12 +13,12 @@ import re import struct -from typing import ( - Optional, - Tuple, - Dict, - Union, - Set, +from typing import ( # noqa: UP035 + Optional, # noqa: F401 + Tuple, # noqa: F401 + Dict, # noqa: F401 + Union, # noqa: F401 + Set, # noqa: F401 ) import weakref from ctypes import ( @@ -72,7 +72,7 @@ # childID event params. liveNVDAObjectTable = weakref.WeakValueDictionary() -IAccessibleRolesToNVDARoles: Dict[Union[int, str], controlTypes.Role] = { +IAccessibleRolesToNVDARoles: dict[int | str, controlTypes.Role] = { oleacc.ROLE_SYSTEM_WINDOW: controlTypes.Role.WINDOW, oleacc.ROLE_SYSTEM_CLIENT: controlTypes.Role.PANE, oleacc.ROLE_SYSTEM_TITLEBAR: controlTypes.Role.TITLEBAR, @@ -254,44 +254,44 @@ def _getStatesSetFromIAccessibleStates( IAccessibleStates: int, -) -> Set[controlTypes.State]: - return set( +) -> set[controlTypes.State]: + return set( # noqa: C401 IAccessibleStatesToNVDAStates[IAState] - for IAState in IAccessibleStatesToNVDAStates.keys() + for IAState in IAccessibleStatesToNVDAStates if IAState & IAccessibleStates ) -def getStatesSetFromIAccessible2States(IAccessible2States: int) -> Set[State]: - return set( +def getStatesSetFromIAccessible2States(IAccessible2States: int) -> set[State]: + return set( # noqa: C401 IAccessible2StatesToNVDAStates[IA2State] - for IA2State in IAccessible2StatesToNVDAStates.keys() + for IA2State in IAccessible2StatesToNVDAStates if IA2State & IAccessible2States ) -def getStatesSetFromIAccessibleAttrs(attrs: "textInfos.ControlField") -> Set[State]: +def getStatesSetFromIAccessibleAttrs(attrs: "textInfos.ControlField") -> set[State]: # States are serialized (in XML) with an attribute per state. # The value for the state is used in the attribute name. # The attribute value is always 1. # EG IAccessible::state_40="1" IAccessibleStateAttrName = "IAccessible::state_{}" - return set( + return set( # noqa: C401 IAccessibleStatesToNVDAStates[IAState] - for IAState in IAccessibleStatesToNVDAStates.keys() + for IAState in IAccessibleStatesToNVDAStates if int(attrs.get(IAccessibleStateAttrName.format(IAState), 0)) ) -def getStatesSetFromIAccessible2Attrs(attrs: "textInfos.ControlField") -> Set[State]: +def getStatesSetFromIAccessible2Attrs(attrs: "textInfos.ControlField") -> set[State]: # States are serialized (in XML) with an attribute per state. # The value for the state is used in the attribute name. # The attribute value is always 1. # EG IAccessible2::state_40="1" IAccessible2StateAttrName = "IAccessible2::state_{}" - return set( + return set( # noqa: C401 IAccessible2StatesToNVDAStates[IA2State] - for IA2State in IAccessible2StatesToNVDAStates.keys() + for IA2State in IAccessible2StatesToNVDAStates if int(attrs.get(IAccessible2StateAttrName.format(IA2State), 0)) ) @@ -304,7 +304,7 @@ def calculateNvdaRole(IARole: int, IAStates: int) -> Role: return role -def calculateNvdaStates(IARole: int, IAStates: int) -> Set[State]: +def calculateNvdaStates(IARole: int, IAStates: int) -> set[State]: """Convert IAStates bit set into a Set of NVDA States and apply any required transformations.""" role = IAccessibleRolesToNVDARoles.get(IARole, Role.UNKNOWN) states = _getStatesSetFromIAccessibleStates(IAStates) @@ -312,7 +312,7 @@ def calculateNvdaStates(IARole: int, IAStates: int) -> Set[State]: return states -def NVDARoleFromAttr(accRole: Optional[str]) -> Role: +def NVDARoleFromAttr(accRole: str | None) -> Role: if not accRole: # empty string or None return controlTypes.Role.UNKNOWN assert isinstance(accRole, str) @@ -324,14 +324,14 @@ def NVDARoleFromAttr(accRole: Optional[str]) -> Role: def normalizeIAccessible( - pacc: Union[IUnknown, IA.IAccessible, IA2.IAccessible2], + pacc: IUnknown | IA.IAccessible | IA2.IAccessible2, childID: int = 0, -) -> Union[IA.IAccessible, IA2.IAccessible2]: +) -> IA.IAccessible | IA2.IAccessible2: if not isinstance(pacc, IA.IAccessible): try: pacc = pacc.QueryInterface(IA.IAccessible) except COMError: - raise RuntimeError("%s Not an IAccessible" % pacc) + raise RuntimeError("%s Not an IAccessible" % pacc) # noqa: UP031 # #2558: IAccessible2 doesn't support simple children. # Therefore, it doesn't make sense to use IA2 if the child ID is non-0. if childID == 0 and not isinstance(pacc, IA2.IAccessible2): @@ -343,7 +343,7 @@ def normalizeIAccessible( # and return a null COM pointer. Treat this as if QueryService failed. raise ValueError pacc = pacc2 - except: # noqa: E722 Bare except + except: # noqa: E722, S110 pass return pacc @@ -351,7 +351,7 @@ def normalizeIAccessible( def accessibleObjectFromEvent(window, objectID, childID): try: pacc, childID = oleacc.AccessibleObjectFromEvent(window, objectID, childID) - except Exception as e: + except Exception as e: # noqa: BLE001 if isMSAADebugLoggingEnabled(): log.debugWarning( f"oleacc.AccessibleObjectFromEvent failed with {e}." @@ -372,7 +372,7 @@ def accessibleObjectFromPoint(x, y): def windowFromAccessibleObject(ia) -> int: try: return oleacc.WindowFromAccessibleObject(ia) - except WindowsError: + except OSError: log.debugWarning("windowFromAccessibleObject failed", exc_info=True) return 0 @@ -382,7 +382,7 @@ def accessibleChildren(ia, startIndex, numChildren): # new profiles dialogs try: rawChildren = oleacc.AccessibleChildren(ia, startIndex, numChildren) - except (WindowsError, COMError): + except (OSError, COMError): log.debugWarning("AccessibleChildren failed", exc_info=True) return [] children = [] @@ -392,7 +392,7 @@ def accessibleChildren(ia, startIndex, numChildren): # Filtering these out here makes life easier for the caller. continue elif ( - isinstance(child, comtypes.client.lazybind.Dispatch) + isinstance(child, comtypes.client.lazybind.Dispatch) # noqa: SIM101 or isinstance(child, comtypes.client.dynamic._Dispatch) or isinstance(child, IUnknown) ): @@ -407,7 +407,7 @@ def accFocus(ia): try: res = ia.accFocus if ( - isinstance(res, comtypes.client.lazybind.Dispatch) + isinstance(res, comtypes.client.lazybind.Dispatch) # noqa: SIM101 or isinstance(res, comtypes.client.dynamic._Dispatch) or isinstance(res, IUnknown) ): @@ -443,7 +443,7 @@ def accHitTest(ia, x, y): except COMError: return None if ( - isinstance(res, comtypes.client.lazybind.Dispatch) + isinstance(res, comtypes.client.lazybind.Dispatch) # noqa: SIM101 or isinstance(res, comtypes.client.dynamic._Dispatch) or isinstance(res, IUnknown) ): @@ -459,12 +459,12 @@ def accChild(ia, child): if not res: return (ia, child) elif ( - isinstance(res, comtypes.client.lazybind.Dispatch) + isinstance(res, comtypes.client.lazybind.Dispatch) # noqa: SIM101 or isinstance(res, comtypes.client.dynamic._Dispatch) or isinstance(res, IUnknown) ): return normalizeIAccessible(res), 0 - except: # noqa: E722 Bare except + except: # noqa: E722, S110 pass return None @@ -474,7 +474,7 @@ def accParent(ia, child): if not child: res = ia.accParent if ( - isinstance(res, comtypes.client.lazybind.Dispatch) + isinstance(res, comtypes.client.lazybind.Dispatch) # noqa: SIM101 or isinstance(res, comtypes.client.dynamic._Dispatch) or isinstance(res, IUnknown) ): @@ -505,26 +505,26 @@ def accNavigate(pacc, childID, direction): pacc = parentRes[0] return pacc, res elif ( - isinstance(res, comtypes.client.lazybind.Dispatch) + isinstance(res, comtypes.client.lazybind.Dispatch) # noqa: SIM101 or isinstance(res, comtypes.client.dynamic._Dispatch) or isinstance(res, IUnknown) ): return normalizeIAccessible(res, 0), 0 else: - log.debugWarning("Unknown IAccessible type: %s" % res, stack_info=True) + log.debugWarning("Unknown IAccessible type: %s" % res, stack_info=True) # noqa: UP031 return None # C901 'winEventToNVDAEvent' is too complex # Note: when working on winEventToNVDAEvent, look for opportunities to simplify # and move logic out into smaller helper functions. -def winEventToNVDAEvent( # noqa: C901 +def winEventToNVDAEvent( eventID: int, window: int, objectID: int, childID: int, useCache: bool = True, -) -> Optional[Tuple[str, NVDAObjects.IAccessible.IAccessible]]: +) -> tuple[str, NVDAObjects.IAccessible.IAccessible] | None: """Tries to convert a win event ID to an NVDA event name, and instantiate or fetch an NVDAObject for the win event parameters. @param eventID: the win event ID (type) @@ -737,7 +737,7 @@ def processFocusWinEvent(window: int, objectID: int, childID: int, force: bool = NVDAEvent = winEventToNVDAEvent(winUser.EVENT_OBJECT_FOCUS, window, objectID, childID, useCache=False) if not NVDAEvent: return False - eventName, obj = NVDAEvent + eventName, obj = NVDAEvent # noqa: RUF059 if (childID == 0 and obj.IAccessibleRole == oleacc.ROLE_SYSTEM_LIST) or ( objectID == winUser.OBJID_CLIENT and "SysListView32" in obj.windowClassName ): @@ -959,7 +959,7 @@ def processMenuStartWinEvent(eventID, window, objectID, childID, validFocus): NVDAEvent = winEventToNVDAEvent(eventID, window, objectID, childID) if not NVDAEvent: return - eventName, obj = NVDAEvent + eventName, obj = NVDAEvent # noqa: RUF059 if obj.IAccessibleRole != oleacc.ROLE_SYSTEM_MENUPOPUP: # menuStart on anything other than a menu is silly. return @@ -1010,13 +1010,13 @@ def initialize(): global accPropServices try: accPropServices = comtypes.client.CreateObject(IA.CAccPropServices) - except (WindowsError, COMError) as e: - log.debugWarning("AccPropServices is not available: %s" % e) + except (OSError, COMError) as e: + log.debugWarning("AccPropServices is not available: %s" % e) # noqa: UP031 internalWinEventHandler.initialize(processDestroyWinEvent) # C901 'pumpAll' is too complex -def pumpAll(): # noqa: C901 +def pumpAll(): if not internalWinEventHandler._shouldGetEvents(): return focusWinEvents = [] @@ -1114,12 +1114,12 @@ def getIAccIdentity(pacc, childID): if accPropServices: try: hwnd, objectID, childID = accPropServices.DecomposeHwndIdentityString(stringPtr, stringSize) - return dict(windowHandle=hwnd, objectID=c_int(objectID).value, childID=childID) + return dict(windowHandle=hwnd, objectID=c_int(objectID).value, childID=childID) # noqa: C408 except COMError: hmenu, childID = accPropServices.DecomposeHmenuIdentityString(stringPtr, stringSize) # hmenu is a wireHMENU, but it seems we can just treat this as a number. # comtypes transparently does this for wireHWND. - return dict(menuHandle=cast(hmenu, wintypes.HMENU).value, childID=childID) + return dict(menuHandle=cast(hmenu, wintypes.HMENU).value, childID=childID) # noqa: C408 stringPtr = cast(stringPtr, POINTER(c_char * stringSize)) fields = struct.unpack("IIiI", stringPtr.contents.raw) d = {} @@ -1165,7 +1165,7 @@ def findGroupboxObject(obj): # C901 'getRecursiveTextFromIAccessibleTextObject' -def getRecursiveTextFromIAccessibleTextObject(obj, startOffset=0, endOffset=-1): # noqa: C901 +def getRecursiveTextFromIAccessibleTextObject(obj, startOffset=0, endOffset=-1): if not isinstance(obj, IA2.IAccessibleText): try: textObject = obj.QueryInterface(IA2.IAccessibleText) @@ -1208,8 +1208,8 @@ def getRecursiveTextFromIAccessibleTextObject(obj, startOffset=0, endOffset=-1): try: index = hypertextObject.hyperlinkIndex(i + startOffset) childTextObject = hypertextObject.hyperlink(index).QueryInterface(IA.IAccessible) - t = " %s " % getRecursiveTextFromIAccessibleTextObject(childTextObject) - except: # noqa: E722 Bare except + t = " %s " % getRecursiveTextFromIAccessibleTextObject(childTextObject) # noqa: UP031 + except: # noqa: E722, S110 pass textList.append(t) return "".join(textList).replace(" ", " ") @@ -1223,9 +1223,9 @@ def getRecursiveTextFromIAccessibleTextObject(obj, startOffset=0, endOffset=-1): # C901: splitIA2Attribs is too complex -def splitIA2Attribs( # noqa: C901 +def splitIA2Attribs( attribsString: str, -) -> Dict[str, Union[str, Dict]]: +) -> dict[str, str | dict]: """Split an IAccessible2 attributes string into a dict of attribute keys and values. An invalid attributes string does not cause an error, but strange results may be returned. Subattributes are handled. Subattribute keys and values are placed into a dict which becomes the value @@ -1303,7 +1303,7 @@ def isMarshalledIAccessible(IAccessibleObject): see if it was implemented in oleacc.dll (its local) or ole32.dll (its marshalled). """ if not isinstance(IAccessibleObject, IA.IAccessible): - raise TypeError("object should be of type IAccessible, not %s" % IAccessibleObject) + raise TypeError("object should be of type IAccessible, not %s" % IAccessibleObject) # noqa: UP031 buf = create_unicode_buffer(1024) addr = ( POINTER(c_void_p) diff --git a/source/IAccessibleHandler/internalWinEventHandler.py b/source/IAccessibleHandler/internalWinEventHandler.py index 4669248406e..573321dc0cb 100644 --- a/source/IAccessibleHandler/internalWinEventHandler.py +++ b/source/IAccessibleHandler/internalWinEventHandler.py @@ -7,9 +7,9 @@ Provides a non-threaded (limited by GIL) Windows Event Hook and processing. """ -from ctypes import c_int +from ctypes import c_int # noqa: I001 -from typing import Dict, Callable +from collections.abc import Callable import core from winBindings.user32 import WINEVENTPROC @@ -74,7 +74,7 @@ def winEventCallback( childID: int, threadID: int, timestamp: int, -) -> None: # noqa: C901 +) -> None: if window is None: window = 0 if isMSAADebugLoggingEnabled(): @@ -192,7 +192,7 @@ def winEventCallback( if winEventLimiter.addEvent(eventID, window, objectID, childID, threadID): core.requestPump(immediate=eventID == winUser.EVENT_OBJECT_FOCUS) except Exception: - log.error("winEventCallback", exc_info=True) + log.error("winEventCallback", exc_info=True) # noqa: G201 # Register internal object event with IAccessible @@ -213,7 +213,7 @@ def initialize( ): global _processDestroyWinEvent _processDestroyWinEvent = processDestroyWinEventFunc - for eventType in winEventIDsToNVDAEventNames: + for eventType in winEventIDsToNVDAEventNames: # noqa: PLC0206 hookID = winUser.setWinEventHook(eventType, eventType, 0, cWinEventCallback, 0, 0, 0) if hookID: winEventHookIDs.append(hookID) @@ -270,4 +270,4 @@ def _shouldGetEvents(): # In order to handle speaking of typed characters etc. # winEventCallback adds these whenever it sees an event for ConsoleWindowClass windows, # As winEvents always contain the true thread ID. -consoleWindowsToThreadIDs: Dict[int, int] = {} +consoleWindowsToThreadIDs: dict[int, int] = {} diff --git a/source/IAccessibleHandler/orderedWinEventLimiter.py b/source/IAccessibleHandler/orderedWinEventLimiter.py index 2e6575d8231..45400fafecf 100644 --- a/source/IAccessibleHandler/orderedWinEventLimiter.py +++ b/source/IAccessibleHandler/orderedWinEventLimiter.py @@ -1,5 +1,4 @@ -from typing import Optional, List -import heapq +import heapq # noqa: I001 import itertools import winUser @@ -18,7 +17,7 @@ ) -class OrderedWinEventLimiter(object): +class OrderedWinEventLimiter: """Collects and limits winEvents based on whether they are focus changes, or just generic (all other ones). @@ -82,7 +81,7 @@ def addEvent( def flushEvents( self, - alwaysAllowedObjects: Optional[List[IAccessibleObjectIdentifierType]] = None, + alwaysAllowedObjects: list[IAccessibleObjectIdentifierType] | None = None, ) -> list[tuple[int, int, int, int]]: """Returns a list of winEvents that have been added. Due to limiting, it will not necessarily be all the winEvents that were originally added. @@ -101,7 +100,7 @@ def flushEvents( # Increase the event count for this thread by 1. threadCount = threadCounters.get(k[-1], 0) threadCounters[k[-1]] = threadCount + 1 - if isMSAADebugLoggingEnabled(): + if isMSAADebugLoggingEnabled(): # noqa: SIM102 if threadCount == MAX_WINEVENTS_PER_THREAD: log.debug(f"winEvent limit for thread {k[-1]} hit for this core cycle") # Find out if this event is for an object whos events are always allowed. diff --git a/source/IAccessibleHandler/types.py b/source/IAccessibleHandler/types.py index ec4318d7252..d6ea23cc540 100644 --- a/source/IAccessibleHandler/types.py +++ b/source/IAccessibleHandler/types.py @@ -9,9 +9,8 @@ """ import enum -from typing import Tuple -IAccessibleObjectIdentifierType = Tuple[ +IAccessibleObjectIdentifierType = tuple[ int, # windowHandle int, # objectID int, # childID diff --git a/source/IAccessibleHandler/utils.py b/source/IAccessibleHandler/utils.py index 3409d1ccbd4..226f12aceaf 100644 --- a/source/IAccessibleHandler/utils.py +++ b/source/IAccessibleHandler/utils.py @@ -8,7 +8,7 @@ Kept here so they can be re-used without having to worry about circular imports. """ -import appModuleHandler +import appModuleHandler # noqa: I001 from comInterfaces import IAccessible2Lib as IA2 import config import winUser diff --git a/source/JABHandler.py b/source/JABHandler.py index cccbd5a5dae..7a49ada9494 100644 --- a/source/JABHandler.py +++ b/source/JABHandler.py @@ -3,7 +3,7 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -from collections.abc import Callable +from collections.abc import Callable # noqa: I001 from enum import IntEnum, IntFlag import os import queue @@ -57,7 +57,7 @@ def _errcheck(res, func, args): if not res: - raise RuntimeError("Result %s" % res) + raise RuntimeError("Result %s" % res) # noqa: UP031 return res @@ -65,7 +65,7 @@ def _fixBridgeFunc(restype, name, *argtypes, **kwargs): try: func = getattr(bridgeDll, name) except AttributeError: - log.warning("%s not found in Java Access Bridge dll" % name) + log.warning("%s not found in Java Access Bridge dll" % name) # noqa: UP031 return func.restype = restype func.argtypes = argtypes @@ -612,7 +612,7 @@ def getWindowHandleFromAccContext(vmID, accContext): return vmIDsToWindowHandles.get(vmID) -class JABContext(object): +class JABContext: def __init__(self, hwnd=None, vmID=None, accContext=None): if hwnd and not vmID: vmID = c_long() @@ -635,7 +635,7 @@ def __del__(self): log.debugWarning("Error releasing java object", exc_info=True) def __eq__(self, jabContext): - if self.vmID == jabContext.vmID and bridgeDll.isSameObject( + if self.vmID == jabContext.vmID and bridgeDll.isSameObject( # noqa: SIM103 self.vmID, self.accContext, jabContext.accContext, @@ -650,7 +650,7 @@ def __hash__(self): return super().__hash__() def __ne__(self, jabContext): - if self.vmID != jabContext.vmID or not bridgeDll.isSameObject( + if self.vmID != jabContext.vmID or not bridgeDll.isSameObject( # noqa: SIM103 self.vmID, self.accContext, jabContext.accContext, @@ -730,7 +730,7 @@ def getAccessibleTextRange(self, start: int, end: int) -> str: def getAccessibleTextLineBounds(self, index): index = max(index, 0) - log.debug("lineBounds: index %s" % index) + log.debug("lineBounds: index %s" % index) # noqa: UP031 # Java returns end as the last character, not end as past the last character startIndex = c_int() endIndex = c_int() @@ -743,7 +743,7 @@ def getAccessibleTextLineBounds(self, index): ) start = startIndex.value end = endIndex.value - log.debug("line bounds: start %s, end %s" % (start, end)) + log.debug("line bounds: start %s, end %s" % (start, end)) # noqa: UP031 if end < start or start < 0: # Invalid or empty line. return (0, -1) @@ -760,7 +760,7 @@ def getAccessibleTextLineBounds(self, index): ) tempStart = max(startIndex.value, 0) tempEnd = max(endIndex.value, 0) - log.debug("line bounds: tempStart %s, tempEnd %s" % (tempStart, tempEnd)) + log.debug("line bounds: tempStart %s, tempEnd %s" % (tempStart, tempEnd)) # noqa: UP031 if tempStart > (index + 1): # This line starts after the requested index, so set end to point at the line before. end = tempStart - 1 @@ -778,13 +778,13 @@ def getAccessibleTextLineBounds(self, index): ) tempStart = max(startIndex.value, 0) tempEnd = max(endIndex.value, 0) - log.debug("line bounds: tempStart %s, tempEnd %s" % (tempStart, tempEnd)) + log.debug("line bounds: tempStart %s, tempEnd %s" % (tempStart, tempEnd)) # noqa: UP031 if tempEnd < (index - 1): # This line ends before the requested index, so set start to point at the line after. start = tempEnd + 1 else: ok = True - log.debug("line bounds: returning %s, %s" % (start, end)) + log.debug("line bounds: returning %s, %s" % (start, end)) # noqa: UP031 return (start, end) def getAccessibleParentFromContext(self): @@ -1016,7 +1016,7 @@ def internal_hasFocus(sourceContext): if isinstance(focus, NVDAObjects.JAB.JAB) and focus.jabContext == sourceContext: return True ancestors = reversed(api.getFocusAncestors()) - return any((isinstance(x, NVDAObjects.JAB.JAB) and x.jabContext == sourceContext for x in ancestors)) + return any(isinstance(x, NVDAObjects.JAB.JAB) and x.jabContext == sourceContext for x in ancestors) @AccessBridge_PropertyNameChangeFP @@ -1170,7 +1170,7 @@ def enterJavaWindow_helper(hwnd): while time.time() < timeout and not eventHandler.isPendingEvents("gainFocus"): try: bridgeDll.getAccessibleContextWithFocus(hwnd, byref(vmID), byref(accContext)) - except: # noqa: E722 + except: # noqa: E722, S110 pass if vmID and accContext: break @@ -1196,7 +1196,7 @@ def isJavaWindow(hwnd): def isBridgeEnabled(): try: - data = open(A11Y_PROPS_PATH, "rt").read() + data = open(A11Y_PROPS_PATH, "rt").read() # noqa: SIM115 except OSError: return False return data == A11Y_PROPS_CONTENT @@ -1204,7 +1204,7 @@ def isBridgeEnabled(): def enableBridge(): try: - props = open(A11Y_PROPS_PATH, "wt") + props = open(A11Y_PROPS_PATH, "wt") # noqa: SIM115 props.write(A11Y_PROPS_CONTENT) log.info("Enabled Java Access Bridge for user") except OSError: @@ -1215,7 +1215,7 @@ def initialize(): global bridgeDll, isRunning try: bridgeDll = cdll.LoadLibrary(NVDAState.ReadPaths.javaAccessBridgeDLL) - except WindowsError: + except OSError: raise NotImplementedError("dll not available") _fixBridgeFuncs() if ( @@ -1298,7 +1298,7 @@ def terminate(): def _getKeyLabels(modifiers, character): keys = [v for m, v in JABKeyModifiersToLabels.items() if modifiers & m] if modifiers & AccessibleKeystroke.FKEY: - keys.append("F{}".format(ord(character))) + keys.append(f"F{ord(character)}") elif modifiers & AccessibleKeystroke.CONTROLCODE: keys.append(JABKeyControlCodesToLabels.get(ord(character), character)) else: diff --git a/source/NVDAHelper/__init__.py b/source/NVDAHelper/__init__.py index 871bb973f37..ace57a276ea 100755 --- a/source/NVDAHelper/__init__.py +++ b/source/NVDAHelper/__init__.py @@ -4,7 +4,7 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -from __future__ import annotations +from __future__ import annotations # noqa: I001 from ctypes.wintypes import ( HANDLE, HKEY, @@ -58,21 +58,21 @@ if typing.TYPE_CHECKING: - from speech.priorities import SpeechPriority + from speech.priorities import SpeechPriority # noqa: I001 from characterProcessing import SymbolLevel _remoteLib = None -_remoteLoaderX86: "_RemoteLoader | None" = None -_remoteLoaderAMD64: "_RemoteLoader | None" = None -_remoteLoaderARM64: "_RemoteLoader | None" = None +_remoteLoaderX86: _RemoteLoader | None = None +_remoteLoaderAMD64: _RemoteLoader | None = None +_remoteLoaderARM64: _RemoteLoader | None = None lastLanguageID = None lastLayoutString = None # utility function to point an exported function pointer in a dll to a ctypes wrapped python function def _setDllFuncPointer(dll, name, cfunc): - cast(getattr(dll, name), POINTER(c_void_p)).contents.value = cast(cfunc, c_void_p).value # noqa: F405 + cast(getattr(dll, name), POINTER(c_void_p)).contents.value = cast(cfunc, c_void_p).value # Implementation of nvdaController methods @@ -91,10 +91,10 @@ def nvdaController_speakText(text): # Note: when working on nvdaController_speakSsml, look for opportunities to simplify # and move logic out into smaller helper functions. @WINFUNCTYPE(c_long, c_wchar_p, c_int, c_int, c_bool) -def nvdaController_speakSsml( # noqa: C901 +def nvdaController_speakSsml( ssml: str, - symbolLevel: "SymbolLevel", - priority: "SpeechPriority", + symbolLevel: SymbolLevel, + priority: SpeechPriority, asynchronous: bool, ) -> SystemErrorCodes: focus = api.getFocusObject() @@ -145,7 +145,7 @@ def markCallable(name: str): try: sequence = _getSpeakSsmlSpeech(ssml, markCallable, prefixSpeechCommand) except Exception: - log.error("Error parsing SSML", exc_info=True) + log.error("Error parsing SSML", exc_info=True) # noqa: G201 return SystemErrorCodes.INVALID_PARAMETER if not asynchronous: @@ -218,17 +218,17 @@ def nvdaController_isSpeaking(pSpeaking: _Pointer[c_bool]) -> int: def _lookupKeyboardLayoutNameWithHexString(layoutString): buf = create_unicode_buffer(1024) bufSize = c_ulong(2048) - key = HKEY() # noqa: F405 + key = HKEY() if ( winBindings.advapi32.RegOpenKeyEx( winreg.HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + layoutString, 0, winreg.KEY_QUERY_VALUE, - byref(key), # noqa: F405 + byref(key), ) == 0 - ): # noqa: F405 + ): try: if ( winBindings.advapi32.RegQueryValueEx( @@ -240,7 +240,7 @@ def _lookupKeyboardLayoutNameWithHexString(layoutString): byref(bufSize), ) == 0 - ): # noqa: F405 + ): winBindings.shlwapi.SHLoadIndirectString(buf.value, buf, 1023, None) return buf.value if winBindings.advapi32.RegQueryValueEx(key, "Layout Text", None, None, buf, byref(bufSize)) == 0: @@ -260,13 +260,13 @@ def nvdaControllerInternal_requestRegistration(uuidString): bindingHandle = HANDLE() bindingHandle.value = localLib.createRemoteBindingHandle(uuidString) if not bindingHandle: - log.error("Could not bind to inproc rpc server for pid %d" % pid) + log.error("Could not bind to inproc rpc server for pid %d" % pid) # noqa: UP031 return -1 registrationHandle = HANDLE() - res = localLib.nvdaInProcUtils_registerNVDAProcess(bindingHandle, byref(registrationHandle)) # noqa: F405 + res = localLib.nvdaInProcUtils_registerNVDAProcess(bindingHandle, byref(registrationHandle)) if res != 0 or not registrationHandle: log.error( - "Could not register NVDA with inproc rpc server for pid %d, res %d, registrationHandle %s" + "Could not register NVDA with inproc rpc server for pid %d, res %d, registrationHandle %s" # noqa: UP031 % (pid, res, registrationHandle), ) winBindings.rpcrt4.RpcBindingFree(byref(bindingHandle)) @@ -292,7 +292,7 @@ def nvdaControllerInternal_reportLiveRegion(text: str, politeness: str): focus = api.getFocusObject() if focus.sleepMode == focus.SLEEP_FULL: return -1 - import speech + import speech # noqa: I001 import braille from aria import AriaLivePoliteness from speech.priorities import Spri @@ -300,7 +300,7 @@ def nvdaControllerInternal_reportLiveRegion(text: str, politeness: str): try: politenessValue = AriaLivePoliteness(politeness.lower()) except ValueError: - log.error( + log.error( # noqa: G201 f"nvdaControllerInternal_reportLiveRegion got unknown politeness of {politeness}", exc_info=True, ) @@ -347,7 +347,7 @@ def nvdaControllerInternal_logMessage(level, pid, message): if pid: from appModuleHandler import getAppNameFromProcessID - codepath = "RPC process %s (%s)" % (pid, getAppNameFromProcessID(pid, includeExt=True)) + codepath = "RPC process %s (%s)" % (pid, getAppNameFromProcessID(pid, includeExt=True)) # noqa: UP031 else: codepath = "NVDAHelperLocal" log._log(level, message, [], codepath=codepath) @@ -355,7 +355,7 @@ def nvdaControllerInternal_logMessage(level, pid, message): def handleInputCompositionEnd(result): - import speech + import speech # noqa: I001 import characterProcessing from NVDAObjects.inputComposition import InputComposition from NVDAObjects.IAccessible.mscandui import ModernCandidateUICandidateItem @@ -396,7 +396,7 @@ def handleInputCompositionEnd(result): def handleInputCompositionStart(compositionString, selectionStart, selectionEnd, isReading): - import speech + import speech # noqa: I001 from NVDAObjects.inputComposition import InputComposition from NVDAObjects.behaviors import CandidateItem @@ -432,7 +432,7 @@ def handleInputCompositionStart(compositionString, selectionStart, selectionEnd, @WINFUNCTYPE(c_long, c_wchar_p, c_int, c_int, c_int) def nvdaControllerInternal_inputCompositionUpdate(compositionString, selectionStart, selectionEnd, isReading): - from NVDAObjects.inputComposition import InputComposition + from NVDAObjects.inputComposition import InputComposition # noqa: I001 from NVDAObjects.IAccessible.mscandui import ModernCandidateUICandidateItem if selectionStart == -1: @@ -659,7 +659,7 @@ def nvdaControllerInternal_inputLangChangeNotify(threadID, hkl, layoutString): inputMethodName = "".join(inputMethodName.split(" - ")[1:]) # Include the language only if it changed. if languageID != lastLanguageID: - msg = "{language} - {layout}".format(language=inputLanguageName, layout=inputMethodName) + msg = f"{inputLanguageName} - {inputMethodName}" else: msg = inputMethodName lastLanguageID = languageID @@ -724,7 +724,7 @@ def nvdaControllerInternal_handleRemoteURL(url): :param url: The nvdaremote:// URL to process :return: 0 on success, -1 on failure """ - from _remoteClient import connectionInfo, _remoteClient as client + from _remoteClient import connectionInfo, _remoteClient as client # noqa: I001 try: if not client: @@ -738,7 +738,7 @@ def nvdaControllerInternal_handleRemoteURL(url): ) return 0 except Exception: - log.error("Error handling remote URL", exc_info=True) + log.error("Error handling remote URL", exc_info=True) # noqa: G201 return -1 @@ -835,12 +835,12 @@ def initialize() -> None: try: _setDllFuncPointer(localLib.dll, f"_{name}", func) except AttributeError as e: - log.error( - "nvdaHelperLocal function pointer for %s could not be found, possibly old nvdaHelperLocal dll" + log.error( # noqa: G201 + "nvdaHelperLocal function pointer for %s could not be found, possibly old nvdaHelperLocal dll" # noqa: UP031 % name, exc_info=True, ) - raise e + raise e # noqa: TRY201 localLib.nvdaHelperLocal_initialize(globalVars.appArgs.secure) # The rest of this function (to do with injection) only applies if NVDA is not running as a Windows store application if config.isAppX: @@ -856,9 +856,9 @@ def initialize() -> None: winKernel.LOAD_WITH_ALTERED_SEARCH_PATH, ) if not h: - log.critical("Error loading nvdaHelperRemote.dll: %s" % WinError()) # noqa: F405 + log.critical("Error loading nvdaHelperRemote.dll: %s" % WinError()) # noqa: UP031 return - _remoteLib = CDLL("nvdaHelperRemote", handle=h) # noqa: F405 + _remoteLib = CDLL("nvdaHelperRemote", handle=h) if _remoteLib.injection_initialize() == 0: raise RuntimeError("Error initializing NVDAHelperRemote") if not _remoteLib.installIA2Support(): @@ -874,7 +874,7 @@ def initialize() -> None: elif arch == "ARM64": if ReadPaths.coreArchLibPath != ReadPaths.versionedLibX86Path: _remoteLoaderX86 = _RemoteLoader(ReadPaths.versionedLibX86Path) - if ReadPaths.coreArchLibPath != ReadPaths.versionedLibAMD64Path: + if ReadPaths.coreArchLibPath != ReadPaths.versionedLibAMD64Path: # noqa: SIM102 # Windows 10 on ARM does not support AMD64 emulation. # Thus only start the AMD64 remote loader if on Windows 11 or above. if winVersion.getWinVer() >= winVersion.WIN11: diff --git a/source/NVDAHelper/localLib.py b/source/NVDAHelper/localLib.py index 061896d51d5..7f2056aacc5 100644 --- a/source/NVDAHelper/localLib.py +++ b/source/NVDAHelper/localLib.py @@ -4,7 +4,7 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -from ctypes import ( +from ctypes import ( # noqa: I001 c_ushort, c_void_p, c_size_t, @@ -354,7 +354,7 @@ class EXCEL_CELLINFO(Structure): ) # special handling to ensure that the bstr is freed correctly. -VBuf_getTextInRange = CFUNCTYPE(c_int, VBufRemote_bufferHandle_t, c_int, c_int, POINTER(BSTR), c_int)( # noqa: F405 +VBuf_getTextInRange = CFUNCTYPE(c_int, VBufRemote_bufferHandle_t, c_int, c_int, POINTER(BSTR), c_int)( ("VBuf_getTextInRange", dll), ((1,), (1,), (1,), (2,), (1,)), ) diff --git a/source/NVDAHelper/localWin10.py b/source/NVDAHelper/localWin10.py index dac4147bdc1..615a3eb1aa4 100644 --- a/source/NVDAHelper/localWin10.py +++ b/source/NVDAHelper/localWin10.py @@ -5,7 +5,7 @@ """Functions exported by nvdaHelperLocalWin10.dll, and supporting definitions.""" -from ctypes import CFUNCTYPE, POINTER, c_bool, c_int, c_uint, c_void_p, c_wchar_p, windll +from ctypes import CFUNCTYPE, POINTER, c_bool, c_int, c_uint, c_void_p, c_wchar_p, windll # noqa: I001 from comtypes import BSTR import NVDAState diff --git a/source/NVDAObjects/IAccessible/MSHTML.py b/source/NVDAObjects/IAccessible/MSHTML.py index 6aca35437e1..6305055604c 100644 --- a/source/NVDAObjects/IAccessible/MSHTML.py +++ b/source/NVDAObjects/IAccessible/MSHTML.py @@ -4,7 +4,7 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -from comtypes import COMError +from comtypes import COMError # noqa: I001 import comtypes.client import comtypes.automation from comtypes import IServiceProvider @@ -28,7 +28,6 @@ from ..window import Window from NVDAObjects.UIA import UIA, UIATextInfo from locationHelper import RectLTRB -from typing import Dict IID_IHTMLElement = comtypes.GUID("{3050F1FF-98B5-11CF-BB82-00AA00BDCE0B}") @@ -40,7 +39,7 @@ class UIAMSHTMLTextInfo(UIATextInfo): _atEndOfStory = False def __init__(self, obj, position, _rangeObj=None): - super(UIAMSHTMLTextInfo, self).__init__(obj, position, _rangeObj) + super().__init__(obj, position, _rangeObj) if position == textInfos.POSITION_CARET: tempRange = self._rangeObj.clone() tempRange.ExpandToEnclosingUnit(UIAHandler.TextUnit_Character) @@ -55,7 +54,7 @@ def __init__(self, obj, position, _rangeObj=None): self._atEndOfStory = True def copy(self): - info = super(UIAMSHTMLTextInfo, self).copy() + info = super().copy() info._atEndOfStory = self._atEndOfStory return info @@ -63,7 +62,7 @@ def expand(self, unit): if unit in (textInfos.UNIT_CHARACTER, textInfos.UNIT_WORD) and self._atEndOfStory: return self._atEndOfStory = False - return super(UIAMSHTMLTextInfo, self).expand(unit) + return super().expand(unit) def move(self, unit, direction, endPoint=None): if direction == 0: @@ -73,10 +72,10 @@ def move(self, unit, direction, endPoint=None): self._atEndOfStory = False if direction == 0: return -1 - return super(UIAMSHTMLTextInfo, self).move(unit, direction, endPoint=endPoint) + return super().move(unit, direction, endPoint=endPoint) -class HTMLAttribCache(object): +class HTMLAttribCache: def __init__(self, HTMLNode): self.HTMLNode = HTMLNode self.cache = {} @@ -109,7 +108,7 @@ def __contains__(self, item): return contains -nodeNamesToNVDARoles: Dict[str, int] = { +nodeNamesToNVDARoles: dict[str, int] = { "FRAME": controlTypes.Role.FRAME, "IFRAME": controlTypes.Role.INTERNALFRAME, "FRAMESET": controlTypes.Role.DOCUMENT, @@ -210,17 +209,17 @@ def locateHTMLElementByID(document, ID): try: element = document.getElementByID(ID) except COMError as e: - log.debugWarning("document.getElementByID failed with COMError %s" % e) + log.debugWarning("document.getElementByID failed with COMError %s" % e) # noqa: UP031 element = None except COMError as e: - log.debugWarning("document.getElementsByName failed with COMError %s" % e) + log.debugWarning("document.getElementsByName failed with COMError %s" % e) # noqa: UP031 element = None if element: return element try: nodeName = document.body.nodeName except COMError as e: - log.debugWarning("document.body.nodeName failed with COMError %s" % e) + log.debugWarning("document.body.nodeName failed with COMError %s" % e) # noqa: UP031 return None if nodeName: nodeName = nodeName.upper() @@ -231,7 +230,7 @@ def locateHTMLElementByID(document, ID): try: frames = document.getElementsByTagName(tag) except COMError as e: - log.debugWarning("document.getElementsByTagName failed with COMError %s" % e) + log.debugWarning("document.getElementsByTagName failed with COMError %s" % e) # noqa: UP031 return None if not frames: # frames can be None in IE 10 return None @@ -305,7 +304,7 @@ def _expandToLine(self, textRange): oldSelRange.select() def __init__(self, obj, position, _rangeObj=None): - super(MSHTMLTextInfo, self).__init__(obj, position) + super().__init__(obj, position) if _rangeObj: self._rangeObj = _rangeObj.duplicate() return @@ -343,11 +342,11 @@ def __init__(self, obj, position, _rangeObj=None): self._rangeObj.moveToBookmark(position.data) else: raise TypeError( - "Bookmark was for %s type, not for %s type" + "Bookmark was for %s type, not for %s type" # noqa: UP031 % (position.infoClass.__name__, self.__class__.__name__), ) else: - raise NotImplementedError("position: %s" % (position,)) + raise NotImplementedError("position: %s" % (position,)) # noqa: UP031 def expand(self, unit): if unit == textInfos.UNIT_PARAGRAPH: @@ -373,10 +372,10 @@ def expand(self, unit): elif unit == textInfos.UNIT_STORY: self._rangeObj.expand("textedit") else: - raise NotImplementedError("unit: %s" % unit) + raise NotImplementedError("unit: %s" % unit) # noqa: UP031 def _get_isCollapsed(self): - if self._rangeObj.compareEndPoints("startToEnd", self._rangeObj) == 0: + if self._rangeObj.compareEndPoints("startToEnd", self._rangeObj) == 0: # noqa: SIM103 return True else: return False @@ -452,10 +451,10 @@ def _get__UIAControl(self): def makeTextInfo(self, position): if self._UIAControl: return self._UIAControl.makeTextInfo(position) - return super(MSHTML, self).makeTextInfo(position) + return super().makeTextInfo(position) - HTMLNodeNameNavSkipList = ["#comment", "SCRIPT", "HEAD", "HTML", "PARAM", "STYLE"] - HTMLNodeNameEmbedList = ["OBJECT", "EMBED", "APPLET", "FRAME", "IFRAME"] + HTMLNodeNameNavSkipList = ["#comment", "SCRIPT", "HEAD", "HTML", "PARAM", "STYLE"] # noqa: RUF012 + HTMLNodeNameEmbedList = ["OBJECT", "EMBED", "APPLET", "FRAME", "IFRAME"] # noqa: RUF012 _ignoreCaretEvents = ( False #:Set to true when moving the caret to calculate lines, event_caret will be disabled. @@ -483,7 +482,7 @@ def event_caret(self): if not newCaretBookmark or newCaretBookmark == getattr(self, "_oldCaretBookmark", None): return self._oldCaretBookmark = newCaretBookmark - return super(MSHTML, self).event_caret() + return super().event_caret() @classmethod def kwargsFromSuper(cls, kwargs, relation=None): @@ -559,7 +558,7 @@ def findOverlayClasses(self, clsList): clsList.append(MSHTML) if not self.HTMLNodeHasAncestorIAccessible: # The IAccessibleObject is for this node (not an ancestor), so IAccessible overlay classes are relevant. - super(MSHTML, self).findOverlayClasses(clsList) + super().findOverlayClasses(clsList) if self.IAccessibleRole == oleacc.ROLE_SYSTEM_DIALOG: ariaRoles = (self.HTMLAttributes["role"] or "").split(" ") if "dialog" in ariaRoles: @@ -577,7 +576,7 @@ def _get_treeInterceptorClass(self): import virtualBuffers.MSHTML return virtualBuffers.MSHTML.MSHTML - return super(MSHTML, self).treeInterceptorClass + return super().treeInterceptorClass def _get_isCurrent(self) -> controlTypes.IsCurrent: try: @@ -627,7 +626,7 @@ def __init__(self, HTMLNode=None, IAccessibleObject=None, IAccessibleChildID=Non if not IAccessibleObject: raise InvalidNVDAObject("Couldn't get IAccessible, probably dead object") - super(MSHTML, self).__init__( + super().__init__( IAccessibleObject=IAccessibleObject, IAccessibleChildID=IAccessibleChildID, **kwargs, @@ -665,10 +664,10 @@ def _get_TextInfo(self): self._HTMLNodeSupportsTextRanges = False if self._HTMLNodeSupportsTextRanges: return MSHTMLTextInfo - return super(MSHTML, self).TextInfo + return super().TextInfo def isDuplicateIAccessibleEvent(self, obj): - if not super(MSHTML, self).isDuplicateIAccessibleEvent(obj): + if not super().isDuplicateIAccessibleEvent(obj): return False # MSHTML winEvents can't be trusted for uniqueness, so just do normal object comparison. return self == obj @@ -682,10 +681,10 @@ def _isEqual(self, other): ) except (COMError, NameError): pass - return super(MSHTML, self)._isEqual(other) + return super()._isEqual(other) def _get_presentationType(self): - presType = super(MSHTML, self).presentationType + presType = super().presentationType if presType == self.presType_content and self.HTMLAttributes["role"] == "presentation": presType = self.presType_layout if presType == self.presType_content and self.role in ( @@ -706,7 +705,7 @@ def _get_shouldAllowIAccessibleFocusEvent(self): ariaRole = self.HTMLAttributes["aria-role"] if ariaRole == "gridcell": return True - return super(MSHTML, self).shouldAllowIAccessibleFocusEvent + return super().shouldAllowIAccessibleFocusEvent def _get_name(self): ariaLabelledBy = self.HTMLAttributes["aria-labelledBy"] @@ -752,7 +751,7 @@ def _get_name(self): if title and isinstance(title, str): return title return "" - return super(MSHTML, self).name + return super().name def _get_landmark(self): if self.HTMLNode: @@ -781,7 +780,7 @@ def _get_value(self): ): return "" else: - return super(MSHTML, self).value + return super().value def _get_description(self): ariaDescribedBy = self.HTMLAttributes["aria-describedBy"] @@ -797,19 +796,19 @@ def _get_description(self): pass if self.HTMLNodeHasAncestorIAccessible: return "" - return super(MSHTML, self).description + return super().description def _get_basicText(self): - if self.HTMLNode and not self.HTMLNodeName == "SELECT": + if self.HTMLNode and not self.HTMLNodeName == "SELECT": # noqa: SIM201 try: return self.HTMLNode.data or "" except (COMError, AttributeError, NameError): pass try: - return self.HTMLNode.innerText or super(MSHTML, self).basicText + return self.HTMLNode.innerText or super().basicText except (COMError, AttributeError, NameError): pass - return super(MSHTML, self).basicText + return super().basicText def _get_role(self): if self.HTMLNode: @@ -835,10 +834,10 @@ def _get_role(self): ): return nodeNamesToNVDARoles.get(nodeName, controlTypes.Role.SECTION) if self.IAccessibleChildID > 0: - states = super(MSHTML, self).states + states = super().states if controlTypes.State.LINKED in states: return controlTypes.Role.LINK - role = super(MSHTML, self).role + role = super().role # IE uses a MSAA role of ROLE_SYSTEM_TEXT with no readonly state for unsupported or future tags with an explicit ARIA role. # If this is the case, force the role to staticText so this is not confused as a real edit field. if role == controlTypes.Role.EDITABLETEXT and ariaRole and ariaRole != "textbox": @@ -847,7 +846,7 @@ def _get_role(self): def _get_states(self): if not self.HTMLNodeHasAncestorIAccessible: - states = super(MSHTML, self).states + states = super().states else: states = set() ariaSort = self.HTMLAttributes["aria-sort"] @@ -921,7 +920,7 @@ def _get_parent(self): obj = MSHTML(HTMLNode=parentNode) if obj and obj.HTMLNodeName not in self.HTMLNodeNameNavSkipList: return obj - return super(MSHTML, self).parent + return super().parent def _get_previous(self): if self.HTMLNode: @@ -935,7 +934,7 @@ def _get_previous(self): if obj and obj.HTMLNodeName in self.HTMLNodeNameNavSkipList: obj = obj.previous return obj - return super(MSHTML, self).previous + return super().previous def _get_next(self): if self.HTMLNode: @@ -949,12 +948,12 @@ def _get_next(self): if obj and obj.HTMLNodeName in self.HTMLNodeNameNavSkipList: obj = obj.next return obj - return super(MSHTML, self).next + return super().next def _get_firstChild(self): if self.HTMLNode: if self.HTMLNodeName in ("FRAME", "IFRAME"): - return super(MSHTML, self).firstChild + return super().firstChild try: childNode = self.HTMLNode.firstChild except COMError: @@ -967,12 +966,12 @@ def _get_firstChild(self): return obj if self.HTMLNodeHasAncestorIAccessible: return None - return super(MSHTML, self).firstChild + return super().firstChild def _get_lastChild(self): if self.HTMLNode: if self.HTMLNodeName in ("FRAME", "IFRAME"): - return super(MSHTML, self).lastChild + return super().lastChild try: childNode = self.HTMLNode.lastChild except COMError: @@ -985,7 +984,7 @@ def _get_lastChild(self): return obj if self.HTMLNodeHasAncestorIAccessible: return None - return super(MSHTML, self).lastChild + return super().lastChild def _get_columnNumber(self): if not self.role == controlTypes.Role.TABLECELL or not self.HTMLNode: @@ -1002,7 +1001,7 @@ def _get_rowNumber(self): while HTMLNode: try: return HTMLNode.rowIndex + 1 - except: # noqa: E722 + except: # noqa: E722, S110 pass HTMLNode = HTMLNode.parentNode raise NotImplementedError @@ -1032,7 +1031,7 @@ def doAction(self, index=None): return except NameError: pass - super(MSHTML, self).doAction(index=index) + super().doAction(index=index) def _get_isFocusable(self): nodeName = self.HTMLNodeName @@ -1059,7 +1058,7 @@ def setFocus(self): except (COMError, AttributeError, NameError): pass return - super(MSHTML, self).setFocus() + super().setFocus() def _get_table(self): if self.role not in (controlTypes.Role.TABLECELL, controlTypes.Role.TABLEROW) or not self.HTMLNode: @@ -1093,14 +1092,14 @@ def _get_HTMLNodeName(self): return self._HTMLNodeName def _get_devInfo(self): - info = super(MSHTML, self).devInfo - info.append("MSHTML node has ancestor IAccessible: %r" % self.HTMLNodeHasAncestorIAccessible) + info = super().devInfo + info.append("MSHTML node has ancestor IAccessible: %r" % self.HTMLNodeHasAncestorIAccessible) # noqa: UP031 htmlNode = self.HTMLNode try: ret = repr(htmlNode.nodeName) - except Exception as e: - ret = "exception: %s" % e - info.append("MSHTML nodeName: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "exception: %s" % e # noqa: UP031 + info.append("MSHTML nodeName: %s" % ret) # noqa: UP031 return info def _get_language(self): @@ -1119,8 +1118,8 @@ def _get_liveRegionPoliteness(self) -> aria.AriaLivePoliteness: try: return aria.AriaLivePoliteness(politeness.lower()) except ValueError: - log.error(f"Unknown live politeness of {politeness}", exc_info=True) - super().liveRegionPoliteness + log.error(f"Unknown live politeness of {politeness}", exc_info=True) # noqa: G201 + super().liveRegionPoliteness # noqa: B018 def event_liveRegionChange(self): # MSHTML live regions are currently handled with custom code in-process @@ -1140,7 +1139,7 @@ def event_valueChange(self): focus = api.getFocusObject() if controlTypes.State.FOCUSED not in self.states or focus.role != controlTypes.Role.COMBOBOX: # This combo box is not focused. - return super(V6ComboBox, self).event_valueChange() + return super().event_valueChange() # This combo box is focused. However, the value change is not fired on the real focus object. # Therefore, redirect this event to the real focus object. focus.event_valueChange() @@ -1153,19 +1152,19 @@ def _get_name(self): except (COMError, NameError): child = None if not child: - return super(Fieldset, self).name + return super().name try: nodeName = child.nodeName except (COMError, NameError): - return super(Fieldset, self).name + return super().name if nodeName: nodeName = nodeName.upper() if nodeName != "LEGEND": - return super(Fieldset, self).name + return super().name try: text = child.innerText except (COMError, NameError): - return super(Fieldset, self).name + return super().name return text @@ -1175,7 +1174,7 @@ def _get_parent(self): # This object isn't returned when requesting OBJID_CLIENT, nor is it returned as a child of its parent. # Therefore, eliminate it from the ancestry completely. # However it is possible that this body is a child document of a parent frame. In this case don't skip it. - parent = super(Body, self).parent + parent = super().parent if parent and not isinstance(parent, MSHTML): return parent.parent else: @@ -1186,7 +1185,7 @@ def _get_shouldAllowIAccessibleFocusEvent(self): # which might have the focused state. if controlTypes.State.FOCUSED in self.states: return True - parent = super(Body, self).parent + parent = super().parent if not parent: return False return parent.shouldAllowIAccessibleFocusEvent @@ -1203,7 +1202,7 @@ def _get_firstChild(self): except COMError: window = None if not window or window == self.windowHandle: - return super(Object, self).firstChild + return super().firstChild return Window(windowHandle=window) diff --git a/source/NVDAObjects/IAccessible/SysMonthCal32.py b/source/NVDAObjects/IAccessible/SysMonthCal32.py index dbd62b20627..cad8f96e55b 100755 --- a/source/NVDAObjects/IAccessible/SysMonthCal32.py +++ b/source/NVDAObjects/IAccessible/SysMonthCal32.py @@ -4,7 +4,7 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -import controlTypes +import controlTypes # noqa: I001 from . import IAccessible @@ -16,7 +16,7 @@ def _get_name(self): return "" def _get_value(self): - return super(SysMonthCal32, self).name + return super().name def script_valueChange(self, gesture): gesture.send() diff --git a/source/NVDAObjects/IAccessible/__init__.py b/source/NVDAObjects/IAccessible/__init__.py index 9a18f934016..49f635710e6 100644 --- a/source/NVDAObjects/IAccessible/__init__.py +++ b/source/NVDAObjects/IAccessible/__init__.py @@ -3,13 +3,13 @@ # This file may be used under the terms of the GNU General Public License, version 2 or later, as modified by the NVDA license. # For full terms and any additional permissions, see the NVDA license file: https://github.com/nvaccess/nvda/blob/master/copying.txt -import typing -from typing import ( - Generator, +import typing # noqa: I001 +from typing import ( # noqa: UP035 Optional, - Tuple, - Union, + Tuple, # noqa: F401 + Union, # noqa: F401 ) +from collections.abc import Generator from comtypes.automation import IEnumVARIANT, VARIANT from comtypes import ( @@ -66,7 +66,7 @@ FocusableUnfocusableContainer, ToolTip, # noqa: F401 Notification, # noqa: F401 -) # noqa: F401 +) import locationHelper from locationHelper import RectLTRB, RectLTWH import NVDAHelper @@ -79,7 +79,7 @@ def getNVDAObjectFromEvent(hwnd, objectID, childID): try: accHandle = IAccessibleHandler.accessibleObjectFromEvent(hwnd, objectID, childID) - except WindowsError: + except OSError: accHandle = None if not accHandle: return None @@ -283,10 +283,10 @@ def expand(self, unit): if unit == self.unit_mouseChunk: isMouseChunkUnit = True origin = self._startOffset - unit = super(IA2TextTextInfo, self).unit_mouseChunk + unit = super().unit_mouseChunk else: isMouseChunkUnit = False - super(IA2TextTextInfo, self).expand(unit) + super().expand(unit) if isMouseChunkUnit: # If there are embedded object characters near our origin, shrink the range # so that it only covers the text between them. Note that the user can @@ -402,11 +402,11 @@ def _getCharacterOffsets(self, offset): try: start, end, text = self.obj.IAccessibleTextObject.TextAtOffset(offset, IA2.IA2_TEXT_BOUNDARY_CHAR) except COMError: - return super(IA2TextTextInfo, self)._getCharacterOffsets(offset) + return super()._getCharacterOffsets(offset) if text and (textUtils.isHighSurrogate(text) or textUtils.isLowSurrogate(text)): # #8953: Some IA2 implementations, including Gecko and Chromium, # erroneously report one offset for surrogates. - return super(IA2TextTextInfo, self)._getCharacterOffsets(offset) + return super()._getCharacterOffsets(offset) return start, end def _getWordOffsets(self, offset): @@ -416,9 +416,9 @@ def _getWordOffsets(self, offset): except COMError: pass try: - start, end, text = self.obj.IAccessibleTextObject.TextAtOffset(offset, IA2.IA2_TEXT_BOUNDARY_WORD) + start, end, text = self.obj.IAccessibleTextObject.TextAtOffset(offset, IA2.IA2_TEXT_BOUNDARY_WORD) # noqa: RUF059 except COMError: - return super(IA2TextTextInfo, self)._getWordOffsets(offset) + return super()._getWordOffsets(offset) if start > offset or offset > end: # HACK: Work around buggy implementations which return a range that does not include offset. return offset, offset + 1 @@ -426,7 +426,7 @@ def _getWordOffsets(self, offset): def _getLineOffsets(self, offset): try: - start, end, text = self.obj.IAccessibleTextObject.TextAtOffset(offset, IA2.IA2_TEXT_BOUNDARY_LINE) + start, end, text = self.obj.IAccessibleTextObject.TextAtOffset(offset, IA2.IA2_TEXT_BOUNDARY_LINE) # noqa: RUF059 return start, end except COMError: log.debugWarning("IAccessibleText::textAtOffset failed", exc_info=True) @@ -439,7 +439,7 @@ def _getSentenceOffsets(self, offset): except COMError: pass try: - start, end, text = self.obj.IAccessibleTextObject.TextAtOffset( + start, end, text = self.obj.IAccessibleTextObject.TextAtOffset( # noqa: RUF059 offset, IA2.IA2_TEXT_BOUNDARY_SENTENCE, ) @@ -447,7 +447,7 @@ def _getSentenceOffsets(self, offset): raise NotImplementedError return start, end except COMError: - return super(IA2TextTextInfo, self)._getSentenceOffsets(offset) + return super()._getSentenceOffsets(offset) def _getParagraphOffsets(self, offset): try: @@ -456,7 +456,7 @@ def _getParagraphOffsets(self, offset): except COMError: pass try: - start, end, text = self.obj.IAccessibleTextObject.TextAtOffset( + start, end, text = self.obj.IAccessibleTextObject.TextAtOffset( # noqa: RUF059 offset, IA2.IA2_TEXT_BOUNDARY_PARAGRAPH, ) @@ -464,7 +464,7 @@ def _getParagraphOffsets(self, offset): raise RuntimeError("did not expand to paragraph correctly") return start, end except (RuntimeError, COMError): - return super(IA2TextTextInfo, self)._getParagraphOffsets(offset) + return super()._getParagraphOffsets(offset) def _lineNumFromOffset(self, offset): return -1 @@ -473,7 +473,7 @@ def _iterTextWithEmbeddedObjects( self, withFields, formatConfig=None, - ) -> typing.Generator[typing.Union[textInfos.FieldCommand, str, int], None, None]: + ) -> typing.Generator[textInfos.FieldCommand | str | int]: """Iterate through the text, splitting at embedded object characters. Where an embedded object character occurs, its offset is provided. @param withFields: Whether to output control/format fields. @@ -592,7 +592,7 @@ def findOverlayClasses(self, clsList): # because of higher API classes; e.g. MSHTML. clsList.insert(0, FocusableUnfocusableContainer) - if hasattr(self, "IAccessibleTextObject"): + if hasattr(self, "IAccessibleTextObject"): # noqa: SIM102 if role == oleacc.ROLE_SYSTEM_TEXT or controlTypes.State.EDITABLE in self.states: clsList.append(EditableTextWithAutoSelectDetection) @@ -610,7 +610,7 @@ def findOverlayClasses(self, clsList): classString = classString[1:] # #8712: Python 3 wants a dot (.) when loading a module from the same folder via relative imports, and this is done via package argument. mod = importlib.import_module( - "NVDAObjects.IAccessible.%s" % modString, + "NVDAObjects.IAccessible.%s" % modString, # noqa: UP031 package="NVDAObjects.IAccessible", ) newCls = getattr(mod, classString) @@ -766,7 +766,7 @@ def findOverlayClasses(self, clsList): # This is the main (client) area of the window, so we can use other classes at the window level. # #3872: However, don't do this for IAccessible2 because # IA2 supersedes window level APIs and might conflict with them. - super(IAccessible, self).findOverlayClasses(clsList) + super().findOverlayClasses(clsList) # Generic client IAccessibles with no children should be classed as content and should use displayModel if ( clsList[0] == IAccessible @@ -777,11 +777,11 @@ def findOverlayClasses(self, clsList): clsList.insert(0, ContentGenericClient) # C901: 'IAccessible.__init__' is too complex - def __init__( # noqa: C901 + def __init__( self, - windowHandle: Optional[int] = None, - IAccessibleObject: Optional[Union[IUnknown, IA.IAccessible, IA2.IAccessible2]] = None, - IAccessibleChildID: Optional[int] = None, + windowHandle: int | None = None, + IAccessibleObject: IUnknown | IA.IAccessible | IA2.IAccessible2 | None = None, + IAccessibleChildID: int | None = None, event_windowHandle: Optional = None, event_objectID: Optional = None, event_childID: Optional = None, @@ -813,10 +813,10 @@ def __init__( # noqa: C901 if not windowHandle: log.debugWarning("Resorting to WindowFromPoint on accLocation") try: - left, top, width, height = IAccessibleObject.accLocation(0) + left, top, width, height = IAccessibleObject.accLocation(0) # noqa: RUF059 windowHandle = user32.WindowFromPoint(winUser.POINT(left, top)) except COMError as e: - log.debugWarning("accLocation failed: %s" % e) + log.debugWarning("accLocation failed: %s" % e) # noqa: UP031 if not windowHandle: raise InvalidNVDAObject("Can't get a window handle from IAccessible") @@ -840,7 +840,7 @@ def __init__( # noqa: C901 self.event_windowHandle = event_windowHandle self.event_objectID = event_objectID self.event_childID = event_childID - super(IAccessible, self).__init__(windowHandle=windowHandle) + super().__init__(windowHandle=windowHandle) try: self.IAccessibleActionObject = IAccessibleObject.QueryInterface(IA2.IAccessibleAction) @@ -901,7 +901,7 @@ def _get_shouldAllowIAccessibleMenuStartEvent(self) -> bool: def _get_TextInfo(self): if hasattr(self, "IAccessibleTextObject"): return IA2TextTextInfo - return super(IAccessible, self).TextInfo + return super().TextInfo def _isEqual(self, other): if self.IAccessibleChildID != other.IAccessibleChildID: @@ -944,7 +944,7 @@ def _isEqual(self, other): and self.event_childID != other.event_childID ): return False - if not super(IAccessible, self)._isEqual(other): + if not super()._isEqual(other): return False selfIden = self.IAccessibleIdentity otherIden = other.IAccessibleIdentity @@ -954,7 +954,7 @@ def _isEqual(self, other): return False if self.IAccessibleRole != other.IAccessibleRole: return False - if self.name != other.name: + if self.name != other.name: # noqa: SIM103 return False return True @@ -1053,19 +1053,19 @@ def _get_IAccessibleRole(self) -> int: try: role = self.IAccessibleObject.accRole(self.IAccessibleChildID) except COMError as e: - log.debugWarning("accRole failed: %s" % e) + log.debugWarning("accRole failed: %s" % e) # noqa: UP031 role = 0 return role def _get_role(self): IARole = self.IAccessibleRole if IARole == oleacc.ROLE_SYSTEM_CLIENT: - superRole = super(IAccessible, self).role + superRole = super().role if superRole != controlTypes.Role.WINDOW: return superRole if isinstance(IARole, str): # todo: when can this be a string? IARole = IARole.split(",")[0].lower() - log.debug("IARole: %s" % IARole) + log.debug("IARole: %s" % IARole) # noqa: UP031 # must not create interdependence between role and states properties. Use IARole / IAStates. NVDARole = IAccessibleHandler.calculateNvdaRole(IARole, self.IAccessibleStates) return NVDARole @@ -1090,7 +1090,7 @@ def _get_IAccessibleStates(self) -> int: """ # C901 '_get_states' is too complex. Look for opportunities to break this method down. - def _get_states(self) -> set[controlTypes.State]: # noqa: C901 + def _get_states(self) -> set[controlTypes.State]: states = set() if self.event_objectID in (winUser.OBJID_CLIENT, winUser.OBJID_WINDOW) and self.event_childID == 0: states.update(super().states) @@ -1199,10 +1199,10 @@ def _get_location(self): return None def isPointInObject(self, x, y): - if self.windowHandle and not super(IAccessible, self).isPointInObject(x, y): + if self.windowHandle and not super().isPointInObject(x, y): return False res = IAccessibleHandler.accHitTest(self.IAccessibleObject, self.IAccessibleChildID, x, y) - if not res or res[0] != self.IAccessibleObject or res[1] != self.IAccessibleChildID: + if not res or res[0] != self.IAccessibleObject or res[1] != self.IAccessibleChildID: # noqa: SIM103 return False return True @@ -1237,12 +1237,12 @@ def _get_parent(self): event_objectID=self.event_objectID, event_childID=0, ) - or super(IAccessible, self).parent + or super().parent ) res = IAccessibleHandler.accParent(self.IAccessibleObject, self.IAccessibleChildID) if res: parentObj = IAccessible(IAccessibleObject=res[0], IAccessibleChildID=res[1]) - if parentObj: + if parentObj: # noqa: SIM102 # Hack around bad MSAA implementations that deliberately skip the window root IAccessible in the ancestry (Skype, iTunes) if ( parentObj.windowHandle != self.windowHandle @@ -1257,8 +1257,8 @@ def _get_parent(self): and windowObj.parent == parentObj ): return windowObj - return self.correctAPIForRelation(parentObj, relation="parent") or super(IAccessible, self).parent - return super(IAccessible, self).parent + return self.correctAPIForRelation(parentObj, relation="parent") or super().parent + return super().parent def _get_next(self): res = IAccessibleHandler.accNavigate( @@ -1405,7 +1405,7 @@ def _get_children(self): if identity and identity.get("objectID", None) == 0 and identity.get("childID", None) == 0: windowHandle = identity.get("windowHandle", None) if windowHandle: - kwargs = dict(windowHandle=windowHandle) + kwargs = dict(windowHandle=windowHandle) # noqa: C408 APIClass = Window.findBestAPIClass( kwargs, relation="parent", @@ -1426,7 +1426,7 @@ def getChild(self, index): child = IAccessibleHandler.accChild(self.IAccessibleObject, index + 1) if not child: if index < self.childCount: - return super(IAccessible, self).getChild(index) + return super().getChild(index) return None if child[0] == self.IAccessibleObject: return IAccessible( @@ -1442,15 +1442,15 @@ def getChild(self, index): ) #: Type definition for auto prop '_get_IA2Attributes' - IA2Attributes: typing.Dict[str, str] + IA2Attributes: dict[str, str] - def _get_IA2Attributes(self) -> typing.Dict[str, str]: + def _get_IA2Attributes(self) -> dict[str, str]: if not isinstance(self.IAccessibleObject, IA2.IAccessible2): return {} try: attribs = self.IAccessibleObject.attributes except COMError as e: - log.debugWarning("IAccessibleObject.attributes COMError %s" % e) + log.debugWarning("IAccessibleObject.attributes COMError %s" % e) # noqa: UP031 attribs = None if attribs: return IAccessibleHandler.splitIA2Attribs(attribs) @@ -1489,7 +1489,7 @@ def _get_presentationalRowNumber(self): try: index = int(index) except (ValueError, TypeError): - log.debugWarning("value %s is not an int" % index, exc_info=True) + log.debugWarning("value %s is not an int" % index, exc_info=True) # noqa: UP031 raise NotImplementedError return index @@ -1529,7 +1529,7 @@ def _get_cellCoordsText(self): colText = self.columnNumber if not rowText: rowText = self.rowNumber - return "%s %s" % (colText, rowText) + return "%s %s" % (colText, rowText) # noqa: UP031 def _get_presentationalColumnNumber(self): index = self.IA2Attributes.get("colindex") @@ -1538,7 +1538,7 @@ def _get_presentationalColumnNumber(self): try: index = int(index) except (ValueError, TypeError): - log.debugWarning("value %s is not an int" % index, exc_info=True) + log.debugWarning("value %s is not an int" % index, exc_info=True) # noqa: UP031 raise NotImplementedError return index @@ -1567,7 +1567,7 @@ def _get_presentationalRowCount(self): try: count = int(count) except (ValueError, TypeError): - log.debugWarning("value %s is not an int" % count, exc_info=True) + log.debugWarning("value %s is not an int" % count, exc_info=True) # noqa: UP031 raise NotImplementedError return count @@ -1591,7 +1591,7 @@ def _get_presentationalColumnCount(self): try: count = int(count) except (ValueError, TypeError): - log.debugWarning("value %s is not an int" % count, exc_info=True) + log.debugWarning("value %s is not an int" % count, exc_info=True) # noqa: UP031 raise NotImplementedError return count @@ -1656,7 +1656,7 @@ def _get_columnHeaderText(self): def _get_selectionContainer(self): if self.table: return self.table - return super(IAccessible, self).selectionContainer + return super().selectionContainer def _getSelectedItemsCount_accSelection(self, maxCount: int) -> int: sel = self.IAccessibleObject.accSelection @@ -1695,20 +1695,17 @@ def getSelectedItemsCount(self, maxCount=2): try: return self._getSelectedItemsCount_accSelection(maxCount) except (COMError, NotImplementedError) as e: - log.debug("Cannot fetch selected items count using accSelection, %s" % e) - pass + log.debug("Cannot fetch selected items count using accSelection, %s" % e) # noqa: UP031 if hasattr(self, "IAccessibleTable2Object"): try: return self.IAccessibleTable2Object.nSelectedCells except COMError as e: log.debug(f"Error calling IAccessibleTable2::nSelectedCells, {e}") - pass elif hasattr(self, "IAccessibleTableObject"): try: return self.IAccessibleTableObject.nSelectedChildren except COMError as e: log.debug(f"Error calling IAccessibleTable::nSelectedCells, {e}") - pass else: log.debug("No means of getting a selection count from this IAccessible") return super().getSelectedItemsCount(maxCount) @@ -1741,7 +1738,7 @@ def _get_table(self): def _get_tableID(self): table = self.table if not table: - return super(IAccessible, self).tableID + return super().tableID return (self.windowHandle, self.table.IA2UniqueID) def _get_activeChild(self): @@ -1760,7 +1757,7 @@ def _get_activeChild(self): return IAccessible(IAccessibleObject=res[0], IAccessibleChildID=res[1]) def _get_hasFocus(self): - if self.IAccessibleStates & oleacc.STATE_SYSTEM_FOCUSED: + if self.IAccessibleStates & oleacc.STATE_SYSTEM_FOCUSED: # noqa: SIM103 return True else: return False @@ -1815,7 +1812,7 @@ def _get_positionInfo(self): parent = self.parent if parent: similarItemsInGroup = parent.childCount - return dict(indexInGroup=indexInGroup, similarItemsInGroup=similarItemsInGroup) + return dict(indexInGroup=indexInGroup, similarItemsInGroup=similarItemsInGroup) # noqa: C408 return {} def _get_indexInParent(self): @@ -1827,13 +1824,13 @@ def _get_indexInParent(self): raise NotImplementedError #: Type definition for auto prop '_get__IA2Relations' - _IA2Relations: typing.List[IA2.IAccessibleRelation] + _IA2Relations: list[IA2.IAccessibleRelation] - def _get__IA2Relations(self) -> typing.List[IA2.IAccessibleRelation]: + def _get__IA2Relations(self) -> list[IA2.IAccessibleRelation]: if not isinstance(self.IAccessibleObject, IA2.IAccessible2): log.debug("Not an IA2.IAccessible2") raise NotImplementedError - import ctypes + import ctypes # noqa: I001 import comtypes.hresult try: @@ -1842,7 +1839,7 @@ def _get__IA2Relations(self) -> typing.List[IA2.IAccessibleRelation]: log.debug("Unable to get nRelations") raise NotImplementedError if size <= 0: - return list() + return list() # noqa: C408 relations = (ctypes.POINTER(IA2.IAccessibleRelation) * size)() count = ctypes.c_int() # The client allocated relations array is an [out] parameter instead of [in, out], so we need to use the raw COM method. @@ -1856,7 +1853,7 @@ def _getIA2TargetsForRelationsOfType( self, relationType: "IAccessibleHandler.RelationType", maxRelations: int = 1, - ) -> Generator[IUnknown, None, None]: + ) -> Generator[IUnknown]: """Gets the target IAccessible (actually IUnknown; use QueryInterface or normalizeIAccessible to resolve) for the relations with given type. Allows escape of exception: COMError(-2147417836, 'Requested object does not exist.'), @@ -1927,12 +1924,11 @@ def _getIA2RelationFirstTarget( ) except (NotImplementedError, COMError): log.debug("Unable to fetch _IA2Relations", exc_info=True) - pass return None def _getIA2RelationTargetsOfType( self, - relationType: Union[str, IAccessibleHandler.RelationType], + relationType: str | IAccessibleHandler.RelationType, ) -> typing.Iterable["IAccessible"]: """Get the targets for the relation of type. Higher level function than _getIA2TargetsForRelationsOfType @@ -1970,7 +1966,7 @@ def _getIA2RelationTargetsOfType( for relation in self._IA2Relations: if relation.relationType == relationType: # Take the first of 'relation.nTargets' see IAccessibleRelation._methods_ - for i in range(0, relation.nTargets): + for i in range(relation.nTargets): target = relation.target(i) ia2Object = IAccessibleHandler.normalizeIAccessible(target) yield IAccessible( @@ -1980,13 +1976,12 @@ def _getIA2RelationTargetsOfType( return except (NotImplementedError, COMError): log.debug("Unable to fetch _IA2Relations", exc_info=True) - pass return None #: Type definition for auto prop '_get_detailsRelations' - detailsRelations: Tuple["IAccessible"] + detailsRelations: tuple["IAccessible"] - def _get_detailsRelations(self) -> Tuple["IAccessible"]: + def _get_detailsRelations(self) -> tuple["IAccessible"]: detailsRelsGen = self._getIA2RelationTargetsOfType(IAccessibleHandler.RelationType.DETAILS) # due to caching of baseObject.AutoPropertyObject, do not attempt to return a generator. return tuple(detailsRelsGen) @@ -2025,7 +2020,7 @@ def event_valueChange(self): if isinstance(self, EditableTextWithAutoSelectDetection): self.hasContentChangedSinceLastSelection = True return - return super(IAccessible, self).event_valueChange() + return super().event_valueChange() def event_alert(self) -> None: if self.role != controlTypes.Role.ALERT: @@ -2079,14 +2074,14 @@ def event_caret(self): # This object is part of the focused compound text editor, so notify it. focus.event_caret() return - super(IAccessible, self).event_caret() + super().event_caret() def _get_groupName(self): return None if self.IAccessibleChildID > 0: return None else: - return super(IAccessible, self)._get_groupName() + return super()._get_groupName() def event_selectionAdd(self): return self.event_stateChange() @@ -2108,24 +2103,24 @@ def _get_isPresentableFocusAncestor(self): and self.windowStyle & winUser.WS_SYSMENU ): return True - return super(IAccessible, self).isPresentableFocusAncestor + return super().isPresentableFocusAncestor def _get_devInfo(self): - info = super(IAccessible, self).devInfo + info = super().devInfo iaObj = self.IAccessibleObject - info.append("IAccessibleObject: %r" % iaObj) + info.append("IAccessibleObject: %r" % iaObj) # noqa: UP031 childID = self.IAccessibleChildID - info.append("IAccessibleChildID: %r" % childID) + info.append("IAccessibleChildID: %r" % childID) # noqa: UP031 info.append( - "IAccessible event parameters: windowHandle=%r, objectID=%r, childID=%r" + "IAccessible event parameters: windowHandle=%r, objectID=%r, childID=%r" # noqa: UP031 % (self.event_windowHandle, self.event_objectID, self.event_childID), ) formatLong = self._formatLongDevInfoString try: ret = formatLong(iaObj.accName(childID)) - except Exception as e: - ret = "exception: %s" % e - info.append("IAccessible accName: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "exception: %s" % e # noqa: UP031 + info.append("IAccessible accName: %s" % ret) # noqa: UP031 try: ret = iaObj.accRole(childID) for name, const in oleacc.__dict__.items(): @@ -2136,9 +2131,9 @@ def _get_devInfo(self): break else: ret = repr(ret) - except Exception as e: - ret = "exception: %s" % e - info.append("IAccessible accRole: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "exception: %s" % e # noqa: UP031 + info.append("IAccessible accRole: %s" % ret) # noqa: UP031 try: temp = iaObj.accState(childID) ret = ( @@ -2147,32 +2142,32 @@ def _get_devInfo(self): for name, const in oleacc.__dict__.items() if name.startswith("STATE_") and temp & const ) - + " (%d)" % temp + + " (%d)" % temp # noqa: UP031 ) - except Exception as e: - ret = "exception: %s" % e - info.append("IAccessible accState: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "exception: %s" % e # noqa: UP031 + info.append("IAccessible accState: %s" % ret) # noqa: UP031 try: ret = formatLong(iaObj.accDescription(childID)) - except Exception as e: - ret = "exception: %s" % e - info.append("IAccessible accDescription: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "exception: %s" % e # noqa: UP031 + info.append("IAccessible accDescription: %s" % ret) # noqa: UP031 try: ret = formatLong(iaObj.accValue(childID)) - except Exception as e: - ret = "exception: %s" % e - info.append("IAccessible accValue: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "exception: %s" % e # noqa: UP031 + info.append("IAccessible accValue: %s" % ret) # noqa: UP031 if isinstance(iaObj, IA2.IAccessible2): try: ret = iaObj.windowHandle - except Exception as e: - ret = "exception: %s" % e - info.append("IAccessible2 windowHandle: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "exception: %s" % e # noqa: UP031 + info.append("IAccessible2 windowHandle: %s" % ret) # noqa: UP031 try: ret = iaObj.uniqueID - except Exception as e: - ret = "exception: %s" % e - info.append("IAccessible2 uniqueID: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "exception: %s" % e # noqa: UP031 + info.append("IAccessible2 uniqueID: %s" % ret) # noqa: UP031 try: ret = iaObj.role() for name, const in itertools.chain(oleacc.__dict__.items(), IA2.__dict__.items()): @@ -2183,9 +2178,9 @@ def _get_devInfo(self): break else: ret = repr(ret) - except Exception as e: - ret = "exception: %s" % e - info.append("IAccessible2 role: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "exception: %s" % e # noqa: UP031 + info.append("IAccessible2 role: %s" % ret) # noqa: UP031 try: temp = iaObj.states ret = ( @@ -2194,19 +2189,19 @@ def _get_devInfo(self): for name, const in IA2.__dict__.items() if name.startswith("IA2_STATE_") and temp & const ) - + " (%d)" % temp + + " (%d)" % temp # noqa: UP031 ) - except Exception as e: - ret = "exception: %s" % e - info.append("IAccessible2 states: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "exception: %s" % e # noqa: UP031 + info.append("IAccessible2 states: %s" % ret) # noqa: UP031 try: ret = repr(iaObj.attributes) - except Exception as e: - ret = "exception: %s" % e - info.append("IAccessible2 attributes: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "exception: %s" % e # noqa: UP031 + info.append("IAccessible2 attributes: %s" % ret) # noqa: UP031 try: ret = ", ".join(f"{r.RelationType} * {r.nTargets}" for r in self._IA2Relations) - except Exception as e: + except Exception as e: # noqa: BLE001 ret = f"exception: {e}" info.append(f"IAccessible2 relations: {ret}") return info @@ -2217,7 +2212,7 @@ def _get_language(self): except (AttributeError, COMError): return None if ia2Locale.language and ia2Locale.country: - return "%s_%s" % (ia2Locale.language, ia2Locale.country) + return "%s_%s" % (ia2Locale.language, ia2Locale.country) # noqa: UP031 elif ia2Locale.language: return ia2Locale.language return None @@ -2233,7 +2228,7 @@ def _get_IA2WindowHandle(self): try: window = self.IAccessibleObject.windowHandle except COMError as e: - log.debugWarning("IAccessible2::windowHandle failed: %s" % e) + log.debugWarning("IAccessible2::windowHandle failed: %s" % e) # noqa: UP031 self.IA2WindowHandle = window # Cache forever. return window @@ -2299,7 +2294,7 @@ def _get_value(self): val = self.displayText truncate = len(val) > 200 if truncate: - return "%s\u2026" % val[:200] + return "%s\u2026" % val[:200] # noqa: UP031 return val @@ -2330,7 +2325,7 @@ def _get_presentationType(self): def _get_parent(self): if self.parentUsesSuperOnWindowRootIAccessible: return super(IAccessible, self).parent - return super(WindowRoot, self).parent + return super().parent def _get_next(self): return super(IAccessible, self).next @@ -2343,7 +2338,7 @@ def _get_container(self): groupboxObj = IAccessibleHandler.findGroupboxObject(self) if groupboxObj: return groupboxObj - return super(WindowRoot, self).container + return super().container class ShellDocObjectView(IAccessible): @@ -2399,13 +2394,13 @@ def _get_description(self): nextNext = self._getNextSkipWindows(next) if nextNext and nextNext.name != next.name: return next.name - return super(Groupbox, self).description + return super().description def _get_isPresentableFocusAncestor(self): # Only fetch this the first time it is requested, # as it is a bit slow due to the description property # and the answer shouldn't change anyway. - self.isPresentableFocusAncestor = res = super(Groupbox, self).isPresentableFocusAncestor + self.isPresentableFocusAncestor = res = super().isPresentableFocusAncestor return res @@ -2421,19 +2416,19 @@ class TrayClockWClass(IAccessible): def _get_role(self): # On Windows 10 Anniversary update and later the text 'clock' is included in the name so having clock in the control type is redundant. - if super(TrayClockWClass, self).value is None: + if super().value is None: return controlTypes.Role.BUTTON return controlTypes.Role.CLOCK def _get_name(self): # #4364 On some versions of Windows name contains redundant information that is available either in the role or the value, however on Windows 10 Anniversary Update and later the value is empty, so we cannot simply dismiss the name. - if super(TrayClockWClass, self).value is None: - clockName = super(TrayClockWClass, self).name + if super().value is None: + clockName = super().name return clockName.replace(CHAR_LTR_MARK, "").replace(CHAR_RTL_MARK, "") return None def _get_value(self): - clockValue = super(TrayClockWClass, self).value + clockValue = super().value if clockValue is not None: clockValue = clockValue.replace(CHAR_LTR_MARK, "").replace(CHAR_RTL_MARK, "") return clockValue @@ -2441,7 +2436,7 @@ def _get_value(self): class OutlineItem(IAccessible): def _get_value(self): - val = super(OutlineItem, self)._get_value() + val = super()._get_value() try: int(val) except (ValueError, TypeError): @@ -2466,13 +2461,13 @@ def reportFocus(self): def _get_role(self): if self.childCount == 0: return controlTypes.Role.LINK - return super(SysLinkClient, self).role + return super().role class SysLink(IAccessible): def _get_name(self): # Workaround for #451 - explorer returns incorrect string length, thus it can contain garbage characters - name = super(SysLink, self).name + name = super().name if name: # Remove any data after the null character i = name.find("\0") @@ -2489,7 +2484,7 @@ def event_gainFocus(self): if self.childCount == 0: # However, in Windows 7, the task list gets focus even if alt+tab is pressed with no applications open. # In this case, we must report the focus so the user knows where the focus has landed. - return super(TaskList, self).event_gainFocus() + return super().event_gainFocus() class TaskListIcon(IAccessible): @@ -2501,7 +2496,7 @@ def _get_role(self): def reportFocus(self): if controlTypes.State.INVISIBLE in self.states: return - super(TaskListIcon, self).reportFocus() + super().reportFocus() #: Window message asking a popup menu window for the handle of the menu it displays, @@ -2716,19 +2711,19 @@ def _get_location(self) -> RectLTWH | None: def _get_description(self): name = self.name - description = super(MenuItem, self)._get_description() + description = super()._get_description() if description != name: return description else: return None def _get_name(self): - return super(MenuItem, self).name or self.displayText + return super().name or self.displayText def event_gainFocus(self): if eventHandler.isPendingEvents("gainFocus"): return - super(MenuItem, self).event_gainFocus() + super().event_gainFocus() class Taskbar(IAccessible): @@ -2744,7 +2739,7 @@ def event_gainFocus(self): class Button(IAccessible): def _get_name(self): - name = super(Button, self).name + name = super().name if not name or name.isspace(): name = self.displayText return name @@ -2774,7 +2769,7 @@ class StaticText(IAccessible): """Support for owner-drawn staticText controls where accName is empty.""" def _get_name(self): - name = super(StaticText, self).name + name = super().name if not name or name.isspace(): name = self.displayText return name diff --git a/source/NVDAObjects/IAccessible/adobeAcrobat.py b/source/NVDAObjects/IAccessible/adobeAcrobat.py index 631fc365543..1a5b81fd171 100644 --- a/source/NVDAObjects/IAccessible/adobeAcrobat.py +++ b/source/NVDAObjects/IAccessible/adobeAcrobat.py @@ -3,9 +3,8 @@ # Copyright (C) 2008-2014 NV Access Limited # This file is covered by the GNU General Public License. # See the file COPYING for more details. -import typing -import api +import api # noqa: I001 import controlTypes import eventHandler import winUser @@ -41,7 +40,7 @@ } -def normalizeStdName(stdName: str) -> typing.Tuple[controlTypes.Role, typing.Optional[str]]: +def normalizeStdName(stdName: str) -> tuple[controlTypes.Role, str | None]: """ @param stdName: @return: Tuple with the NVDA role and optionally the level number of the heading as a string, E.G.: @@ -103,7 +102,7 @@ def _get_role(self): except (AttributeError, LookupError, COMError): pass - role = super(AcrobatNode, self).role + role = super().role if role == controlTypes.Role.PANE: # Pane doesn't make sense for nodes in a document. role = controlTypes.Role.TEXTFRAME @@ -118,7 +117,7 @@ def scrollIntoView(self): def _isEqual(self, other): if self.windowHandle == other.windowHandle and self.accID and other.accID: return self.accID == other.accID - return super(AcrobatNode, self)._isEqual(other) + return super()._isEqual(other) @staticmethod def getMathMLAttributes(node: IPDDomElement, attrList: list) -> str: @@ -267,7 +266,7 @@ def _get_shouldAllowIAccessibleFocusEvent(self): return self.IAccessibleObject.accFocus in (None, 0) except COMError: pass - return super(Document, self).shouldAllowIAccessibleFocusEvent + return super().shouldAllowIAccessibleFocusEvent class RootTextNode(RootNode): @@ -322,7 +321,7 @@ class BadFocusStates(AcrobatNode): """An object which reports focus states when it shouldn't.""" def _get_states(self): - states = super(BadFocusStates, self).states + states = super().states states.difference_update({controlTypes.State.FOCUSABLE, controlTypes.State.FOCUSED}) return states diff --git a/source/NVDAObjects/IAccessible/chromium.py b/source/NVDAObjects/IAccessible/chromium.py index 0ad8eb53ad8..5173ef2d511 100644 --- a/source/NVDAObjects/IAccessible/chromium.py +++ b/source/NVDAObjects/IAccessible/chromium.py @@ -5,8 +5,7 @@ """NVDAObjects for the Chromium browser project""" -import typing -from typing import Dict, Optional +import typing # noqa: I001 from comtypes import COMError import config @@ -19,9 +18,9 @@ if typing.TYPE_CHECKING: # F401 imported but unused, actually used as a string within type annotation (to avoid having to import # at run time) - from treeInterceptorHandler import TreeInterceptor # noqa: F401 + from treeInterceptorHandler import TreeInterceptor -supportedAriaDetailsRoles: Dict[str, Optional[controlTypes.Role]] = { +supportedAriaDetailsRoles: dict[str, controlTypes.Role | None] = { "unknown": None, # no explicit role, should be reported as "details" "comment": controlTypes.Role.COMMENT, "doc-footnote": controlTypes.Role.FOOTNOTE, @@ -97,7 +96,7 @@ def __contains__(self, obj): class Document(ia2Web.Document): - def _get_treeInterceptorClass(self) -> typing.Type["TreeInterceptor"]: + def _get_treeInterceptorClass(self) -> type["TreeInterceptor"]: shouldLoadVBufOnBusyFeatureFlag = bool( config.conf["virtualBuffers"]["loadChromiumVBufOnBusyState"], ) diff --git a/source/NVDAObjects/IAccessible/delphi.py b/source/NVDAObjects/IAccessible/delphi.py index a0f8f8414ba..b1013773828 100644 --- a/source/NVDAObjects/IAccessible/delphi.py +++ b/source/NVDAObjects/IAccessible/delphi.py @@ -1,4 +1,4 @@ -from NVDAObjects import behaviors +from NVDAObjects import behaviors # noqa: I001 import controlTypes from . import IAccessible diff --git a/source/NVDAObjects/IAccessible/hh.py b/source/NVDAObjects/IAccessible/hh.py index 787a187a7b8..d91cb44e4c2 100644 --- a/source/NVDAObjects/IAccessible/hh.py +++ b/source/NVDAObjects/IAccessible/hh.py @@ -6,7 +6,7 @@ """NVDAObjects for Microsoft HTML Help.""" -import IAccessibleHandler +import IAccessibleHandler # noqa: I001 from . import IAccessible @@ -51,4 +51,4 @@ def event_gainFocus(self): # We do this at the IAccessibleHandler level so that duplicate focus event checks will work properly. IAccessibleHandler.processFocusNVDAEvent(child) else: - super(KeywordList, self).event_gainFocus() + super().event_gainFocus() diff --git a/source/NVDAObjects/IAccessible/ia2TextMozilla.py b/source/NVDAObjects/IAccessible/ia2TextMozilla.py index 0d485c7017f..af8ab8b77d3 100644 --- a/source/NVDAObjects/IAccessible/ia2TextMozilla.py +++ b/source/NVDAObjects/IAccessible/ia2TextMozilla.py @@ -7,14 +7,7 @@ This is now used by other applications as well. """ -import typing -from typing import ( - Optional, - Dict, - Type, -) - -from comtypes import COMError +from comtypes import COMError # noqa: I001 import winUser import textInfos from textInfos import offsets @@ -28,13 +21,13 @@ from logHandler import log -def _getRawTextInfo(obj) -> Type[offsets.OffsetsTextInfo]: +def _getRawTextInfo(obj) -> type[offsets.OffsetsTextInfo]: if obj.TextInfo is NVDAObjectTextInfo: return NVDAObjectTextInfo return IA2TextTextInfo -def _getEmbedded(obj, offset) -> typing.Optional[IAccessible]: +def _getEmbedded(obj, offset) -> IAccessible | None: if not hasattr(obj, "IAccessibleTextObject"): return obj.getChild(offset) # Mozilla uses IAccessibleHypertext to facilitate quick retrieval of embedded objects. @@ -80,7 +73,7 @@ def _isCaretAtEndOfLine(self, caretObj: IAccessible) -> bool: # support IA2_TEXT_OFFSET_CARET to take this into account. Use this to # determine whether we are at this position. try: - start, end, text = caretObj.IAccessibleTextObject.textAtOffset( + start, end, text = caretObj.IAccessibleTextObject.textAtOffset( # noqa: RUF059 IA2.IA2_TEXT_OFFSET_CARET, IA2.IA2_TEXT_BOUNDARY_CHAR, ) @@ -93,7 +86,7 @@ def _isCaretAtEndOfLine(self, caretObj: IAccessible) -> bool: # It's also possible that this is an empty last line, in which case any # adjustment would cause us to report the previous line instead of the empty # one. Either way, we don't need the special end of line adjustment. - if start > 0 and start == caretObj.IAccessibleTextObject.nCharacters: + if start > 0 and start == caretObj.IAccessibleTextObject.nCharacters: # noqa: SIM103 return False return True except COMError: @@ -104,7 +97,7 @@ def _isCaretAtEndOfLine(self, caretObj: IAccessible) -> bool: return False def __init__(self, obj, position): - super(MozillaCompoundTextInfo, self).__init__(obj, position) + super().__init__(obj, position) # #3156: The position when the caret is at the end of a wrapped line (e.g. # when you press the end key) has the same offset as the start of the next # line. We need to handle this specially so that the correct units are @@ -121,7 +114,7 @@ def __init__(self, obj, position): except LookupError: # This might be an embedded object that doesn't support text such as a graphic. if position not in obj: - raise ValueError("Object %s not in document" % position) + raise ValueError("Object %s not in document" % position) # noqa: UP031 # Use the point where this is embedded. self._start = self._end = self._getEmbedding(position) self._startObj = self._endObj = self._start.obj @@ -254,14 +247,14 @@ def _getEmbedding(self, obj): POSITION_SELECTION_START = 3 POSITION_SELECTION_END = 4 - FINDCONTENTDESCENDANT_POSITIONS = { + FINDCONTENTDESCENDANT_POSITIONS = { # noqa: RUF012 textInfos.POSITION_FIRST: 0, textInfos.POSITION_CARET: 1, textInfos.POSITION_LAST: 2, } def _findContentDescendant(self, obj, position): - import ctypes + import ctypes # noqa: I001 import NVDAHelper import NVDAObjects.IAccessible @@ -294,7 +287,7 @@ def _findContentDescendant(self, obj, position): winUser.OBJID_CLIENT, descendantID.value, ) - if position == textInfos.POSITION_CARET: + if position == textInfos.POSITION_CARET: # noqa: SIM102 # If the compound TextInfo is for the current focus, # We should cache the caret object as we know it will probably be needed again. # Note that event_loseFocus on NVDAObjects.IAccessible.ia2Web.Editor will clear the cache, @@ -319,7 +312,7 @@ def _iterRecursiveText(self, ti: offsets.OffsetsTextInfo, controlStack, formatCo elif isinstance(item, str): yield item elif isinstance(item, int): # Embedded object. - embedded: typing.Optional[IAccessible] = _getEmbedded(ti.obj, item) + embedded: IAccessible | None = _getEmbedded(ti.obj, item) if embedded is None: continue notText = _getRawTextInfo(embedded) is NVDAObjectTextInfo @@ -453,7 +446,7 @@ def _getText(self, withFields, formatConfig=None): def _get_text(self): return "".join(self._getText(False)) - def getTextWithFields(self, formatConfig: Optional[Dict] = None) -> textInfos.TextInfo.TextWithFieldsT: + def getTextWithFields(self, formatConfig: dict | None = None) -> textInfos.TextInfo.TextWithFieldsT: return self._getText(True, formatConfig) def _adjustIfEndOfLine( @@ -631,7 +624,7 @@ def _findNextContent(self, origin, moveBack=False, limitToInline=False): if obj == self.obj: # We're at the root. Don't go any further. raise LookupError - if limitToInline: + if limitToInline: # noqa: SIM102 if obj.IA2Attributes.get("display") != "inline": # The caller requested to limit to inline objects. # As this container is not inline, diff --git a/source/NVDAObjects/IAccessible/ia2Web.py b/source/NVDAObjects/IAccessible/ia2Web.py index e840615deca..f0172ed712b 100644 --- a/source/NVDAObjects/IAccessible/ia2Web.py +++ b/source/NVDAObjects/IAccessible/ia2Web.py @@ -5,12 +5,10 @@ """Base classes with common support for browsers exposing IAccessible2.""" -from typing import ( - Generator, - Optional, +from typing import ( # noqa: I001 TYPE_CHECKING, - Tuple, ) +from collections.abc import Generator import re from ctypes import c_short from comtypes import COMError, BSTR @@ -67,7 +65,7 @@ def __bool__(self) -> bool: ) @property - def targets(self) -> Tuple[AnnotationTarget]: + def targets(self) -> tuple[AnnotationTarget]: if not bool(self): # optimisation that avoids having to fetch details relations which may be a more costly procedure. if config.conf["debugLog"]["annotations"]: @@ -81,7 +79,7 @@ def roles(self) -> _AnnotationRolesT: return tuple(self._rolesGenerator) @property - def _rolesGenerator(self) -> Generator[Optional[controlTypes.Role], None, None]: + def _rolesGenerator(self) -> Generator[controlTypes.Role | None]: """ Since Chromium exposes the roles via the "details-roles" IA2Attributes, an optimisation can be used to return them. @@ -103,7 +101,7 @@ def _rolesGenerator(self) -> Generator[Optional[controlTypes.Role], None, None]: # Created supported details role detailsRole = supportedAriaDetailsRoles.get(roleStr) if config.conf["debugLog"]["annotations"]: - log.debug(f"detailsRole: {repr(detailsRole)}") + log.debug(f"detailsRole: {detailsRole!r}") yield detailsRole @@ -125,7 +123,7 @@ def isDescendantOf(self, obj: "NVDAObjects.NVDAObject") -> bool: return bool(res) def _get_positionInfo(self): - info = super(Ia2Web, self).positionInfo + info = super().positionInfo level = info.get("level", None) if not level: level = self.IA2Attributes.get("level", None) @@ -134,7 +132,7 @@ def _get_positionInfo(self): return info def _get_descriptionFrom(self) -> controlTypes.DescriptionFrom: - ia2attrDescriptionFrom: Optional[str] = self.IA2Attributes.get("description-from") + ia2attrDescriptionFrom: str | None = self.IA2Attributes.get("description-from") try: return controlTypes.DescriptionFrom(ia2attrDescriptionFrom) except ValueError: @@ -150,7 +148,7 @@ def _get_annotations(self) -> "AnnotationOrigin": annotationOrigin = IA2WebAnnotation(self) return annotationOrigin - def _get_detailsSummary(self) -> Optional[str]: + def _get_detailsSummary(self) -> str | None: log.warning( "NVDAObject.detailsSummary is deprecated. Use NVDAObject.annotations instead.", stack_info=True, @@ -166,7 +164,7 @@ def hasDetails(self) -> bool: ) return bool(self.annotations) - def _get_detailsRole(self) -> Optional[controlTypes.Role]: + def _get_detailsRole(self) -> controlTypes.Role | None: log.warning( "NVDAObject.detailsRole is deprecated. Use NVDAObject.annotations instead.", stack_info=True, @@ -191,7 +189,7 @@ def _get_isPresentableFocusAncestor(self): # It is not useful to present IAccessible2 table rows in the focus ancestry as cells contain row and column information anyway. # Also presenting the rows would cause duplication of information return False - return super(Ia2Web, self).isPresentableFocusAncestor + return super().isPresentableFocusAncestor def _get_roleText(self): roleText = self.IA2Attributes.get("roledescription") @@ -206,7 +204,7 @@ def _get_roleTextBraille(self) -> str: return super().roleTextBraille def _get_states(self): - states = super(Ia2Web, self).states + states = super().states # Ensure that ARIA gridcells always get the focusable state, even if the Browser fails to provide it. # This is necessary for other code that calculates how selection of cells should be spoken. if "gridcell" in self.IA2Attributes.get("xml-roles", "").split(" "): @@ -252,8 +250,8 @@ def _get_liveRegionPoliteness(self) -> aria.AriaLivePoliteness: try: return aria.AriaLivePoliteness(politeness.lower()) except ValueError: - log.error(f"Unknown live politeness of {politeness}", exc_info=True) - super().liveRegionPoliteness + log.error(f"Unknown live politeness of {politeness}", exc_info=True) # noqa: G201 + super().liveRegionPoliteness # noqa: B018 class Document(Ia2Web): @@ -367,8 +365,8 @@ def _getMathNodeInfoByPath(self) -> dict["MathMlNodePath", "MathMlNodeRectInfo"] # Avoid importing mathPres at startup. from mathPres._mathMlNode import MathMlNodeRectInfo - nodeInfoByPath: dict["MathMlNodePath", "MathMlNodeRectInfo"] = {} - stack: list[tuple[IAccessible, "MathMlNodePath"]] = [ + nodeInfoByPath: dict[MathMlNodePath, MathMlNodeRectInfo] = {} + stack: list[tuple[IAccessible, MathMlNodePath]] = [ (self._getMathNodeMapRoot(), ()), ] visitedCount = 0 @@ -424,7 +422,7 @@ def _get_mathMl(self): if self.IA2Attributes.get("tag") != "math": # Could be a (etc) that has role = math -- check the child # If there is a single child, recurse on the assumption that is what was the intended math - mathObjs: list["NVDAObjects.NVDAObject"] = [ + mathObjs: list[NVDAObjects.NVDAObject] = [ child for child in self.children if child.IA2Attributes.get("tag") == "math" ] if len(mathObjs) == 1: @@ -432,10 +430,10 @@ def _get_mathMl(self): # This isn't MathML raise LookupError if self.language: - attrs = ' xml:lang="%s"' % self.language + attrs = ' xml:lang="%s"' % self.language # noqa: UP031 else: attrs = "" - return "%s" % (attrs, node.innerHTML) + return "%s" % (attrs, node.innerHTML) # noqa: UP031 except COMError: log.debugWarning( "Error retrieving math. " @@ -525,7 +523,7 @@ def findExtraOverlayClasses(obj, clsList, baseClass=Ia2Web, documentClass=None): else: clsList.append(EditorChunk) - if iaRole in (oleacc.ROLE_SYSTEM_DIALOG, oleacc.ROLE_SYSTEM_PROPERTYPAGE): + if iaRole in (oleacc.ROLE_SYSTEM_DIALOG, oleacc.ROLE_SYSTEM_PROPERTYPAGE): # noqa: SIM102 if "dialog" in xmlRoles or "tabpanel" in xmlRoles: # #2390: Don't try to calculate text for ARIA dialogs. # #4638: Don't try to calculate text for ARIA tab panels. diff --git a/source/NVDAObjects/IAccessible/mozilla.py b/source/NVDAObjects/IAccessible/mozilla.py index 35d3953bede..7fde350c2fd 100755 --- a/source/NVDAObjects/IAccessible/mozilla.py +++ b/source/NVDAObjects/IAccessible/mozilla.py @@ -4,11 +4,7 @@ # See the file COPYING for more details. # Copyright (C) 2006-2022 NV Access Limited, Peter Vágner -from typing import ( - Generator, - Optional, - Tuple, -) +from collections.abc import Generator # noqa: I001 from annotation import ( _AnnotationRolesT, @@ -36,7 +32,7 @@ def summary(self) -> str: return self._target.summarizeInProcess() @property - def role(self) -> Optional[controlTypes.Role]: + def role(self) -> controlTypes.Role | None: # details-roles is currently only defined in Chromium # this may diverge in Firefox in the future. from .chromium import supportedAriaDetailsRoles @@ -46,7 +42,7 @@ def role(self) -> Optional[controlTypes.Role]: ) # return a supported details role if config.conf["debugLog"]["annotations"]: - log.debug(f"detailsRole: {repr(detailsRole)}") + log.debug(f"detailsRole: {detailsRole!r}") if detailsRole in supportedAriaDetailsRoles.values(): return detailsRole @@ -75,7 +71,7 @@ def __bool__(self) -> bool: ) @property - def targets(self) -> Tuple[MozAnnotationTarget]: + def targets(self) -> tuple[MozAnnotationTarget]: return tuple(MozAnnotationTarget(rel) for rel in self._originObj.detailsRelations) @property @@ -83,7 +79,7 @@ def roles(self) -> _AnnotationRolesT: return tuple(self._rolesGenerator) @property - def _rolesGenerator(self) -> Generator[Optional[controlTypes.Role], None, None]: + def _rolesGenerator(self) -> Generator[controlTypes.Role | None]: # Unlike base Ia2Web implementation, the details-roles # IA2 attribute is not exposed in Firefox. # Although slower, we have to fetch the details relations instead. @@ -91,12 +87,12 @@ def _rolesGenerator(self) -> Generator[Optional[controlTypes.Role], None, None]: try: yield target.role except ValueError: - log.error("Error getting role.", exc_info=True) + log.error("Error getting role.", exc_info=True) # noqa: G201 class Mozilla(ia2Web.Ia2Web): def _get_states(self): - states = super(Mozilla, self).states + states = super().states if self.IAccessibleStates & oleacc.STATE_SYSTEM_MARQUEED: states.add(controlTypes.State.CHECKABLE) return states @@ -129,11 +125,14 @@ def _get_descriptionFrom(self) -> controlTypes.DescriptionFrom: return controlTypes.DescriptionFrom.ARIA_DESCRIPTION def _get_presentationType(self): - presType = super(Mozilla, self).presentationType - if presType == self.presType_content: - if self.role == controlTypes.Role.TABLE and self.IA2Attributes.get("layout-guess") == "true": - presType = self.presType_layout - elif self.table and self.table.presentationType == self.presType_layout: + presType = super().presentationType + if presType == self.presType_content: # noqa: SIM102 + if ( + self.role == controlTypes.Role.TABLE + and self.IA2Attributes.get("layout-guess") == "true" + or self.table + and self.table.presentationType == self.presType_layout + ): presType = self.presType_layout return presType @@ -145,7 +144,7 @@ def _get_annotations(self) -> MozAnnotation: annotationOrigin = MozAnnotation(self) return annotationOrigin - def _get_detailsSummary(self) -> Optional[str]: + def _get_detailsSummary(self) -> str | None: log.warning( "NVDAObject.detailsSummary is deprecated. Use NVDAObject.annotations instead.", stack_info=True, @@ -153,7 +152,7 @@ def _get_detailsSummary(self) -> Optional[str]: # just take the first for now. return self.annotations.targets[0].summary - def _get_detailsRole(self) -> Optional[controlTypes.Role]: + def _get_detailsRole(self) -> controlTypes.Role | None: log.warning( "NVDAObject.detailsRole is deprecated. Use NVDAObject.annotations instead.", stack_info=True, @@ -193,7 +192,7 @@ def _get_treeInterceptorClass(self): import virtualBuffers.gecko_ia2 return virtualBuffers.gecko_ia2.Gecko_ia2 - return super(Document, self).treeInterceptorClass + return super().treeInterceptorClass class EmbeddedObject(Mozilla): @@ -203,14 +202,14 @@ def _get_shouldAllowIAccessibleFocusEvent(self): # This window doesn't have the focus, which means the embedded object's window probably already has the focus. # We don't want to override the focus event fired by the embedded object. return False - return super(EmbeddedObject, self).shouldAllowIAccessibleFocusEvent + return super().shouldAllowIAccessibleFocusEvent class GeckoPluginWindowRoot(WindowRoot): parentUsesSuperOnWindowRootIAccessible = False def _get_parent(self): - parent = super(GeckoPluginWindowRoot, self).parent + parent = super().parent if parent.IAccessibleRole == oleacc.ROLE_SYSTEM_CLIENT: # Skip the window wrapping the plugin window, # which doesn't expose a Gecko accessible in Gecko >= 11. @@ -226,7 +225,7 @@ def _get_parent(self): if controlTypes.State.OFFSCREEN not in obj.states: return obj else: - log.debugWarning("NAVRELATION_EMBEDS returned an offscreen document, name %r" % obj.name) + log.debugWarning("NAVRELATION_EMBEDS returned an offscreen document, name %r" % obj.name) # noqa: UP031 else: log.debugWarning("NAVRELATION_EMBEDS returned an invalid object") else: @@ -254,7 +253,7 @@ def findExtraOverlayClasses(obj, clsList): iaStates = obj.IAccessibleStates # Text leaves are never focusable. # Not unavailable excludes disabled editable text fields (which also aren't focusable). - if not (iaStates & oleacc.STATE_SYSTEM_FOCUSABLE or iaStates & oleacc.STATE_SYSTEM_UNAVAILABLE): + if not (iaStates & oleacc.STATE_SYSTEM_FOCUSABLE or iaStates & oleacc.STATE_SYSTEM_UNAVAILABLE): # noqa: SIM102 # This excludes a non-focusable @role="textbox". if not (obj.IA2States & IA2.IA2_STATE_EDITABLE): cls = TextLeaf @@ -263,9 +262,11 @@ def findExtraOverlayClasses(obj, clsList): if cls: clsList.append(cls) - if iaRole == oleacc.ROLE_SYSTEM_ROW: - clsList.append(RowWithFakeNavigation) - elif iaRole == oleacc.ROLE_SYSTEM_LISTITEM and hasattr(obj.parent, "IAccessibleTableObject"): + if ( + iaRole == oleacc.ROLE_SYSTEM_ROW + or iaRole == oleacc.ROLE_SYSTEM_LISTITEM + and hasattr(obj.parent, "IAccessibleTableObject") + ): clsList.append(RowWithFakeNavigation) elif iaRole == oleacc.ROLE_SYSTEM_OUTLINEITEM: # Check if the tree view is a table. diff --git a/source/NVDAObjects/IAccessible/msOffice.py b/source/NVDAObjects/IAccessible/msOffice.py index ba0bcfe05cc..1677514c6bb 100755 --- a/source/NVDAObjects/IAccessible/msOffice.py +++ b/source/NVDAObjects/IAccessible/msOffice.py @@ -4,7 +4,7 @@ # This file may be used under the terms of the GNU General Public License, version 2 or later. # For more details see: https://www.gnu.org/licenses/gpl-2.0.html -import oleacc +import oleacc # noqa: I001 import IAccessibleHandler import controlTypes import winUser @@ -22,10 +22,10 @@ def _get_shouldAllowIAccessibleFocusEvent(self): # E.g. File recovery pane, clipboard manager pane if winUser.getGUIThreadInfo(0).hwndFocus != self.windowHandle: return False - return super(SDM, self).shouldAllowIAccessibleFocusEvent + return super().shouldAllowIAccessibleFocusEvent def _get_name(self): - name = super(SDM, self).name + name = super().name if not name and self.role == controlTypes.Role.LISTITEM: name = self.displayText return name @@ -33,7 +33,7 @@ def _get_name(self): def _get_positionInfo(self): if self.role != controlTypes.Role.LISTITEM: return {} - return super(SDM, self).positionInfo + return super().positionInfo def _get_parent(self): if self.IAccessibleChildID == 0 and self.role not in ( @@ -44,22 +44,22 @@ def _get_parent(self): # SDM child IAccessible objects have a broken accParent. # The parent should be the dialog. return getNVDAObjectFromEvent(self.windowHandle, winUser.OBJID_CLIENT, 0) - return super(SDM, self).parent + return super().parent def _get_presentationType(self): - t = super(SDM, self).presentationType + t = super().presentationType if t == self.presType_content and self.SDMChild: t = self.presType_layout return t def _get_firstChild(self): - child = super(SDM, self).firstChild + child = super().firstChild if not child: child = self.SDMChild return child def _get_lastChild(self): - child = super(SDM, self).lastChild + child = super().lastChild if not child: child = self.SDMChild return child @@ -95,10 +95,10 @@ def _get_isPresentableFocusAncestor(self): # Therefore suppress reporting of these toolbars in focus ancestry if they only have one child. if self.childCount == 1: return False - return super(MsoCommandBarToolBar, self).isPresentableFocusAncestor + return super().isPresentableFocusAncestor def _get_name(self): - name = super(MsoCommandBarToolBar, self).name + name = super().name # #3407: overly verbose and programmatic toolbar label if name and name.startswith("MSO Generic Control Container"): name = "" @@ -135,7 +135,7 @@ def _get_firstChild(self): description = None def _get_name(self): - name = super(BrokenMsoCommandBar, self).name + name = super().name if name == "MSO Generic Control Container": return None return name @@ -144,10 +144,10 @@ def _get_name(self): class CommandBarListItem(IAccessible): """A list item in an MSO commandbar, that may be part of a color palet.""" - COMPILED_RE = re.compile(r"RGB\(\d+, \d+, \d+\)", re.I) + COMPILED_RE = re.compile(r"RGB\(\d+, \d+, \d+\)", re.IGNORECASE) def _get_rgbNameAndMatch(self): - name = super(CommandBarListItem, self).name + name = super().name if self.COMPILED_RE.match(name): matchRGB = True else: @@ -173,7 +173,7 @@ def _get_description(self): rgb=colors.RGB.fromString(name), ) else: - return super(CommandBarListItem, self).description + return super().description class SDMSymbols(SDM): @@ -191,7 +191,7 @@ def script_selectGraphic(self, gesture): gesture.send() eventHandler.queueEvent("valueChange", self) - __gestures = { + __gestures = { # noqa: RUF012 "kb:downArrow": "selectGraphic", "kb:upArrow": "selectGraphic", "kb:home": "selectGraphic", diff --git a/source/NVDAObjects/IAccessible/mscandui.py b/source/NVDAObjects/IAccessible/mscandui.py index 5a155d3f3fb..26521ca8616 100755 --- a/source/NVDAObjects/IAccessible/mscandui.py +++ b/source/NVDAObjects/IAccessible/mscandui.py @@ -1,4 +1,4 @@ -import oleacc +import oleacc # noqa: I001 import queueHandler import eventHandler import controlTypes @@ -39,7 +39,7 @@ class BaseCandidateItem(CandidateItemBehavior, IAccessible): keyboardShortcut = "" def _get_candidateNumber(self): - number = super(BaseCandidateItem, self).keyboardShortcut + number = super().keyboardShortcut try: number = int(number) except (ValueError, TypeError): @@ -47,7 +47,7 @@ def _get_candidateNumber(self): return number def _get_parent(self): - parent = super(BaseCandidateItem, self).parent + parent = super().parent # Translators: A label for a 'candidate' list which contains symbols the user can choose from when typing east-asian characters into a document. parent.name = _("Candidate") parent.description = None @@ -57,21 +57,21 @@ def _get_name(self): try: number = int(self.candidateNumber) except (TypeError, ValueError): - return super(BaseCandidateItem, self).name - candidate = super(BaseCandidateItem, self).name + return super().name + candidate = super().name return self.getFormattedCandidateName(number, candidate) def _get_description(self): - candidate = super(BaseCandidateItem, self).name + candidate = super().name return self.getFormattedCandidateDescription(candidate) def _get_basicText(self): - return super(BaseCandidateItem, self).name + return super().name class MSCandUI_candidateListItem(BaseCandidateItem): def _get_states(self): - states = super(MSCandUI_candidateListItem, self).states + states = super().states states.add(controlTypes.State.SELECTABLE) return states @@ -82,7 +82,7 @@ def event_stateChange(self): class MSCandUI21_candidateMenuItem(BaseCandidateItem): def _get_previous(self): - item = super(MSCandUI21_candidateMenuItem, self).previous + item = super().previous if not item or controlTypes.State.INVISIBLE in item.states: return return MSCandUI21_candidateMenuItem( @@ -91,7 +91,7 @@ def _get_previous(self): ) def _get_next(self): - item = super(MSCandUI21_candidateMenuItem, self).next + item = super().next if not item or controlTypes.State.INVISIBLE in item.states: return return MSCandUI21_candidateMenuItem( @@ -101,7 +101,7 @@ def _get_next(self): def doAction(self, index=None): if not index: - l = self.location # noqa: E741 + l = self.location if l: x = l[0] y = l[1] @@ -148,7 +148,7 @@ def script_activate(self, gesture): if oldItem and isinstance(oldItem.candidateNumber, int) and oldItem.name: reportSelectedCandidate(oldItem, allowDuplicate=True, newList=True) - __gestures = { + __gestures = { # noqa: RUF012 "kb:downArrow": "nextItem", "kb:upArrow": "previousItem", "kb:pageDown": "changePage", @@ -196,7 +196,7 @@ def _get_isValidCandidate(self): if self.IAccessibleRole != oleacc.ROLE_SYSTEM_LISTITEM: return False name = super(BaseCandidateItem, self).name - if not name: + if not name: # noqa: SIM103 return False return True @@ -225,7 +225,7 @@ class MSCandUIWindow(IAccessible): role = controlTypes.Role.LIST def _get_states(self): - states = super(MSCandUIWindow, self).states + states = super().states states.discard(controlTypes.State.UNAVAILABLE) return states @@ -253,7 +253,7 @@ def _get_candidateCharacters(self): def refreshCandidateList(self): textList = [] - candidateItems = super(ModernCandidateUICandidateItem, self).parent.children + candidateItems = super().parent.children for child in candidateItems: if ( not isinstance(child, ModernCandidateUICandidateItem) diff --git a/source/NVDAObjects/IAccessible/qt.py b/source/NVDAObjects/IAccessible/qt.py index 6d66a6b3019..a97156669a4 100644 --- a/source/NVDAObjects/IAccessible/qt.py +++ b/source/NVDAObjects/IAccessible/qt.py @@ -4,7 +4,7 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -import controlTypes +import controlTypes # noqa: I001 from NVDAObjects.IAccessible import IAccessible import eventHandler from scriptHandler import isScriptWaiting @@ -64,7 +64,7 @@ def _get_activeChild(self): def _get_shouldAllowIAccessibleFocusEvent(self): # QT doesn't fire focus on the active child as it should, so we will bounce the focus to it. # However, as the container does not have the focused state in QT5, we must still ensure we can get the event if we are going to bounce it - res = super(Container, self).shouldAllowIAccessibleFocusEvent + res = super().shouldAllowIAccessibleFocusEvent if not res: res = bool(self.activeChild) return res @@ -98,7 +98,7 @@ def script_previousColumn(self, gesture): if previous and controlTypes.State.FOCUSED in previous.states: eventHandler.executeEvent("gainFocus", previous) - __gestures = { + __gestures = { # noqa: RUF012 "kb:tab": "nextColumn", "kb:rightArrow": "nextColumn", "kb:shift+tab": "previousColumn", @@ -129,7 +129,7 @@ class Application(IAccessible): description = None def _get_states(self): - states = super(Application, self)._get_states() + states = super()._get_states() # The application should not have the focused state. # Otherwise, checks for the focused state will always hit the application and assume the focus is valid. states.discard(controlTypes.State.FOCUSED) diff --git a/source/NVDAObjects/IAccessible/scintilla.py b/source/NVDAObjects/IAccessible/scintilla.py index a87f5ffe8e4..efbef3e70bb 100755 --- a/source/NVDAObjects/IAccessible/scintilla.py +++ b/source/NVDAObjects/IAccessible/scintilla.py @@ -4,7 +4,7 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -import winUser +import winUser # noqa: I001 from . import IAccessible diff --git a/source/NVDAObjects/IAccessible/sysListView32.py b/source/NVDAObjects/IAccessible/sysListView32.py index 3ed2abb8930..40cf4164a35 100644 --- a/source/NVDAObjects/IAccessible/sysListView32.py +++ b/source/NVDAObjects/IAccessible/sysListView32.py @@ -3,10 +3,10 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -import time -from ctypes import * # noqa: F403 +import time # noqa: I001 +from ctypes import * import ctypes -from ctypes.wintypes import * # noqa: F403 +from ctypes.wintypes import * from comtypes import BSTR from enum import IntFlag import NVDAHelper @@ -22,7 +22,6 @@ from config.configFlags import ReportTableHeaders from locationHelper import RectLTRB from logHandler import log -from typing import Optional from utils import _deprecate # Window messages @@ -130,81 +129,81 @@ class ListViewWindowStyle(IntFlag): HDM_GETITEMCOUNT = HDM_FIRST -class LVITEM(Structure): # noqa: F405 - _fields_ = [ - ("mask", c_uint), # noqa: F405 - ("iItem", c_int), # noqa: F405 - ("iSubItem", c_int), # noqa: F405 - ("state", c_uint), # noqa: F405 - ("stateMask", c_uint), # noqa: F405 +class LVITEM(Structure): + _fields_ = [ # noqa: RUF012 + ("mask", c_uint), + ("iItem", c_int), + ("iSubItem", c_int), + ("state", c_uint), + ("stateMask", c_uint), # A pointer to a buffer containing the text of the item. # #18706: note that the pointer size is dictated by the architecture of the process that # hosts the list item, not the process that fetches the list item information. - ("pszText", c_ulong), # noqa: F405 - ("cchTextMax", c_int), # noqa: F405 - ("iImage", c_int), # noqa: F405 - ("lParam", LPARAM), # noqa: F405 - ("iIndent", c_int), # noqa: F405 - ("iGroupID", c_int), # noqa: F405 - ("cColumns", c_uint), # noqa: F405 - ("puColumns", c_uint), # noqa: F405 - ("piColFmt", POINTER(c_int)), # noqa: F405 - ("iGroup", c_int), # noqa: F405 + ("pszText", c_ulong), + ("cchTextMax", c_int), + ("iImage", c_int), + ("lParam", LPARAM), + ("iIndent", c_int), + ("iGroupID", c_int), + ("cColumns", c_uint), + ("puColumns", c_uint), + ("piColFmt", POINTER(c_int)), + ("iGroup", c_int), ] -class LVITEM64(Structure): # noqa: F405 - _fields_ = [ - ("mask", c_uint), # noqa: F405 - ("iItem", c_int), # noqa: F405 - ("iSubItem", c_int), # noqa: F405 - ("state", c_uint), # noqa: F405 - ("stateMask", c_uint), # noqa: F405 - ("pszText", c_ulonglong), # noqa: F405 - ("cchTextMax", c_int), # noqa: F405 - ("iImage", c_int), # noqa: F405 - ("lParam", c_ulonglong), # noqa: F405 - ("iIndent", c_int), # noqa: F405 - ("iGroupID", c_int), # noqa: F405 - ("cColumns", c_uint), # noqa: F405 - ("puColumns", c_uint), # noqa: F405 - ("piColFmt", c_ulonglong), # noqa: F405 - ("iGroup", c_int), # noqa: F405 +class LVITEM64(Structure): + _fields_ = [ # noqa: RUF012 + ("mask", c_uint), + ("iItem", c_int), + ("iSubItem", c_int), + ("state", c_uint), + ("stateMask", c_uint), + ("pszText", c_ulonglong), + ("cchTextMax", c_int), + ("iImage", c_int), + ("lParam", c_ulonglong), + ("iIndent", c_int), + ("iGroupID", c_int), + ("cColumns", c_uint), + ("puColumns", c_uint), + ("piColFmt", c_ulonglong), + ("iGroup", c_int), ] -class LVCOLUMN(Structure): # noqa: F405 - _fields_ = [ - ("mask", c_uint), # noqa: F405 - ("fmt", c_int), # noqa: F405 - ("cx", c_int), # noqa: F405 +class LVCOLUMN(Structure): + _fields_ = [ # noqa: RUF012 + ("mask", c_uint), + ("fmt", c_int), + ("cx", c_int), # A pointer to a buffer containing the column text. # #18706: note that the pointer size is dictated by the architecture of the process that # hosts the list item, not the process that fetches the list item information. - ("pszText", c_ulong), # noqa: F405 - ("cchTextMax", c_int), # noqa: F405 - ("iSubItem", c_int), # noqa: F405 - ("iImage", c_int), # noqa: F405 - ("iOrder", c_int), # noqa: F405 - ("cxMin", c_int), # noqa: F405 - ("cxDefault", c_int), # noqa: F405 - ("cxIdeal", c_int), # noqa: F405 + ("pszText", c_ulong), + ("cchTextMax", c_int), + ("iSubItem", c_int), + ("iImage", c_int), + ("iOrder", c_int), + ("cxMin", c_int), + ("cxDefault", c_int), + ("cxIdeal", c_int), ] -class LVCOLUMN64(Structure): # noqa: F405 - _fields_ = [ - ("mask", c_uint), # noqa: F405 - ("fmt", c_int), # noqa: F405 - ("cx", c_int), # noqa: F405 - ("pszText", c_ulonglong), # noqa: F405 - ("cchTextMax", c_int), # noqa: F405 - ("iSubItem", c_int), # noqa: F405 - ("iImage", c_int), # noqa: F405 - ("iOrder", c_int), # noqa: F405 - ("cxMin", c_int), # noqa: F405 - ("cxDefault", c_int), # noqa: F405 - ("cxIdeal", c_int), # noqa: F405 +class LVCOLUMN64(Structure): + _fields_ = [ # noqa: RUF012 + ("mask", c_uint), + ("fmt", c_int), + ("cx", c_int), + ("pszText", c_ulonglong), + ("cchTextMax", c_int), + ("iSubItem", c_int), + ("iImage", c_int), + ("iOrder", c_int), + ("cxMin", c_int), + ("cxDefault", c_int), + ("cxIdeal", c_int), ] @@ -230,24 +229,24 @@ class List(List): def getListGroupInfo(self, groupIndex): header = AutoFreeBSTR() footer = AutoFreeBSTR() - state = c_int() # noqa: F405 + state = c_int() if ( watchdog.cancellableExecute( NVDAHelper.localLib.nvdaInProcUtils_sysListView32_getGroupInfo, self.appModule.helperLocalBindingHandle, self.windowHandle, groupIndex, - byref(header), # noqa: F405 - byref(footer), # noqa: F405 - byref(state), # noqa: F405 + byref(header), + byref(footer), + byref(state), ) != 0 - ): # noqa: F405 + ): return None - return dict(header=header.value, footer=footer.value, state=state.value, groupIndex=groupIndex) + return dict(header=header.value, footer=footer.value, state=state.value, groupIndex=groupIndex) # noqa: C408 def _get_name(self): - name = super(List, self)._get_name() + name = super()._get_name() if not name: name = super(IAccessible, self)._get_name() return name @@ -269,7 +268,7 @@ def event_gainFocus(self): groupInfo=info, ) return eventHandler.queueEvent("gainFocus", groupingObj) - return super(List, self).event_gainFocus() + return super().event_gainFocus() def _get_isMultiColumn(self): view = watchdog.cancellableSendMessage(self.windowHandle, LVM_GETVIEW, 0, 0) @@ -297,7 +296,7 @@ def _get_columnCount(self) -> int: return 1 return count - def _getColumnOrderArrayRawInProc(self, columnCount: int) -> Optional[ctypes.Array]: + def _getColumnOrderArrayRawInProc(self, columnCount: int) -> ctypes.Array | None: """Retrieves a list of column indexes for a given list control. See `_getColumnOrderArrayRaw` for more comments. Note that this method operates in process and cannot be used in situations where NVDA cannot inject @@ -315,7 +314,7 @@ def _getColumnOrderArrayRawInProc(self, columnCount: int) -> Optional[ctypes.Arr return None return columnOrderArray - def _getColumnOrderArrayRawOutProc(self, columnCount: int) -> Optional[ctypes.Array]: + def _getColumnOrderArrayRawOutProc(self, columnCount: int) -> ctypes.Array | None: """Retrieves a list of column indexes for a given list control. See `_getColumnOrderArrayRaw` for more comments. Note that this method operates out of process and has to reserve memory inside a given application. @@ -328,12 +327,12 @@ def _getColumnOrderArrayRawOutProc(self, columnCount: int) -> Optional[ctypes.Ar internalCoa = winKernel.virtualAllocEx( processHandle, None, - sizeof(coa), # noqa: F405 + sizeof(coa), winKernel.MEM_COMMIT, - winKernel.PAGE_READWRITE, # noqa: F405 - ) # noqa: F405 + winKernel.PAGE_READWRITE, + ) try: - winKernel.writeProcessMemory(processHandle, internalCoa, byref(coa), sizeof(coa), None) # noqa: F405 + winKernel.writeProcessMemory(processHandle, internalCoa, byref(coa), sizeof(coa), None) # The meaning of the return value depends on the message sent, for LVM_GETCOLUMNORDERARRAY, # it returns nonzero if successful, or 0 otherwise. # https://docs.microsoft.com/en-us/windows/win32/controls/lvm-getcolumnorderarray#return-value @@ -344,7 +343,7 @@ def _getColumnOrderArrayRawOutProc(self, columnCount: int) -> Optional[ctypes.Ar internalCoa, ) if res: - winKernel.readProcessMemory(processHandle, internalCoa, byref(coa), sizeof(coa), None) # noqa: F405 + winKernel.readProcessMemory(processHandle, internalCoa, byref(coa), sizeof(coa), None) else: coa = None log.debugWarning( @@ -355,7 +354,7 @@ def _getColumnOrderArrayRawOutProc(self, columnCount: int) -> Optional[ctypes.Ar winKernel.virtualFreeEx(processHandle, internalCoa, 0, winKernel.MEM_RELEASE) return coa - def _getColumnOrderArrayRaw(self, columnCount: int) -> Optional[ctypes.Array]: + def _getColumnOrderArrayRaw(self, columnCount: int) -> ctypes.Array | None: """Retrieves an array of column indexes for a given list. The indexes are placed in order in which columns are displayed on screen from left to right. Note that when columns are reordered the indexes remain the same - only their order differs. @@ -364,7 +363,7 @@ def _getColumnOrderArrayRaw(self, columnCount: int) -> Optional[ctypes.Array]: return self._getColumnOrderArrayRawOutProc(columnCount) return self._getColumnOrderArrayRawInProc(columnCount) - def _getMappedColumn(self, presentationIndex: int) -> Optional[int]: + def _getMappedColumn(self, presentationIndex: int) -> int | None: """ Multi-column SysListViews can have their columns re-ordered. To keep a consistent internal mapping, a column order array is used @@ -396,7 +395,7 @@ def _get_states(self) -> set[controlTypes.State]: class GroupingItem(Window): def __init__(self, windowHandle=None, parentNVDAObject=None, groupInfo=None): - super(GroupingItem, self).__init__(windowHandle=windowHandle) + super().__init__(windowHandle=windowHandle) self.parent = parentNVDAObject self.groupInfo = groupInfo @@ -453,7 +452,7 @@ def initOverlayClass(self): description = None def _get_value(self): - value = super(ListItemWithoutColumnSupport, self)._get_description() + value = super()._get_description() if (not value or value.isspace()) and self.windowStyle & ListViewWindowStyle.OWNERDRAWFIXED: value = self.displayText if not value: @@ -464,11 +463,11 @@ def _get_value(self): def _get_positionInfo(self): index = self.IAccessibleChildID totalCount = watchdog.cancellableSendMessage(self.windowHandle, LVM_GETITEMCOUNT, 0, 0) - return dict(indexInGroup=index, similarItemsInGroup=totalCount) + return dict(indexInGroup=index, similarItemsInGroup=totalCount) # noqa: C408 def event_stateChange(self): if self.hasFocus: - super(ListItemWithoutColumnSupport, self).event_stateChange() + super().event_stateChange() class ListItem(RowWithFakeNavigation, RowWithoutCellObjects, ListItemWithoutColumnSupport): @@ -505,7 +504,7 @@ def _getColumnLocationRawOutProc(self, index: int) -> ctypes.wintypes.RECT: """ processHandle = self.processHandle # LVM_GETSUBITEMRECT requires a pointer to a RECT structure that will receive the subitem bounding rectangle information. - localRect = RECT( # noqa: F405 + localRect = RECT( # Returns the bounding rectangle of the entire item, including the icon and label. left=LVIR_LABEL, # According to Microsoft, top should be the one-based index of the subitem. @@ -515,18 +514,18 @@ def _getColumnLocationRawOutProc(self, index: int) -> ctypes.wintypes.RECT: internalRect = winKernel.virtualAllocEx( processHandle, None, - sizeof(localRect), # noqa: F405 + sizeof(localRect), winKernel.MEM_COMMIT, - winKernel.PAGE_READWRITE, # noqa: F405 - ) # noqa: F405 + winKernel.PAGE_READWRITE, + ) try: winKernel.writeProcessMemory( processHandle, internalRect, - byref(localRect), # noqa: F405 - sizeof(localRect), # noqa: F405 - None, # noqa: F405 - ) # noqa: F405 + byref(localRect), + sizeof(localRect), + None, + ) res = watchdog.cancellableSendMessage( self.windowHandle, LVM_GETSUBITEMRECT, @@ -548,7 +547,7 @@ def _getColumnLocationRawOutProc(self, index: int) -> ctypes.wintypes.RECT: return None return localRect - def _getColumnLocationRaw(self, index: int) -> Optional[RectLTRB]: + def _getColumnLocationRaw(self, index: int) -> RectLTRB | None: if not self.appModule.helperLocalBindingHandle: rect = self._getColumnLocationRawOutProc(index) else: @@ -563,19 +562,17 @@ def _getColumnLocationRaw(self, index: int) -> Optional[RectLTRB]: top = rect.top right = rect.right bottom = rect.bottom - if left > right: - left = right - if top > bottom: - top = bottom + left = min(left, right) + top = min(top, bottom) return RectLTRB(left, top, right, bottom).toScreen(self.windowHandle).toLTWH() - def _getColumnLocation(self, column: int) -> Optional[RectLTRB]: + def _getColumnLocation(self, column: int) -> RectLTRB | None: mappedColumn = self.parent._getMappedColumn(column) if mappedColumn is None: return None return self._getColumnLocationRaw(mappedColumn) - def _getColumnContentRawInProc(self, index: int) -> Optional[str]: + def _getColumnContentRawInProc(self, index: int) -> str | None: """Retrieves text for a given column. Note that this method operates in process and cannot be used in situations where NVDA cannot inject i.e when running as a Windows Store application or when no focus event was received on startup. @@ -597,7 +594,7 @@ def _getColumnContentRawInProc(self, index: int) -> Optional[str]: return None return text.value - def _getColumnContentRawOutProc(self, index: int) -> Optional[str]: + def _getColumnContentRawOutProc(self, index: int) -> str | None: """Retrieves text for a given column. Note that this method operates out of process and has to reserve memory inside a given application. As a consequence it may fail when reserved memory is above the range available @@ -609,10 +606,10 @@ def _getColumnContentRawOutProc(self, index: int) -> Optional[str]: internalItem = winKernel.virtualAllocEx( processHandle, None, - sizeof(self.LVITEM), # noqa: F405 + sizeof(self.LVITEM), winKernel.MEM_COMMIT, - winKernel.PAGE_READWRITE, # noqa: F405 - ) # noqa: F405 + winKernel.PAGE_READWRITE, + ) try: internalText = winKernel.virtualAllocEx( processHandle, @@ -632,10 +629,10 @@ def _getColumnContentRawOutProc(self, index: int) -> Optional[str]: winKernel.writeProcessMemory( processHandle, internalItem, - byref(item), # noqa: F405 - sizeof(self.LVITEM), # noqa: F405 - None, # noqa: F405 - ) # noqa: F405 + byref(item), + sizeof(self.LVITEM), + None, + ) len = watchdog.cancellableSendMessage( self.windowHandle, LVM_GETITEMTEXTW, @@ -646,24 +643,24 @@ def _getColumnContentRawOutProc(self, index: int) -> Optional[str]: winKernel.readProcessMemory( processHandle, internalItem, - byref(item), # noqa: F405 - sizeof(self.LVITEM), # noqa: F405 - None, # noqa: F405 - ) # noqa: F405 - buffer = create_unicode_buffer(len) # noqa: F405 - winKernel.readProcessMemory(processHandle, item.pszText, buffer, sizeof(buffer), None) # noqa: F405 + byref(item), + sizeof(self.LVITEM), + None, + ) + buffer = create_unicode_buffer(len) + winKernel.readProcessMemory(processHandle, item.pszText, buffer, sizeof(buffer), None) finally: winKernel.virtualFreeEx(processHandle, internalText, 0, winKernel.MEM_RELEASE) finally: winKernel.virtualFreeEx(processHandle, internalItem, 0, winKernel.MEM_RELEASE) return buffer.value if buffer else None - def _getColumnContentRaw(self, index: int) -> Optional[str]: + def _getColumnContentRaw(self, index: int) -> str | None: if not self.appModule.helperLocalBindingHandle: return self._getColumnContentRawOutProc(index) return self._getColumnContentRawInProc(index) - def _getColumnContent(self, column: int) -> Optional[str]: + def _getColumnContent(self, column: int) -> str | None: mappedColumn = self.parent._getMappedColumn(column) if mappedColumn is None: return None @@ -674,21 +671,21 @@ def _getColumnImageIDRaw(self, index): internalItem = winKernel.virtualAllocEx( processHandle, None, - sizeof(self.LVITEM), # noqa: F405 + sizeof(self.LVITEM), winKernel.MEM_COMMIT, - winKernel.PAGE_READWRITE, # noqa: F405 - ) # noqa: F405 + winKernel.PAGE_READWRITE, + ) try: item = self.LVITEM( iItem=self.IAccessibleChildID - 1, mask=LVIF_IMAGE | LVIF_COLUMNS, iSubItem=index, ) - winKernel.writeProcessMemory(processHandle, internalItem, byref(item), sizeof(self.LVITEM), None) # noqa: F405 + winKernel.writeProcessMemory(processHandle, internalItem, byref(item), sizeof(self.LVITEM), None) item.mask = LVIF_IMAGE | LVIF_COLUMNS - winKernel.writeProcessMemory(processHandle, internalItem, byref(item), sizeof(self.LVITEM), None) # noqa: F405 + winKernel.writeProcessMemory(processHandle, internalItem, byref(item), sizeof(self.LVITEM), None) watchdog.cancellableSendMessage(self.windowHandle, LVM_GETITEMW, 0, internalItem) - winKernel.readProcessMemory(processHandle, internalItem, byref(item), sizeof(item), None) # noqa: F405 + winKernel.readProcessMemory(processHandle, internalItem, byref(item), sizeof(item), None) finally: winKernel.virtualFreeEx(processHandle, internalItem, 0, winKernel.MEM_RELEASE) return item.iImage @@ -699,7 +696,7 @@ def _getColumnImageID(self, column): return None return self._getColumnImageIDRaw(mappedColumn) - def _getColumnHeaderRawOutProc(self, index: int) -> Optional[str]: + def _getColumnHeaderRawOutProc(self, index: int) -> str | None: """Retrieves text of the header for the given column. Note that this method operates out of process and has to reserve memory inside a given application. As a consequence it may fail when reserved memory is above the range available @@ -711,10 +708,10 @@ def _getColumnHeaderRawOutProc(self, index: int) -> Optional[str]: internalColumn = winKernel.virtualAllocEx( processHandle, None, - sizeof(self.LVCOLUMN), # noqa: F405 + sizeof(self.LVCOLUMN), winKernel.MEM_COMMIT, - winKernel.PAGE_READWRITE, # noqa: F405 - ) # noqa: F405 + winKernel.PAGE_READWRITE, + ) try: internalText = winKernel.virtualAllocEx( processHandle, @@ -733,10 +730,10 @@ def _getColumnHeaderRawOutProc(self, index: int) -> Optional[str]: winKernel.writeProcessMemory( processHandle, internalColumn, - byref(column), # noqa: F405 - sizeof(self.LVCOLUMN), # noqa: F405 - None, # noqa: F405 - ) # noqa: F405 + byref(column), + sizeof(self.LVCOLUMN), + None, + ) res = watchdog.cancellableSendMessage( self.windowHandle, LVM_GETCOLUMNW, @@ -747,19 +744,19 @@ def _getColumnHeaderRawOutProc(self, index: int) -> Optional[str]: winKernel.readProcessMemory( processHandle, internalColumn, - byref(column), # noqa: F405 - sizeof(self.LVCOLUMN), # noqa: F405 - None, # noqa: F405 - ) # noqa: F405 - buffer = create_unicode_buffer(column.cchTextMax) # noqa: F405 - winKernel.readProcessMemory(processHandle, column.pszText, buffer, sizeof(buffer), None) # noqa: F405 + byref(column), + sizeof(self.LVCOLUMN), + None, + ) + buffer = create_unicode_buffer(column.cchTextMax) + winKernel.readProcessMemory(processHandle, column.pszText, buffer, sizeof(buffer), None) finally: winKernel.virtualFreeEx(processHandle, internalText, 0, winKernel.MEM_RELEASE) finally: winKernel.virtualFreeEx(processHandle, internalColumn, 0, winKernel.MEM_RELEASE) return buffer.value if buffer else None - def _getColumnHeaderRawInProc(self, index: int) -> Optional[str]: + def _getColumnHeaderRawInProc(self, index: int) -> str | None: """Retrieves text of the header for the given column. Note that this method operates in process and cannot be used in situations where NVDA cannot inject i.e when running as a Windows Store application or when no focus event was received on startup. @@ -779,12 +776,12 @@ def _getColumnHeaderRawInProc(self, index: int) -> Optional[str]: return None return text.value - def _getColumnHeaderRaw(self, index: int) -> Optional[str]: + def _getColumnHeaderRaw(self, index: int) -> str | None: if not self.appModule.helperLocalBindingHandle: return self._getColumnHeaderRawOutProc(index) return self._getColumnHeaderRawInProc(index) - def _getColumnHeader(self, column: int) -> Optional[str]: + def _getColumnHeader(self, column: int) -> str | None: mappedColumn = self.parent._getMappedColumn(column) if mappedColumn is None: return None @@ -793,7 +790,7 @@ def _getColumnHeader(self, column: int) -> Optional[str]: def _get_name(self): parent = self.parent if not isinstance(parent, List) or not parent.isMultiColumn or self._shouldDisableMultiColumn: - name = super(ListItem, self).name + name = super().name if name: return name elif self.windowStyle & ListViewWindowStyle.OWNERDRAWFIXED: @@ -819,7 +816,7 @@ def _get_name(self): else: header = None if header: - textList.append("%s: %s" % (header, content)) + textList.append("%s: %s" % (header, content)) # noqa: UP031 else: textList.append(content) name = "; ".join(textList) diff --git a/source/NVDAObjects/IAccessible/sysTreeView32.py b/source/NVDAObjects/IAccessible/sysTreeView32.py index be937352fd5..15dfdf7f172 100755 --- a/source/NVDAObjects/IAccessible/sysTreeView32.py +++ b/source/NVDAObjects/IAccessible/sysTreeView32.py @@ -3,7 +3,7 @@ # See the file COPYING for more details. # Copyright (C) 2007-2020 NV Access Limited -import api +import api # noqa: I001 import controlTypes import speech import UIAHandler @@ -37,7 +37,7 @@ class TreeView(IAccessible): def _get_firstChild(self): try: - return super(TreeView, self).firstChild + return super().firstChild except: # noqa: E722 # Broken commctrl 5 tree view. return BrokenCommctrl5Item.getFirstItem(self) @@ -64,7 +64,7 @@ def _get_treeview_level(self): return int(self.IAccessibleObject.accValue(self.IAccessibleChildID)) def _get_states(self): - states = super(TreeViewItem, self)._get_states() + states = super()._get_states() hItem = self.treeview_hItem itemStates = watchdog.cancellableSendMessage( self.windowHandle, @@ -86,13 +86,13 @@ def _get_value(self): def _get_parent(self): if self.IAccessibleChildID == 0: - return super(TreeViewItem, self)._get_parent() + return super()._get_parent() hItem = self.treeview_hItem if not hItem: - return super(TreeViewItem, self)._get_parent() + return super()._get_parent() parentItem = watchdog.cancellableSendMessage(self.windowHandle, TVM_GETNEXTITEM, TVGN_PARENT, hItem) if parentItem <= 0: - return super(TreeViewItem, self)._get_parent() + return super()._get_parent() newID = watchdog.cancellableSendMessage(self.windowHandle, TVM_MAPHTREEITEMTOACCID, parentItem, 0) if not newID: # Tree views from comctl < 6.0 use the hItem as the child ID. @@ -105,13 +105,13 @@ def _get_parent(self): def _get_firstChild(self): if self.IAccessibleChildID == 0: - return super(TreeViewItem, self)._get_firstChild() + return super()._get_firstChild() hItem = self.treeview_hItem if not hItem: - return super(TreeViewItem, self)._get_firstChild() + return super()._get_firstChild() childItem = watchdog.cancellableSendMessage(self.windowHandle, TVM_GETNEXTITEM, TVGN_CHILD, hItem) if childItem <= 0: - return super(TreeViewItem, self)._get_firstChild() + return super()._get_firstChild() newID = watchdog.cancellableSendMessage(self.windowHandle, TVM_MAPHTREEITEMTOACCID, childItem, 0) if not newID: # Tree views from comctl < 6.0 use the hItem as the child ID. @@ -124,7 +124,7 @@ def _get_firstChild(self): def _get_next(self): if self.IAccessibleChildID == 0: - return super(TreeViewItem, self)._get_next() + return super()._get_next() hItem = self.treeview_hItem if not hItem: return None @@ -143,7 +143,7 @@ def _get_next(self): def _get_previous(self): if self.IAccessibleChildID == 0: - return super(TreeViewItem, self)._get_previous() + return super()._get_previous() hItem = self.treeview_hItem if not hItem: return None @@ -188,7 +188,7 @@ def _get_childCount(self): def _get_positionInfo(self): if self.IAccessibleChildID == 0: - return super(TreeViewItem, self)._get_positionInfo() + return super()._get_positionInfo() info = {} info["level"] = self.treeview_level hItem = self.treeview_hItem @@ -220,7 +220,7 @@ def event_stateChange(self): and controlTypes.State.EXPANDED not in getattr(self, "_speakObjectPropertiesCache", {}).get("states", frozenset()) ) - super(TreeViewItem, self).event_stateChange() + super().event_stateChange() if announceContains: # Translators: a message reported when opening when expanding a node in a tree view. speech.speakMessage(ngettext("%s item", "%s items", self.childCount) % self.childCount) @@ -238,19 +238,19 @@ def __init__(self, _uiaObj=None, **kwargs): if not _uiaObj: raise ValueError("Cannot instantiate directly without supplying _uiaObj") self._uiaObj = _uiaObj - super(BrokenCommctrl5Item, self).__init__(**kwargs) + super().__init__(**kwargs) def initOverlayClass(self): self._uiaObj = None if UIAHandler.handler: - parent = super(BrokenCommctrl5Item, self).parent + parent = super().parent if parent and parent.hasFocus: try: kwargs = {} UIA.kwargsFromSuper(kwargs, relation="focus", ignoreNonNativeElementsWithFocus=False) self._uiaObj = UIA(**kwargs) except Exception: - log.error("Retrieving UIA focus failed", exc_info=True) + log.error("Retrieving UIA focus failed", exc_info=True) # noqa: G201 def _get_role(self): return self._uiaObj.role if self._uiaObj else controlTypes.Role.UNKNOWN @@ -290,7 +290,7 @@ def _get_parent(self): # If the parent is the tree view itself (root window object), just use super's parent. IAccessible isn't broken on the container itself. if not uiaParent.UIAElement.cachedNativeWindowHandle: return self._makeRelatedObj(uiaParent) - return super(BrokenCommctrl5Item, self).parent + return super().parent def _get_next(self): return self._makeRelatedObj(self._uiaObj.next) if self._uiaObj else None diff --git a/source/NVDAObjects/IAccessible/webKit.py b/source/NVDAObjects/IAccessible/webKit.py index d8ea0c155ec..17040dc84b6 100644 --- a/source/NVDAObjects/IAccessible/webKit.py +++ b/source/NVDAObjects/IAccessible/webKit.py @@ -4,7 +4,7 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -import IAccessibleHandler +import IAccessibleHandler # noqa: I001 import controlTypes import braille from . import IAccessible diff --git a/source/NVDAObjects/IAccessible/winConsole.py b/source/NVDAObjects/IAccessible/winConsole.py index 4d798eca815..56c4ec97f75 100644 --- a/source/NVDAObjects/IAccessible/winConsole.py +++ b/source/NVDAObjects/IAccessible/winConsole.py @@ -3,7 +3,7 @@ # See the file COPYING for more details. # Copyright (C) 2007-2020 NV Access Limited, Bill Dengler -import config +import config # noqa: I001 from NVDAObjects.behaviors import KeyboardHandlerBasedTypedCharSupport from winVersion import getWinVer, WIN10_1607 @@ -29,8 +29,6 @@ class LegacyWinConsole(winConsole.WinConsole, IAccessible): before 1607. """ - pass - def findExtraOverlayClasses(obj, clsList): if getWinVer() >= WIN10_1607 and config.conf["terminals"]["keyboardSupportInLegacy"]: diff --git a/source/NVDAObjects/IAccessible/winword.py b/source/NVDAObjects/IAccessible/winword.py index 040a6c4b8b8..9c18e62f81f 100644 --- a/source/NVDAObjects/IAccessible/winword.py +++ b/source/NVDAObjects/IAccessible/winword.py @@ -3,7 +3,7 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -from comtypes import COMError +from comtypes import COMError # noqa: I001 import operator import uuid from logHandler import log @@ -54,19 +54,19 @@ def event_caret(self) -> None: curSelectionPos = self.makeTextInfo(textInfos.POSITION_SELECTION) lastSelectionPos = getattr(self, "_lastSelectionPos", None) self._lastSelectionPos = curSelectionPos - if lastSelectionPos: + if lastSelectionPos: # noqa: SIM102 if curSelectionPos._rangeObj.isEqual(lastSelectionPos._rangeObj): if self._fromUpdateBrailleAndReviewPosition: super().event_caret() self._fromUpdateBrailleAndReviewPosition = False return - super(WordDocument, self).event_caret() + super().event_caret() def _get_role(self): return controlTypes.Role.EDITABLETEXT def _get_states(self): - states = super(WordDocument, self).states + states = super().states states.add(controlTypes.State.MULTILINE) return states @@ -404,11 +404,9 @@ def _moveInTable(self, row=True, forward=True): ui.message(_("Not in table")) return False _cell = table.cell - getCell = ( # noqa: E731 - lambda thisIndex, otherIndex: ( - _cell(thisIndex, otherIndex) if row else _cell(otherIndex, thisIndex) - ) - ) # noqa: E731 + getCell = lambda thisIndex, otherIndex: ( + _cell(thisIndex, otherIndex) if row else _cell(otherIndex, thisIndex) + ) thisIndex = rowNumber if row else columnNumber otherIndex = columnNumber if row else rowNumber thisLimit = (rowCount if row else columnCount) if forward else 1 @@ -548,8 +546,8 @@ def _get_errorText(self): def _get_name(self): if self.WinwordVersion < 13: - return super(SpellCheckErrorField, self).description - return super(SpellCheckErrorField, self).name + return super().description + return super().name description = None diff --git a/source/NVDAObjects/IAccessible/wx.py b/source/NVDAObjects/IAccessible/wx.py index 0e98ee90f67..73d9ff41dc2 100644 --- a/source/NVDAObjects/IAccessible/wx.py +++ b/source/NVDAObjects/IAccessible/wx.py @@ -5,7 +5,7 @@ """Improvements for wxWidgets objects.""" -import api +import api # noqa: I001 import eventHandler import winUser diff --git a/source/NVDAObjects/JAB/__init__.py b/source/NVDAObjects/JAB/__init__.py index 6597560c697..41ba2684f45 100644 --- a/source/NVDAObjects/JAB/__init__.py +++ b/source/NVDAObjects/JAB/__init__.py @@ -3,7 +3,7 @@ # This file is covered by the GNU General Public License. # See the file COPYING for more details. -import ctypes +import ctypes # noqa: I001 import re from typing import ( Any, @@ -327,9 +327,9 @@ def __init__(self, relation=None, windowHandle=None, jabContext=None): windowHandle = jabContext.hwnd self.windowHandle = windowHandle self.jabContext = jabContext - super(JAB, self).__init__(windowHandle=windowHandle) + super().__init__(windowHandle=windowHandle) try: - self._JABAccContextInfo + self._JABAccContextInfo # noqa: B018 except RuntimeError: raise InvalidNVDAObject("Could not get accessible context info") @@ -344,7 +344,7 @@ def _get_TextInfo(self): controlTypes.Role.LISTITEM, ]: return JABTextInfo - return super(JAB, self).TextInfo + return super().TextInfo def _isEqual(self, other: Any) -> bool: try: @@ -374,7 +374,7 @@ def _get_keyboardShortcut(self) -> str | None: modifiers |= JABHandler.AccessibleKeystroke.ALT keyList = [ keyLabels.localizedKeyLabels.get(l, l) - for l in JABHandler._getKeyLabels(modifiers, binding.character) # noqa: E741 + for l in JABHandler._getKeyLabels(modifiers, binding.character) ] shortcutsList.append("+".join(keyList)) return ", ".join(shortcutsList) @@ -407,7 +407,7 @@ def _get_JABStates(self): return self._JABAccContextInfo.states_en_US def _get_states(self): - log.debug("states: %s" % self.JABStates) + log.debug("states: %s" % self.JABStates) # noqa: UP031 stateSet = set() stateString = self.JABStates stateStrings = stateString.split(",") @@ -458,13 +458,13 @@ def _get_location(self): ) def _get_hasFocus(self) -> bool: - if controlTypes.State.FOCUSED in self.states: + if controlTypes.State.FOCUSED in self.states: # noqa: SIM103 return True else: return False def _get_positionInfo(self): - info = super(JAB, self).positionInfo or {} + info = super().positionInfo or {} # If tree view item, try to retrieve the level via JAB if self.role == controlTypes.Role.TREEVIEWITEM: @@ -475,7 +475,7 @@ def _get_positionInfo(self): selfDepth = self.jabContext.getObjectDepth() if selfDepth > treeDepth: info["level"] = selfDepth - treeDepth - except: # noqa: E722 + except: # noqa: E722, S110 pass targets = self._getJABRelationTargets("memberOf") @@ -510,13 +510,13 @@ def _get_parent(self): if jabContext and self.indexInParent is not None: self._parent = JAB(jabContext=jabContext) else: - self._parent = super(JAB, self).parent + self._parent = super().parent return self._parent def _get_next(self): parent = self.parent if not isinstance(parent, JAB): - return super(JAB, self).next + return super().next if self.indexInParent is None: return None newIndex = self.indexInParent + 1 @@ -537,7 +537,7 @@ def _get_next(self): def _get_previous(self): parent = self.parent if not isinstance(parent, JAB): - return super(JAB, self).previous + return super().previous if self.indexInParent is None: return None newIndex = self.indexInParent - 1 @@ -634,7 +634,7 @@ def reportFocus(self): and parent.role == controlTypes.Role.COMBOBOX ): return - super(JAB, self).reportFocus() + super().reportFocus() def _get__actions(self): actions = JABHandler.AccessibleActions() @@ -689,7 +689,7 @@ def _get_activeDescendant(self): def event_gainFocus(self): if eventHandler.isPendingEvents("gainFocus"): return - super(JAB, self).event_gainFocus() + super().event_gainFocus() if eventHandler.isPendingEvents("gainFocus"): return activeDescendant = self.activeDescendant @@ -699,8 +699,8 @@ def event_gainFocus(self): class ComboBox(JAB): def _get_states(self): - states = super(ComboBox, self).states - if controlTypes.State.COLLAPSED not in states and controlTypes.State.EXPANDED not in states: + states = super().states + if controlTypes.State.COLLAPSED not in states and controlTypes.State.EXPANDED not in states: # noqa: SIM102 if ( self.childCount == 1 and self.firstChild @@ -715,12 +715,12 @@ def _get_states(self): def _get_activeDescendant(self): if controlTypes.State.COLLAPSED in self.states: return None - return super(ComboBox, self).activeDescendant + return super().activeDescendant def _get_value(self): - value = super(ComboBox, self).value + value = super().value if not value and not self.activeDescendant: - descendant = super(ComboBox, self).activeDescendant + descendant = super().activeDescendant if descendant: value = descendant.name return value diff --git a/source/NVDAObjects/UIA/VisualStudio.py b/source/NVDAObjects/UIA/VisualStudio.py index 98578783e8c..0c85d7c5051 100644 --- a/source/NVDAObjects/UIA/VisualStudio.py +++ b/source/NVDAObjects/UIA/VisualStudio.py @@ -7,7 +7,7 @@ available in Visual Studio and SQL Server Management Studio. """ -from . import UIA, ToolTip +from . import UIA, ToolTip # noqa: I001 import speech import braille import braille.regions.properties diff --git a/source/NVDAObjects/UIA/__init__.py b/source/NVDAObjects/UIA/__init__.py index b6e57dc6022..c1252a841bb 100644 --- a/source/NVDAObjects/UIA/__init__.py +++ b/source/NVDAObjects/UIA/__init__.py @@ -6,17 +6,16 @@ """Support for UI Automation (UIA) controls.""" -from __future__ import annotations +from __future__ import annotations # noqa: I001 import typing -from typing import ( - Generator, - List, - Optional, - Dict, - Tuple, - Callable, +from typing import ( # noqa: UP035 + List, # noqa: F401 + Optional, # noqa: F401 + Dict, # noqa: F401 + Tuple, # noqa: F401 Any, ) +from collections.abc import Generator, Callable import array import ctypes from ctypes.wintypes import POINT @@ -103,7 +102,7 @@ def _get_controlFieldNVDAObjectClass(self): return UIA # UIA property IDs that should be automatically cached for control fields - _controlFieldUIACachedPropertyIDs = { + _controlFieldUIACachedPropertyIDs = { # noqa: RUF012 UIAHandler.UIA_IsValuePatternAvailablePropertyId, UIAHandler.UIA_NamePropertyId, UIAHandler.UIA_HelpTextPropertyId, @@ -154,7 +153,7 @@ def _get__controlFieldUIACacheRequest(self): return cacheRequest #: The UI Automation text units (in order of resolution) that should be used when fetching formatting. - UIAFormatUnits = [ + UIAFormatUnits = [ # noqa: RUF012 UIAHandler.TextUnit_Format, UIAHandler.TextUnit_Word, UIAHandler.TextUnit_Character, @@ -290,13 +289,13 @@ def _getFormatFieldColor(self, fetch: Callable[[int], int], formatField: textInf def _getFormatFieldLineSpacing(self, fetch: Callable[[int], int], formatField: textInfos.FormatField): val = fetch(UIAHandler.UIA_LineSpacingAttributeId) - if val != UIAHandler.handler.reservedNotSupportedValue: + if val != UIAHandler.handler.reservedNotSupportedValue: # noqa: SIM102 if val: formatField["line-spacing"] = val def _getFormatFieldLinks(self, fetch: Callable[[int], int], formatField: textInfos.FormatField): val = fetch(UIAHandler.UIA_LinkAttributeId) - if val != UIAHandler.handler.reservedNotSupportedValue: + if val != UIAHandler.handler.reservedNotSupportedValue: # noqa: SIM102 if val: formatField["link"] = True @@ -314,7 +313,7 @@ def _getFormatFieldAnnotationTypes( self, fetch: Callable[[int], int], formatField: textInfos.FormatField, - formatConfig: Dict, + formatConfig: dict, ): annotationTypes = fetch(UIAHandler.UIA_AnnotationTypesAttributeId) # Some UIA implementations return a single value rather than a tuple. @@ -354,12 +353,11 @@ def _getFormatFieldCulture(self, fetch: Callable[[int], int], formatField: textI formatField["language"] = languageHandler.windowsLCIDToLocaleName(cultureVal) except: # noqa: E722 log.debugWarning("language error", exc_info=True) - pass - def _getFormatFieldAtRange( # noqa: C901 + def _getFormatFieldAtRange( self, textRange: IUIAutomationTextRangeT, - formatConfig: Dict, + formatConfig: dict, ignoreMixedValues: bool = False, ) -> textInfos.FormatField: """ @@ -374,7 +372,7 @@ def _getFormatFieldAtRange( # noqa: C901 @return: The formatting for the given text range. """ if not isinstance(textRange, UIAHandler.IUIAutomationTextRange): - raise ValueError("%s is not a text range" % textRange) + raise ValueError("%s is not a text range" % textRange) # noqa: TRY004, UP031 fetchAnnotationTypes = ( formatConfig["reportSpellingErrors2"] != ReportSpellingErrors.OFF.value or formatConfig["reportComments"] @@ -473,13 +471,13 @@ def _getIndentValueDisplayString(self, val: float) -> str: # C901 '__init__' is too complex # Note: when working on getPropertiesBraille, look for opportunities to simplify # and move logic out into smaller helper functions. - def __init__( # noqa: C901 + def __init__( self, obj: NVDAObject, position: str, - _rangeObj: Optional[IUIAutomationTextRangeT] = None, + _rangeObj: IUIAutomationTextRangeT | None = None, ): - super(UIATextInfo, self).__init__(obj, position) + super().__init__(obj, position) if _rangeObj: try: self._rangeObj = _rangeObj.clone() @@ -512,11 +510,11 @@ def __init__( # noqa: C901 self.collapse(True) elif position == textInfos.POSITION_ALL or position == self.obj: self._rangeObj: IUIAutomationTextRangeT = self.obj.UIATextPattern.documentRange - elif isinstance(position, UIA) or isinstance(position, UIAHandler.IUIAutomationElement): + elif isinstance(position, UIA) or isinstance(position, UIAHandler.IUIAutomationElement): # noqa: SIM101 if isinstance(position, UIA): position = position.UIAElement try: - self._rangeObj: Optional[IUIAutomationTextRangeT] = self.obj.UIATextPattern.rangeFromChild( + self._rangeObj: IUIAutomationTextRangeT | None = self.obj.UIATextPattern.rangeFromChild( position, ) except COMError: @@ -532,9 +530,9 @@ def __init__( # noqa: C901 position = typing.cast(IUIAutomationTextRangeT, position) self._rangeObj = position.clone() else: - raise ValueError("Unknown position %s" % position) + raise ValueError("Unknown position %s" % position) # noqa: UP031 - def __eq__(self, other: "UIATextInfo"): + def __eq__(self, other: UIATextInfo): if self is other: return True if self.__class__ is not other.__class__: @@ -566,7 +564,7 @@ def _get_UIAElementAtStart(self): try: children = getChildrenWithCacheFromUIATextRange(tempRange, UIAHandler.handler.baseCacheRequest) except COMError as e: - log.debugWarning("Could not get children from UIA text range, %s" % e) + log.debugWarning("Could not get children from UIA text range, %s" % e) # noqa: UP031 children = None if children and children.length == 1: child = children.getElement(0) @@ -580,7 +578,7 @@ def _get_UIAElementAtStart(self): def _get_bookmark(self): return self.copy() - UIAControlTypesWhereNameIsContent = { + UIAControlTypesWhereNameIsContent = { # noqa: RUF012 UIAHandler.UIA_ButtonControlTypeId, UIAHandler.UIA_HyperlinkControlTypeId, UIAHandler.UIA_ImageControlTypeId, @@ -592,7 +590,7 @@ def _get_bookmark(self): def _getControlFieldForUIAObject( self, - obj: "UIA", + obj: UIA, isEmbedded=False, startOfNode=False, endOfNode=False, @@ -662,9 +660,9 @@ def _getTextFromUIARange(self, textRange: IUIAutomationTextRangeT) -> str: def _getTextWithFields_text( self, textRange: IUIAutomationTextRangeT, - formatConfig: Dict, - UIAFormatUnits: Optional[List[int]] = None, - ) -> Generator[textInfos.FieldCommand, None, None]: + formatConfig: dict, + UIAFormatUnits: list[int] | None = None, + ) -> Generator[textInfos.FieldCommand]: """ Yields format fields and text for the given UI Automation text range, split up by the first available UI Automation text unit that does not result in mixed attribute values. @param textRange: the UI Automation text range to walk. @@ -704,7 +702,7 @@ def _getTextWithFields_text( except UIAMixedAttributeError: if debug: log.debug("Mixed formatting. Trying higher resolution unit") - for subfield in self._getTextWithFields_text( + for subfield in self._getTextWithFields_text( # noqa: UP028 tempRange, formatConfig, UIAFormatUnits=furtherUIAFormatUnits, @@ -725,16 +723,16 @@ def _getTextWithFields_text( # C901 '_getTextWithFieldsForUIARange' is too complex # Note: when working on getPropertiesBraille, look for opportunities to simplify # and move logic out into smaller helper functions. - def _getTextWithFieldsForUIARange( # noqa: C901 + def _getTextWithFieldsForUIARange( self, rootElement: UIAHandler.IUIAutomationElement, textRange: IUIAutomationTextRangeT, - formatConfig: Dict, + formatConfig: dict, includeRoot: bool = False, alwaysWalkAncestors: bool = True, recurseChildren: bool = True, - _rootElementClipped: Tuple[bool, bool] = (True, True), - ) -> Generator[textInfos.TextInfo.TextOrFieldsT, None, None]: + _rootElementClipped: tuple[bool, bool] = (True, True), + ) -> Generator[textInfos.TextInfo.TextOrFieldsT]: """ Yields start and end control fields, and text, for the given UI Automation text range. :param rootElement: the highest ancestor that encloses the given text range. This function will not walk higher than this point. @@ -751,8 +749,8 @@ def _getTextWithFieldsForUIARange( # noqa: C901 debug = UIAHandler._isDebug() and log.isEnabledFor(log.DEBUG) if debug: log.debug("_getTextWithFieldsForUIARange") - log.debug("rootElement: %s" % rootElement.currentLocalizedControlType if rootElement else None) - log.debug("full text: %s" % textRange.getText(-1)) + log.debug("rootElement: %s" % rootElement.currentLocalizedControlType if rootElement else None) # noqa: UP031 + log.debug("full text: %s" % textRange.getText(-1)) # noqa: UP031 if recurseChildren: childElements = getChildrenWithCacheFromUIATextRange(textRange, self._controlFieldUIACacheRequest) # Specific check for embedded elements (checkboxes etc) @@ -833,7 +831,7 @@ def _getTextWithFieldsForUIARange( # noqa: C901 controlFieldNVDAObjectClass = self.controlFieldNVDAObjectClass for index, (parentElement, parentClipped) in enumerate(parentElements): if debug: - log.debug("parentElement: %s" % parentElement.currentLocalizedControlType) + log.debug("parentElement: %s" % parentElement.currentLocalizedControlType) # noqa: UP031 startOfNode = not parentClipped[0] endOfNode = not parentClipped[1] try: @@ -877,7 +875,7 @@ def _getTextWithFieldsForUIARange( # noqa: C901 UIAHandler.TextPatternRangeEndpoint_Start, ) if debug: - log.debug("Child count: %s" % childElements.length) + log.debug("Child count: %s" % childElements.length) # noqa: UP031 log.debug("Walking children") lastChildIndex = childCount - 1 lastChildEndDelta = 0 @@ -899,7 +897,7 @@ def _getTextWithFieldsForUIARange( # noqa: C901 if childAutomationID.startswith("UIA_AutomationId_Word_Page_"): continue if debug: - log.debug("Fetched child %s (%s)" % (index, childElement.currentLocalizedControlType)) + log.debug("Fetched child %s (%s)" % (index, childElement.currentLocalizedControlType)) # noqa: UP031 try: childRange = documentTextPattern.rangeFromChild(childElement) except COMError as e: @@ -1036,7 +1034,7 @@ def _getTextWithFieldsForUIARange( # noqa: C901 if debug: log.debug("_getTextWithFieldsForUIARange end") - def getTextWithFields(self, formatConfig: Optional[Dict] = None) -> textInfos.TextInfo.TextWithFieldsT: + def getTextWithFields(self, formatConfig: dict | None = None) -> textInfos.TextInfo.TextWithFieldsT: if not formatConfig: formatConfig = config.conf["documentFormatting"] fields = list(self._getTextWithFieldsForUIARange(self.obj.UIAElement, self._rangeObj, formatConfig)) @@ -1071,7 +1069,7 @@ def move( self, unit: str, direction: int, - endPoint: Optional[str] = None, + endPoint: str | None = None, ): UIAUnit = UIAHandler.getUIAUnitFromNVDAUnit(unit) if endPoint == "start": @@ -1110,7 +1108,7 @@ def collapse(self, end: bool = False): UIAHandler.TextPatternRangeEndpoint_Start, ) - def compareEndPoints(self, other: "UIATextInfo", which: str): + def compareEndPoints(self, other: UIATextInfo, which: str): if which.startswith("start"): src = UIAHandler.TextPatternRangeEndpoint_Start else: @@ -1121,7 +1119,7 @@ def compareEndPoints(self, other: "UIATextInfo", which: str): target = UIAHandler.TextPatternRangeEndpoint_End return self._rangeObj.CompareEndpoints(src, other._rangeObj, target) - def setEndPoint(self, other: "UIATextInfo", which: str): + def setEndPoint(self, other: UIATextInfo, which: str): if which.startswith("start"): src = UIAHandler.TextPatternRangeEndpoint_Start else: @@ -1206,13 +1204,13 @@ def _prefetchUIACacheForPropertyIDs(self, IDs: typing.Collection[int]) -> None: cacheRequest.addProperty(ID) except COMError: log.debug( - "Couldn't add property ID %d to cache request, most likely unsupported on this version of Windows" + "Couldn't add property ID %d to cache request, most likely unsupported on this version of Windows" # noqa: UP031 % ID, ) try: cacheElement = self.UIAElement.buildUpdatedCache(cacheRequest) except COMError: - log.debugWarning("IUIAutomationElement.buildUpdatedCache failed given IDs of %s" % IDs) + log.debugWarning("IUIAutomationElement.buildUpdatedCache failed given IDs of %s" % IDs) # noqa: UP031 return for ID in IDs: elementCache[ID] = cacheElement @@ -1220,7 +1218,7 @@ def _prefetchUIACacheForPropertyIDs(self, IDs: typing.Collection[int]) -> None: # C901 'findOverlayClasses' is too complex # Note: when working on findOverlayClasses, look for opportunities to simplify # and move logic out into smaller helper functions. - def findOverlayClasses(self, clsList): # NOQA: C901 + def findOverlayClasses(self, clsList): UIAControlType = self.UIAElement.cachedControlType UIAClassName = self.UIAElement.cachedClassName # #11445: to avoid COM errors, do not fetch cached UIA Automation Id from the underlying element. @@ -1295,7 +1293,7 @@ def findOverlayClasses(self, clsList): # NOQA: C901 elif ( self.UIAElement.cachedFrameworkID in ("InternetExplorer", "MicrosoftEdge") # But not for Internet Explorer - and not self.appModule.appName == "iexplore" + and not self.appModule.appName == "iexplore" # noqa: SIM201 ): from . import spartanEdge @@ -1329,7 +1327,7 @@ def findOverlayClasses(self, clsList): # NOQA: C901 self.windowClassName == "Chrome_RenderWidgetHostHWND" or self.UIAElement.cachedFrameworkID == "Chrome" ): - from . import chromium + from . import chromium # noqa: I001 from . import web if ( @@ -1495,7 +1493,7 @@ def findOverlayClasses(self, clsList): # NOQA: C901 clsList.append(UIA) if self.UIAIsWindowElement: - super(UIA, self).findOverlayClasses(clsList) + super().findOverlayClasses(clsList) if self.UIATextPattern: # Since there is a UIA text pattern, there is no need to use the win32 edit support at all. # However, UIA classifies (rich) edit controls with a role of document and doesn't add a multiline state. @@ -1606,7 +1604,7 @@ def __init__( windowHandle = UIAHandler.handler.getNearestWindowHandle(UIAElement) if not windowHandle: raise InvalidNVDAObject("no windowHandle") - super(UIA, self).__init__(windowHandle=windowHandle) + super().__init__(windowHandle=windowHandle) self.initialUIACachedPropertyIDs = initialUIACachedPropertyIDs if initialUIACachedPropertyIDs: @@ -1647,7 +1645,7 @@ def _get__shouldAllowUIALiveRegionChangeEvent(self): newText = self.name newTime = time.time() self.__class__._lastLiveRegionChangeInfo = (newText, newTime) - if newText == oldText and oldTime is not None and (newTime - oldTime) < 0.5: + if newText == oldText and oldTime is not None and (newTime - oldTime) < 0.5: # noqa: SIM103 return False return True @@ -1723,9 +1721,9 @@ def getSelectedItemsCount(self, maxItems=None): return 0 #: Typing information for auto-property: _get_selectionContainer - selectionContainer: "typing.Optional[UIA]" + selectionContainer: UIA | None - def _get_selectionContainer(self) -> "typing.Optional[UIA]": + def _get_selectionContainer(self) -> UIA | None: p = self.UIASelectionItemPattern if not p: return None @@ -1747,9 +1745,9 @@ def _get_selectionContainer(self) -> "typing.Optional[UIA]": return None #: typing for auto-property: UIAAnnotationObjects - UIAAnnotationObjects: typing.Dict[int, UIAHandler.IUIAutomationElement] + UIAAnnotationObjects: dict[int, UIAHandler.IUIAutomationElement] - def _get_UIAAnnotationObjects(self) -> typing.Dict[int, UIAHandler.IUIAutomationElement]: + def _get_UIAAnnotationObjects(self) -> dict[int, UIAHandler.IUIAutomationElement]: """ Returns this UIAElement's annotation objects, in a dict keyed by their annotation type ID. @@ -1803,7 +1801,7 @@ def _get_UIALegacyIAccessiblePattern(self): def _get_TextInfo(self): if self.UIATextPattern: return self._TextInfo - textInfo = super(UIA, self).TextInfo + textInfo = super().TextInfo if ( textInfo is NVDAObjectTextInfo and self.UIAIsWindowElement @@ -1818,36 +1816,36 @@ def setFocus(self): self.UIAElement.setFocus() def _get_devInfo(self): - info = super(UIA, self).devInfo - info.append("UIAElement: %r" % self.UIAElement) + info = super().devInfo + info.append("UIAElement: %r" % self.UIAElement) # noqa: UP031 # #11445: allow exceptions to be recorded when presenting Automation Id. try: ret = self.UIAElement.currentAutomationID - except Exception as e: - ret = "Exception: %s" % e - info.append("UIA automationID: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "Exception: %s" % e # noqa: UP031 + info.append("UIA automationID: %s" % ret) # noqa: UP031 try: ret = self.UIAElement.cachedFrameworkID - except Exception as e: - ret = "Exception: %s" % e - info.append("UIA frameworkID: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "Exception: %s" % e # noqa: UP031 + info.append("UIA frameworkID: %s" % ret) # noqa: UP031 try: ret = str(self.UIAElement.getRuntimeID()) - except Exception as e: - ret = "Exception: %s" % e - info.append("UIA runtimeID: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "Exception: %s" % e # noqa: UP031 + info.append("UIA runtimeID: %s" % ret) # noqa: UP031 try: ret = self.UIAElement.cachedProviderDescription - except Exception as e: - ret = "Exception: %s" % e - info.append("UIA providerDescription: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "Exception: %s" % e # noqa: UP031 + info.append("UIA providerDescription: %s" % ret) # noqa: UP031 try: ret = self.UIAElement.currentClassName - except Exception as e: - ret = "Exception: %s" % e - info.append("UIA className: %s" % ret) + except Exception as e: # noqa: BLE001 + ret = "Exception: %s" % e # noqa: UP031 + info.append("UIA className: %s" % ret) # noqa: UP031 patternsAvailable = [] - patternAvailableConsts = dict( + patternAvailableConsts = dict( # noqa: C402 (const, name) for name, const in UIAHandler.__dict__.items() if name.startswith("UIA_Is") and name.endswith("PatternAvailablePropertyId") @@ -1861,7 +1859,7 @@ def _get_devInfo(self): if res: # Every name has the same format, so the string indexes can be safely hardcoded here. patternsAvailable.append(name[6:-19]) - info.append("UIA patterns available: %s" % ", ".join(patternsAvailable)) + info.append("UIA patterns available: %s" % ", ".join(patternsAvailable)) # noqa: UP031 return info def _get_UIAAutomationId(self): @@ -1912,7 +1910,7 @@ def _get_role(self): role in (controlTypes.Role.UNKNOWN, controlTypes.Role.PANE, controlTypes.Role.WINDOW) and self.windowHandle ): - superRole = super(UIA, self).role + superRole = super().role if superRole != controlTypes.Role.WINDOW: role = superRole return role @@ -1947,7 +1945,7 @@ def _get_keyboardShortcut(self): # #6790: Do not add two spaces unless both access key and accelerator are present in order to not waste string real estate. return " ".join(shortcuts) if shortcuts else "" - _UIAStatesPropertyIDs = { + _UIAStatesPropertyIDs = { # noqa: RUF012 UIAHandler.UIA_HasKeyboardFocusPropertyId, UIAHandler.UIA.UIA_SelectionCanSelectMultiplePropertyId, UIAHandler.UIA_SelectionItemIsSelectedPropertyId, @@ -1965,7 +1963,7 @@ def _get_keyboardShortcut(self): UIAHandler.UIA_DragIsGrabbedPropertyId, } - _focusPrefetchUIAPropertyIDs = { + _focusPrefetchUIAPropertyIDs = { # noqa: RUF012 UIAHandler.UIA_FullDescriptionPropertyId, UIAHandler.UIA_HelpTextPropertyId, UIAHandler.UIA_AccessKeyPropertyId, @@ -2091,7 +2089,7 @@ def _get_states(self): onError=None, ) - if annotationTypes: + if annotationTypes: # noqa: SIM102 if UIAHandler.AnnotationType_Comment in annotationTypes: states.add(controlTypes.State.HASCOMMENT) # Drag "is grabbed" property was added in Windows 8. @@ -2120,7 +2118,7 @@ def _getReadOnlyState(self) -> bool: return isReadOnly def _get_presentationType(self): - presentationType = super(UIA, self).presentationType + presentationType = super().presentationType # UIA NVDAObjects can only be considered content if UI Automation considers them both a control and content. if presentationType == self.presType_content and not ( self.UIAElement.cachedIsContentElement and self.UIAElement.cachedIsControlElement @@ -2132,7 +2130,7 @@ def correctAPIForRelation(self, obj, relation=None): if obj and self.windowHandle != obj.windowHandle and not obj.UIAElement.cachedNativeWindowHandle: # The target element is not the root element for the window, so don't change API class; i.e. always use UIA. return obj - return super(UIA, self).correctAPIForRelation(obj, relation) + return super().correctAPIForRelation(obj, relation) def _get_parent(self): try: @@ -2143,7 +2141,7 @@ def _get_parent(self): except COMError: parentElement = None if not parentElement: - return super(UIA, self).parent + return super().parent if not parentElement.CachedNativeWindowHandle and not self.UIAElement.CachedNativeWindowHandle: # Neither self or parent have a window handle themselves, so their nearest window handle will be the same. # Cache this on the parent if cached on self, to avoid fetching it later. @@ -2168,9 +2166,9 @@ def _get_previous(self): return self.correctAPIForRelation(UIA(UIAElement=previousElement)) #: Typing information for auto-property: _get_next - next: "typing.Optional[UIA]" + next: UIA | None - def _get_next(self) -> "typing.Optional[UIA]": + def _get_next(self) -> UIA | None: try: nextElement = UIAHandler.handler.baseTreeWalker.GetNextSiblingElementBuildCache( self.UIAElement, @@ -2215,8 +2213,8 @@ def _get_UIAChildren(self): try: return self.UIAElement.buildUpdatedCache(childrenCacheRequest).getCachedChildren() except COMError as e: - log.debugWarning("Could not fetch cached children from UIA element: %s" % e) - raise e + log.debugWarning("Could not fetch cached children from UIA element: %s" % e) # noqa: UP031 + raise e # noqa: TRY201 def _get_children(self): try: @@ -2255,7 +2253,7 @@ def _get_rowSpan(self): return val return 1 - def _getTextFromHeaderElement(self, element: UIAHandler.IUIAutomationElement) -> typing.Optional[str]: + def _getTextFromHeaderElement(self, element: UIAHandler.IUIAutomationElement) -> str | None: obj = UIA( windowHandle=self.windowHandle, UIAElement=element.buildUpdatedCache(UIAHandler.handler.baseCacheRequest), @@ -2356,19 +2354,19 @@ def _get_location(self): # r is a tuple of floats representing left, top, width and height. return locationHelper.RectLTWH.fromFloatCollection(*r) - def _get_UIAValue(self) -> typing.Optional[str]: + def _get_UIAValue(self) -> str | None: val = self._getUIACacheablePropertyValue(UIAHandler.UIA.UIA_ValueValuePropertyId, True) if val != UIAHandler.handler.reservedNotSupportedValue: return val return None - def _get_UIARangeValue(self) -> typing.Optional[float]: + def _get_UIARangeValue(self) -> float | None: val = self._getUIACacheablePropertyValue(UIAHandler.UIA.UIA_RangeValueValuePropertyId, True) if val != UIAHandler.handler.reservedNotSupportedValue: return val return None - def _get_value(self) -> typing.Optional[str]: + def _get_value(self) -> str | None: if self.UIAValue is not None: return self.UIAValue if self.UIARangeValue is not None: @@ -2416,7 +2414,7 @@ def _get_hasIrrelevantLocation(self): return isOffScreen or not self.location or not any(self.location) def _get_positionInfo(self): - info = super(UIA, self).positionInfo or {} + info = super().positionInfo or {} itemIndex = 0 try: itemIndex = self._getUIACacheablePropertyValue(UIAHandler.UIA_PositionInSetPropertyId) @@ -2442,7 +2440,7 @@ def _get_positionInfo(self): def scrollIntoView(self): pass - def isDescendantOf(self, obj: "NVDAObjects.NVDAObject") -> bool: + def isDescendantOf(self, obj: NVDAObjects.NVDAObject) -> bool: if isinstance(obj, UIA): # As both objects are UIA, # We can search this object's ancestors for obj with a UIA treeWalker @@ -2512,7 +2510,7 @@ def event_UIA_elementSelected(self): def event_valueChange(self): if issubclass(self.TextInfo, UIATextInfo): return - return super(UIA, self).event_valueChange() + return super().event_valueChange() def event_UIA_systemAlert(self): """ @@ -2598,8 +2596,6 @@ class InaccurateTextChangeEventEmittingEditableText(EditableTextBase, UIA): class XamlEditableText(EditableTextBase, UIA): """An UIA element with editable text exposed by the XAML framework.""" - ... - class TreeviewItem(UIA): def _get_value(self): @@ -2617,7 +2613,7 @@ def _get__level(self): return level def _get_positionInfo(self): - info = super(TreeviewItem, self).positionInfo or {} + info = super().positionInfo or {} info["level"] = self._level return info @@ -2719,7 +2715,7 @@ def event_valueChange(self): if self == focusParent: speech.speakObjectProperties(self, value=True, reason=controlTypes.OutputReason.CHANGE) else: - super(SensitiveSlider, self).event_valueChange() + super().event_valueChange() class ControlPanelLink(UIA): @@ -2804,7 +2800,7 @@ def event_stateChange(self): # #6337: This is an item in a combo box without the Value pattern or does not raise value change event. # This item has been selected, so notify the combo box that its value has changed. focus.event_valueChange() - super(ListItem, self).event_stateChange() + super().event_stateChange() class Dialog(Dialog): @@ -2897,7 +2893,7 @@ class SuggestionListItem(UIA): # NetUIDropdownAnchor comboBoxes (such as in the MS Office Options dialog) class NetUIDropdownAnchor(UIA): def _get_name(self): - name = super(NetUIDropdownAnchor, self).name + name = super().name # In MS Office 2010, these combo boxes had no name. # However, the name can be found as the direct previous sibling label element. if not name and self.previous and self.previous.role == controlTypes.Role.STATICTEXT: @@ -2939,7 +2935,7 @@ class ProgressBar(UIA, ProgressBar): This overlay class ensures that the reported value wil be between the accepted range of progress bar values. """ - def _get_value(self) -> typing.Optional[str]: + def _get_value(self) -> str | None: val = self.UIARangeValue if val is None: return self.UIAValue diff --git a/source/NVDAObjects/UIA/chromium.py b/source/NVDAObjects/UIA/chromium.py index d931fdd2adb..f836b7338a4 100644 --- a/source/NVDAObjects/UIA/chromium.py +++ b/source/NVDAObjects/UIA/chromium.py @@ -4,7 +4,7 @@ # Copyright (C) 2020-2021 NV Access limited, Leonard de Ruijter -import UIAHandler +import UIAHandler # noqa: I001 from . import web import controlTypes @@ -51,7 +51,7 @@ def _getControlFieldForUIAObject(self, obj, isEmbedded=False, startOfNode=False, if obj.role == controlTypes.Role.COMBOBOX: field["content"] = obj.value # Layout tables do not have the UIA table pattern - if field["role"] == controlTypes.Role.TABLE: + if field["role"] == controlTypes.Role.TABLE: # noqa: SIM102 if not obj._getUIACacheablePropertyValue(UIAHandler.UIA_IsTablePatternAvailablePropertyId): field["table-layout"] = True # Currently no way to tell if author has explicitly set name. diff --git a/source/NVDAObjects/UIA/excel.py b/source/NVDAObjects/UIA/excel.py index 3f734e90926..d903c64f4ca 100644 --- a/source/NVDAObjects/UIA/excel.py +++ b/source/NVDAObjects/UIA/excel.py @@ -3,8 +3,7 @@ # See the file COPYING for more details. # Copyright (C) 2018-2021 NV Access Limited, Leonard de Ruijter -from typing import Optional, Tuple -from comtypes import COMError +from comtypes import COMError # noqa: I001 import winVersion import UIAHandler import UIAHandler.constants @@ -133,36 +132,36 @@ def _get_areGridlinesVisible(self) -> bool: return False #: Typing information for auto-property: _get_outlineColor - outlineColor: Optional[Tuple[colors.RGB]] + outlineColor: tuple[colors.RGB] | None - def _get_outlineColor(self) -> Optional[Tuple[colors.RGB]]: + def _get_outlineColor(self) -> tuple[colors.RGB] | None: val = self._getUIACacheablePropertyValue(UIAHandler.UIA_OutlineColorPropertyId, True) if isinstance(val, tuple): return tuple(colors.RGB.fromCOLORREF(v) for v in val) return None #: Typing information for auto-property: _get_outlineThickness - outlineThickness: Optional[Tuple[float]] + outlineThickness: tuple[float] | None - def _get_outlineThickness(self) -> Optional[Tuple[float]]: + def _get_outlineThickness(self) -> tuple[float] | None: val = self._getUIACacheablePropertyValue(UIAHandler.UIA_OutlineThicknessPropertyId, True) if isinstance(val, tuple): return val return None #: Typing information for auto-property: _get_fillColor - fillColor: Optional[colors.RGB] + fillColor: colors.RGB | None - def _get_fillColor(self) -> Optional[colors.RGB]: + def _get_fillColor(self) -> colors.RGB | None: val = self._getUIACacheablePropertyValue(UIAHandler.UIA_FillColorPropertyId, True) if isinstance(val, int): return colors.RGB.fromCOLORREF(val) return None #: Typing information for auto-property: _get_fillType - fillType: Optional[UIAHandler.constants.FillType] + fillType: UIAHandler.constants.FillType | None - def _get_fillType(self) -> Optional[UIAHandler.constants.FillType]: + def _get_fillType(self) -> UIAHandler.constants.FillType | None: val = self._getUIACacheablePropertyValue(UIAHandler.UIA_FillTypePropertyId, True) if isinstance(val, int): try: @@ -172,9 +171,9 @@ def _get_fillType(self) -> Optional[UIAHandler.constants.FillType]: return None #: Typing information for auto-property: _get_rotation - rotation: Optional[float] + rotation: float | None - def _get_rotation(self) -> Optional[float]: + def _get_rotation(self) -> float | None: val = self._getUIACacheablePropertyValue(UIAHandler.UIA_RotationPropertyId, True) if isinstance(val, float): return val @@ -384,7 +383,7 @@ def _get_states(self): except COMError: # annotationTypes cannot be fetched on older Operating Systems such as Windows 7. annotationTypes = None - if annotationTypes: + if annotationTypes: # noqa: SIM102 if self._UIAExcelCustomAnnotationTypes.note.id in annotationTypes: states.add(controlTypes.State.HASNOTE) return states @@ -397,7 +396,7 @@ def _getColumnRepresentationForNumber(n: int) -> str: for more details about the approach used. """ - def modGenerator(x: int) -> Tuple[int, int]: + def modGenerator(x: int) -> tuple[int, int]: """Generate digits from L{x} in base alphabet, least significants bits first. diff --git a/source/NVDAObjects/UIA/spartanEdge.py b/source/NVDAObjects/UIA/spartanEdge.py index 00dc8b4f0d8..0472f2d7889 100644 --- a/source/NVDAObjects/UIA/spartanEdge.py +++ b/source/NVDAObjects/UIA/spartanEdge.py @@ -3,7 +3,7 @@ # See the file COPYING for more details. # Copyright (C) 2015-2021 NV Access Limited, Babbage B.V. -import winVersion +import winVersion # noqa: I001 from logHandler import log import eventHandler import controlTypes @@ -96,7 +96,7 @@ def expand(self, unit): # C901 '_getTextWithFieldsForUIARange' is too complex # Note: when working here look for opportunities to simplify # and move logic out into smaller helper functions. - def _getTextWithFieldsForUIARange( # noqa: C901 + def _getTextWithFieldsForUIARange( self, rootElement, textRange, @@ -296,7 +296,7 @@ def _getTextWithFieldsForUIARange( # noqa: C901 UIAHandler.TextPatternRangeEndpoint_Start, ): log.debug("Recursing endRange") - for endField in self._getTextWithFieldsForUIARange( + for endField in self._getTextWithFieldsForUIARange( # noqa: UP028 parentElement, tempRange, formatConfig, @@ -363,7 +363,7 @@ def _get__isTextEmpty(self): numberOfCharacters = 2 text = ti._rangeObj.getText(numberOfCharacters) # Edge can report newline for empty fields: - if text == "\n": + if text == "\n": # noqa: SIM103 return True return False diff --git a/source/NVDAObjects/UIA/sysListView32.py b/source/NVDAObjects/UIA/sysListView32.py index 64494511b81..135303f7542 100644 --- a/source/NVDAObjects/UIA/sysListView32.py +++ b/source/NVDAObjects/UIA/sysListView32.py @@ -6,8 +6,7 @@ """Module for native UIA implementations of SysListView32, e.g. in Windows Forms.""" -from typing import Dict, List, Optional, Type -from comtypes import COMError +from comtypes import COMError # noqa: I001 import config from logHandler import log from config.configFlags import ReportTableHeaders @@ -17,7 +16,7 @@ from . import ListItem, UIA -def findExtraOverlayClasses(obj: NVDAObject, clsList: List[Type[NVDAObject]]) -> None: +def findExtraOverlayClasses(obj: NVDAObject, clsList: list[type[NVDAObject]]) -> None: UIAControlType = obj.UIAElement.cachedControlType if UIAControlType == UIAHandler.UIA.UIA_ListControlTypeId: clsList.insert(0, SysListViewList) @@ -83,7 +82,7 @@ def _get_name(self) -> str: textList.append(text) return "; ".join(textList) - def _get_indexInParent(self) -> Optional[int]: + def _get_indexInParent(self) -> int | None: parent = self.parent if not isinstance(parent, SysListViewList) or self.childCount == 0: return super().indexInParent @@ -101,7 +100,7 @@ def _get_indexInParent(self) -> Optional[int]: return super().indexInParent return val - def _get_positionInfo(self) -> Dict[str, int]: + def _get_positionInfo(self) -> dict[str, int]: info = super().positionInfo or {} itemIndex = 0 try: diff --git a/source/NVDAObjects/UIA/web.py b/source/NVDAObjects/UIA/web.py index 7c29cd3cd4f..229e9b5abaf 100644 --- a/source/NVDAObjects/UIA/web.py +++ b/source/NVDAObjects/UIA/web.py @@ -2,12 +2,8 @@ # Copyright (C) 2015-2026 NV Access Limited, Babbage B.V., Leonard de Ruijter # This file may be used under the terms of the GNU General Public License, version 2 or later, as modified by the NVDA license. # For full terms and any additional permissions, see the NVDA license file: https://github.com/nvaccess/nvda/blob/master/copying.txt -from typing import ( - Optional, - Dict, -) -from comtypes import COMError +from comtypes import COMError # noqa: I001 from comtypes.automation import VARIANT from ctypes import byref @@ -268,9 +264,9 @@ def _getControlFieldForUIAObject(self, obj, isEmbedded=False, startOfNode=False, # C901 'getTextWithFields' is too complex # Note: when working on getTextWithFields, look for opportunities to simplify # and move logic out into smaller helper functions. - def getTextWithFields( # noqa: C901 + def getTextWithFields( self, - formatConfig: Optional[Dict] = None, + formatConfig: dict | None = None, ) -> textInfos.TextInfo.TextWithFieldsT: # We don't want fields for collapsed ranges. # This would normally be a general rule, but MS Word currently needs fields for collapsed ranges, @@ -365,7 +361,7 @@ def _get_role(self): ariaRole = self._getUIACacheablePropertyValue(UIAHandler.UIA_AriaRolePropertyId).lower() # #7333: It is valid to provide multiple, space separated aria roles in HTML # The role used is the first role in the list that has an associated NVDA role in aria.ariaRolesToNVDARoles - for ariaRole in ariaRole.split(): + for ariaRole in ariaRole.split(): # noqa: B020 newRole = aria.ariaRolesToNVDARoles.get(ariaRole) if newRole: return newRole @@ -518,7 +514,7 @@ def makeTextInfo(self, position): info = self.makeTextInfo(textInfos.POSITION_FIRST) self._selection = info return info - raise e + raise e # noqa: TRY201 def shouldPassThrough(self, obj, reason=None): # Enter focus mode for selectable list items (