diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index bfe37d43d25..cc196130696 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -29,3 +29,7 @@ be112ed44cb68f622a770c72fd29dd10899e9d07 73a3529d8b10eb73a45117eead906c0a9cb4c41b # String concatenation 9616ef6b18b5c5a5b64037a640d205868e66b964 +# Run runlint.bat on scons and .pyw files +0643d6e41089fb6aed22d489c7ccc3f32381f199 +# Run add-trailing-comma and ruff format on scons files +9fd7ba5cb268b64aacf45a43b1edb64c120ce20c diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6d5d4e95f96..e3cdb5541e5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -151,6 +151,7 @@ repos: pass_filenames: false types: [python] files: ^source/.*$ + exclude: "(sconscript|sconstruct)$" - id: unitTest name: unit tests entry: ./rununittests.bat @@ -168,3 +169,4 @@ repos: entry: uv run pyright language: system types: [python] + exclude: "(sconscript|sconstruct)$" diff --git a/appx/sconscript b/appx/sconscript index 45525d3baee..ab30388576a 100644 --- a/appx/sconscript +++ b/appx/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # A part of NonVisual Desktop Access (NVDA) # Copyright (C) 2018-2025 NV Access Limited # This file may be used under the terms of the GNU General Public License, version 2 or later, as modified by the NVDA license. @@ -13,7 +14,7 @@ Import( "env", "outFilePrefix", "isStoreSubmission", - ] + ], ) diff --git a/cldrDict_sconscript b/cldrDict_sconscript index 60f444e2bc0..119dea76ab1 100644 --- a/cldrDict_sconscript +++ b/cldrDict_sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # A part of NonVisual Desktop Access (NVDA) # Copyright (C) 2018-2022 NV Access Limited # This file may be used under the terms of the GNU General Public License, version 2 or later. diff --git a/nvdaHelper/ISimpleDOM_sconscript b/nvdaHelper/ISimpleDOM_sconscript index cd0b858a0ea..1a52a31ef4c 100644 --- a/nvdaHelper/ISimpleDOM_sconscript +++ b/nvdaHelper/ISimpleDOM_sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ @@ -19,7 +20,9 @@ env["MIDLCOM"] = env["MIDLCOM"][:-6] # Copy some secondary IDL files included by ISimpleDOMNode.idl idlDeps = [ env.Command( - "ISimpleDOMText.idl", "#/miscDeps/include/ISimpleDOM/ISimpleDOMText.idl", Copy("$TARGET", "$SOURCE") + "ISimpleDOMText.idl", + "#/miscDeps/include/ISimpleDOM/ISimpleDOMText.idl", + Copy("$TARGET", "$SOURCE"), ), env.Command( "ISimpleDOMDocument.idl", diff --git a/nvdaHelper/UIARemote/sconscript b/nvdaHelper/UIARemote/sconscript index 13d8b824f99..f52a9b1e426 100644 --- a/nvdaHelper/UIARemote/sconscript +++ b/nvdaHelper/UIARemote/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ @@ -16,7 +17,7 @@ Import( [ "env", "localLib", - ] + ], ) UIARemoteLib = env.SharedLibrary( diff --git a/nvdaHelper/acrobatAccess_sconscript b/nvdaHelper/acrobatAccess_sconscript index 1e7d0c00d78..2c587e393aa 100644 --- a/nvdaHelper/acrobatAccess_sconscript +++ b/nvdaHelper/acrobatAccess_sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ @@ -15,7 +16,9 @@ Import("env") idlFile = env.Command( - "acrobatAccess.idl", "#/miscDeps/include/acrobatAccess/acrobatAccess.idl", Copy("$TARGET", "$SOURCE") + "acrobatAccess.idl", + "#/miscDeps/include/acrobatAccess/acrobatAccess.idl", + Copy("$TARGET", "$SOURCE"), ) tlbFile, headerFile, iidSourceFile, proxySourceFile, dlldataSourceFile = env.TypeLibrary(source=idlFile) diff --git a/nvdaHelper/archBuild_sconscript b/nvdaHelper/archBuild_sconscript index fb19ef5e3db..22f73cd893a 100644 --- a/nvdaHelper/archBuild_sconscript +++ b/nvdaHelper/archBuild_sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # A part of NonVisual Desktop Access (NVDA) # Copyright (C) 2006-2026 NV Access Limited # This file may be used under the terms of the GNU General Public License, version 2 or later. @@ -82,9 +83,7 @@ isNVDACoreArch = ( or (PYTHON_PLATFORM == "win-arm64" and TARGET_ARCH == "arm64") ) isNVDAHelperLocalArch = isNVDACoreArch or ( - PYTHON_PLATFORM == "win-amd64" - and TARGET_ARCH == "arm64" - and isArm64EC + PYTHON_PLATFORM == "win-amd64" and TARGET_ARCH == "arm64" and isArm64EC ) debug = env["nvdaHelperDebugFlags"] release = env["release"] @@ -100,7 +99,7 @@ env.Append( # NOMINMAX: prevent minwindef.h min/max macro definition, which unexpectedly override developer # expectations "NOMINMAX", - ] + ], ) env.Append(CXXFLAGS=["/EHsc"]) @@ -116,13 +115,13 @@ env.Append( "/WX", subsystem, "/release", # We always want a checksum in the header - ] + ], ) env.Append( ARFLAGS=[ "/WX", subsystem, - ] + ], ) if TARGET_ARCH == "x86_64": env.Append(MIDLFLAGS="/x64") @@ -149,7 +148,7 @@ if "RTC" in debug: # We always want debug symbols env.Append(PDB="${TARGET}.pdb") env.Append( - LINKFLAGS="/OPT:REF" + LINKFLAGS="/OPT:REF", ) # having symbols usually turns this off but we have no need for unused symbols env.Append( @@ -160,7 +159,7 @@ env.Append( # It will output a list of the include files. # The option also displays nested include files, that is, the files # included by the files that you include. - ] + ], ) if isArm64EC: @@ -181,7 +180,7 @@ thirdPartyEnv = env.Clone() env.Append( CCFLAGS=[ "/W3", # warning level 3 - ] + ], ) if "analyze" in debug: env.Append(CCFLAGS=["/analyze"]) @@ -195,7 +194,7 @@ else: env.Append( CCFLAGS=[ "/WX", # warnings as error, don't do this with analyze, the build stops too early - ] + ], ) Export("thirdPartyEnv") @@ -266,7 +265,7 @@ if not isNVDAHelperLocalArch: if isNVDACoreArch: sonicLib = thirdPartyEnv.SConscript("sonic/sconscript") Export("sonicLib") - env.Install(sourceDir.Dir('synthDrivers'), sonicLib) + env.Install(sourceDir.Dir("synthDrivers"), sonicLib) thirdPartyEnv.SConscript("espeak/sconscript") thirdPartyEnv.SConscript("liblouis/sconscript") thirdPartyEnv.SConscript("javaAccessBridge/sconscript") @@ -275,4 +274,4 @@ if isNVDACoreArch: if TARGET_ARCH == "x86": sonicLib = thirdPartyEnv.SConscript("sonic/sconscript") Export("sonicLib") - env.Install(sourceDir.Dir('_synthDrivers32'), sonicLib) + env.Install(sourceDir.Dir("_synthDrivers32"), sonicLib) diff --git a/nvdaHelper/client/sconscript b/nvdaHelper/client/sconscript index 80aebba435e..c4378fffa85 100644 --- a/nvdaHelper/client/sconscript +++ b/nvdaHelper/client/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ @@ -15,7 +16,7 @@ Import( [ "env", - ] + ], ) winIPCUtilsObj = env.Object("./winIPCUtils", "../common/winIPCUtils.cpp") diff --git a/nvdaHelper/detours/sconscript b/nvdaHelper/detours/sconscript index fde5021feab..d0f0406c3b0 100644 --- a/nvdaHelper/detours/sconscript +++ b/nvdaHelper/detours/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 Import(["thirdPartyEnv"]) import typing # noqa: E402 diff --git a/nvdaHelper/espeak/sconscript b/nvdaHelper/espeak/sconscript index 6ef1b0637b9..bfa910408e2 100644 --- a/nvdaHelper/espeak/sconscript +++ b/nvdaHelper/espeak/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # A part of NonVisual Desktop Access (NVDA) # This file is covered by the GNU General Public License. # See the file COPYING for more details. @@ -21,7 +22,7 @@ Import( "thirdPartyEnv", "sourceDir", "sonicLib", - ] + ], ) freeLibrary = ctypes.windll.kernel32.FreeLibrary @@ -29,13 +30,13 @@ freeLibrary.argtypes = (ctypes.wintypes.HANDLE,) DLL_DIRECTORY_COOKIE = ctypes.c_void_p AddDllDirectory = ctypes.windll.kernel32.AddDllDirectory AddDllDirectory.argtypes = (ctypes.wintypes.LPCWSTR,) -AddDllDirectory.restype = DLL_DIRECTORY_COOKIE +AddDllDirectory.restype = DLL_DIRECTORY_COOKIE # Add the directory of the sonic dll to our DLL search path # So that eSpeak.dll cna find it when being loaded to compile dictionaries etc. sonicDllDir = sonicLib[0].get_dir().abspath AddDllDirectory(sonicDllDir) - + class AutoFreeCDLL(ctypes.CDLL): def __del__(self): @@ -127,7 +128,7 @@ env.Append( "/DUSE_SPEECHPLAYER=1", "/DUSE_KLATT=1", "/DUSE_LIBSONIC=1", - ] + ], ) env.Append( @@ -138,7 +139,7 @@ env.Append( espeakSrcDir.Dir("speechPlayer/include"), sonicSrcDir, espeakSrcDir.Dir("ucd-tools/src/include"), - ] + ], ) @@ -148,7 +149,7 @@ def espeak_compilePhonemeData_buildEmitter(target, source, env): [ [Dir(topDir).File(f) for f in files if f not in phSourceIgnores] for topDir, subdirs, files in os.walk(source[0].abspath) - ] + ], ) sources = env.Flatten([phSources]) targets = [ @@ -1046,13 +1047,14 @@ def espeak_compileDict_buildAction( f"Failed to compile dictionary: '{target}'" f"\n rulesPath: {rulesPathEncoded}" f"\n language: '{lang}'" - f"\n result: {espeak_ng_STATUS(compileDictResult)!s}" + f"\n result: {espeak_ng_STATUS(compileDictResult)!s}", ) return ACTION_FAILURE finally: espeak.espeak_Terminate() return ACTION_SUCCESS + espeakLib = env.SharedLibrary( target="espeak", srcdir=espeakSrcDir.Dir("libespeak-ng").abspath, @@ -1112,7 +1114,7 @@ espeakLib = env.SharedLibrary( # com\ttsengine.cpp # We do not use the ASYNC compile option in espeak. ], - LIBS=["advapi32", sonicLib[2]] , + LIBS=["advapi32", sonicLib[2]], LIBPATH=".", ) @@ -1131,7 +1133,8 @@ for i in phonemeData: env.AddPreAction(espeakLib, env.Action(cleanFiles_preBuildAction)) # Move any extra dictionaries into dictsource for compilation env.Install( - espeakRepo.Dir("dictsource"), env.Glob(os.path.join(espeakRepo.abspath, "dictsource", "extra", "*_*")) + espeakRepo.Dir("dictsource"), + env.Glob(os.path.join(espeakRepo.abspath, "dictsource", "extra", "*_*")), ) excludeLangs: typing.List[str] = [] @@ -1160,7 +1163,8 @@ for dictFileName, (langCode, inputFiles) in espeakDictionaryCompileList.items(): # Dictionaries can not be compiled in parallel, force SCons not to do this env.SideEffect("_espeak_compileDict", dictFile) env.InstallAs( # Install files to the "synthDrivers/espeak-ng-data/" dir. - os.path.join(synthDriversDir.Dir("espeak-ng-data").abspath, dictFileName), dictFile + os.path.join(synthDriversDir.Dir("espeak-ng-data").abspath, dictFileName), + dictFile, ) env.Install(synthDriversDir, espeakLib) @@ -1172,5 +1176,6 @@ espeakDataSource = espeakRepo.Dir("espeak-ng-data") # also install the lang and voices/!v directories. Exclude the voices/mb directory since we are not using mbrola. env.RecursiveInstall(targetEspeakDataDir.Dir("lang"), espeakDataSource.Dir("lang").abspath) env.RecursiveInstall( - targetEspeakDataDir.Dir("voices").Dir("!v"), espeakDataSource.Dir("voices").Dir("!v").abspath + targetEspeakDataDir.Dir("voices").Dir("!v"), + espeakDataSource.Dir("voices").Dir("!v").abspath, ) diff --git a/nvdaHelper/ia2_sconscript b/nvdaHelper/ia2_sconscript index ee734962a04..90ea1f69515 100644 --- a/nvdaHelper/ia2_sconscript +++ b/nvdaHelper/ia2_sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ diff --git a/nvdaHelper/javaAccessBridge/sconscript b/nvdaHelper/javaAccessBridge/sconscript index 0c0ed22bfb7..9c66c4be373 100644 --- a/nvdaHelper/javaAccessBridge/sconscript +++ b/nvdaHelper/javaAccessBridge/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # A part of NonVisual Desktop Access (NVDA) # Copyright (C) 2019-2025 NV Access Limited, 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. @@ -7,7 +8,7 @@ Import( [ "thirdPartyEnv", "sourceDir", - ] + ], ) env: Environment = thirdPartyEnv @@ -23,6 +24,7 @@ match TARGET_ARCH: jabDllName = None if jabDllName: env.Command( - sourceDir.File("windowsaccessbridge.dll"), env.Dir("#include/javaAccessBridge32").File(jabDllName), Copy("$TARGET", "$SOURCE") + sourceDir.File("windowsaccessbridge.dll"), + env.Dir("#include/javaAccessBridge32").File(jabDllName), + Copy("$TARGET", "$SOURCE"), ) - diff --git a/nvdaHelper/liblouis/sconscript b/nvdaHelper/liblouis/sconscript index d2704b2bc1d..c98d4900e66 100644 --- a/nvdaHelper/liblouis/sconscript +++ b/nvdaHelper/liblouis/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # A part of NonVisual Desktop Access (NVDA) # Copyright (C) 2011-2025 NV Access Limited, Joseph Lee, 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. @@ -15,7 +16,7 @@ Import( [ "thirdPartyEnv", "sourceDir", - ] + ], ) sourceDir: Base = sourceDir thirdPartyEnv: Environment = thirdPartyEnv @@ -29,7 +30,7 @@ unitTestTablesDir = env.Dir("#tests/unit/brailleTables") signExec = env["signExec"] if (bool(env["certFile"]) ^ bool(env["apiSigningToken"])) else None RE_AC_INIT = re.compile( - r"^AC_INIT\(\[(?P.*)\], \[(?P.*)\], \[(?P.*)\], \[(?P.*)\], \[(?P.*)\]\)" + r"^AC_INIT\(\[(?P.*)\], \[(?P.*)\], \[(?P.*)\], \[(?P.*)\], \[(?P.*)\]\)", ) @@ -48,7 +49,7 @@ clangDirs = glob.glob(os.path.join(find_vc_pdir(env.get("MSVC_VERSION"), env), r if len(clangDirs) == 0: raise RuntimeError( "Could not find the Clang compiler. " - "Perhaps the C++ Clang tools for Windows component in visual Studio is not installed" + "Perhaps the C++ Clang tools for Windows component in visual Studio is not installed", ) env["CC"] = "clang-cl" env["M4"] = f'"{env.File("#miscdeps/tools/m4.exe")}"' @@ -72,7 +73,7 @@ env.Append( "WIDECHARS_ARE_UCS4", # Tell liblouis.h that we're exporting liblouis dll functions, not importing them. "_EXPORTING", - ] + ], ) env.Prepend(CPPPATH=[".", louisSourceDir]) @@ -80,7 +81,9 @@ env.Prepend(CPPPATH=[".", louisSourceDir]) env["CPPDEFINES"].remove("UNICODE") liblouisH = env.Substfile( - "liblouis.h", louisSourceDir.File("liblouis.h.in"), SUBST_DICT={"@WIDECHAR_TYPE@": "unsigned int"} + "liblouis.h", + louisSourceDir.File("liblouis.h.in"), + SUBST_DICT={"@WIDECHAR_TYPE@": "unsigned int"}, ) sourceFiles = [ diff --git a/nvdaHelper/local/sconscript b/nvdaHelper/local/sconscript index ce3a618d416..d043948506e 100644 --- a/nvdaHelper/local/sconscript +++ b/nvdaHelper/local/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ @@ -17,7 +18,7 @@ Import( "env", "detoursLib", "apiHookObj", - ] + ], ) winIPCUtilsObj = env.Object("./winIPCUtils", "../common/winIPCUtils.cpp") diff --git a/nvdaHelper/localWin10/sconscript b/nvdaHelper/localWin10/sconscript index bad1a590f49..7be2268f90d 100644 --- a/nvdaHelper/localWin10/sconscript +++ b/nvdaHelper/localWin10/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvaccess.org/ diff --git a/nvdaHelper/remote/sconscript b/nvdaHelper/remote/sconscript index a553d40d3bd..7b039e86f3e 100644 --- a/nvdaHelper/remote/sconscript +++ b/nvdaHelper/remote/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ @@ -18,7 +19,7 @@ Import( "ia2RPCStubs", "detoursLib", "apiHookObj", - ] + ], ) winIPCUtilsObj = env.Object("./winIPCUtils", "../common/winIPCUtils.cpp") diff --git a/nvdaHelper/remoteLoader/sconscript b/nvdaHelper/remoteLoader/sconscript index 3bc427342f9..de3de067f04 100644 --- a/nvdaHelper/remoteLoader/sconscript +++ b/nvdaHelper/remoteLoader/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ diff --git a/nvdaHelper/sonic/sconscript b/nvdaHelper/sonic/sconscript index d7eae37d963..74483725574 100644 --- a/nvdaHelper/sonic/sconscript +++ b/nvdaHelper/sonic/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # A part of NonVisual Desktop Access (NVDA) # This file is covered by the GNU General Public License. # See the file COPYING for more details. @@ -9,7 +10,7 @@ thirdPartyEnv: SCons.Environment.Environment Import( [ "thirdPartyEnv", - ] + ], ) sonicSrcDir = Dir("#include/sonic") @@ -18,7 +19,7 @@ env: SCons.Environment.Environment = thirdPartyEnv.Clone() env.Append(CPPPATH=sonicSrcDir) -sonicObj = env.Object("sonic.obj", sonicSrcDir.File('sonic.c')) +sonicObj = env.Object("sonic.obj", sonicSrcDir.File("sonic.c")) sonicLib = env.SharedLibrary( target="sonic", diff --git a/nvdaHelper/uwp/sconscript b/nvdaHelper/uwp/sconscript index 2639e4e8d13..338cec8aee8 100644 --- a/nvdaHelper/uwp/sconscript +++ b/nvdaHelper/uwp/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # A part of NonVisual Desktop Access (NVDA) # Copyright (C) 2017-2025 NV Access Limited, 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. @@ -12,7 +13,7 @@ Import( [ "thirdPartyEnv", "sourceDir", - ] + ], ) env: Environment = thirdPartyEnv @@ -32,11 +33,11 @@ vcRedistDirs = glob.glob( f"{msvc[:2]}*", targetArch if (targetArch := env["TARGET_ARCH"]) != "x86_64" else "x64", f"Microsoft.VC{msvc.replace('.', '')}.CRT", - ) + ), ) if len(vcRedistDirs) == 0: raise RuntimeError( - "Could not locate vc redistributables. Perhaps the Universal Windows Platform component in visual Studio is not installed" + "Could not locate vc redistributables. Perhaps the Universal Windows Platform component in visual Studio is not installed", ) vcRedistDirs.sort(reverse=True) vcRedistLibs = ["msvcp140.dll", "vccorlib140.dll", "vcruntime140.dll", "vcruntime140_1.dll"] @@ -51,5 +52,5 @@ for fn in vcRedistLibs: break else: raise RuntimeError( - f"Could not locate {fn}. Perhaps the Universal Windows Platform component in visual Studio is not installed" + f"Could not locate {fn}. Perhaps the Universal Windows Platform component in visual Studio is not installed", ) diff --git a/nvdaHelper/vbufBackends/adobeAcrobat/sconscript b/nvdaHelper/vbufBackends/adobeAcrobat/sconscript index d667c877e83..719062d7ff4 100644 --- a/nvdaHelper/vbufBackends/adobeAcrobat/sconscript +++ b/nvdaHelper/vbufBackends/adobeAcrobat/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ @@ -16,7 +17,7 @@ Import( [ "env", "acrobatAccessRPCStubs", - ] + ], ) adobeAcrobatBackendLib = [ diff --git a/nvdaHelper/vbufBackends/gecko_ia2/sconscript b/nvdaHelper/vbufBackends/gecko_ia2/sconscript index 1809c3237c5..2ceac17759c 100644 --- a/nvdaHelper/vbufBackends/gecko_ia2/sconscript +++ b/nvdaHelper/vbufBackends/gecko_ia2/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ @@ -15,7 +16,7 @@ Import( [ "env", - ] + ], ) geckoBackendLib = env.Object("gecko_ia2.cpp") diff --git a/nvdaHelper/vbufBackends/lotusNotesRichText/sconscript b/nvdaHelper/vbufBackends/lotusNotesRichText/sconscript index 054a32fb1b6..d95b11ab833 100644 --- a/nvdaHelper/vbufBackends/lotusNotesRichText/sconscript +++ b/nvdaHelper/vbufBackends/lotusNotesRichText/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ @@ -15,7 +16,7 @@ Import( [ "env", - ] + ], ) lotusNotesRichTextBackendLib = env.Object("lotusNotesRichText.cpp") diff --git a/nvdaHelper/vbufBackends/mshtml/sconscript b/nvdaHelper/vbufBackends/mshtml/sconscript index b947852742e..a6f9bc5d212 100644 --- a/nvdaHelper/vbufBackends/mshtml/sconscript +++ b/nvdaHelper/vbufBackends/mshtml/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ @@ -15,7 +16,7 @@ Import( [ "env", - ] + ], ) mshtmlBackendLib = [ diff --git a/nvdaHelper/vbufBackends/webKit/sconscript b/nvdaHelper/vbufBackends/webKit/sconscript index c0818656a01..c95653c6885 100644 --- a/nvdaHelper/vbufBackends/webKit/sconscript +++ b/nvdaHelper/vbufBackends/webKit/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ @@ -15,7 +16,7 @@ Import( [ "env", - ] + ], ) webKitBackendLib = env.Object("webKit.cpp") diff --git a/nvdaHelper/vbufBase/sconscript b/nvdaHelper/vbufBase/sconscript index 9c5015dd75d..467dfa3c2af 100644 --- a/nvdaHelper/vbufBase/sconscript +++ b/nvdaHelper/vbufBase/sconscript @@ -1,7 +1,8 @@ +#!/usr/bin/env python3 Import( [ "env", - ] + ], ) vbufBaseObjs = [ diff --git a/projectDocs/dev/developerGuide/sconscript b/projectDocs/dev/developerGuide/sconscript index 348f3a99308..c3f12b12d78 100644 --- a/projectDocs/dev/developerGuide/sconscript +++ b/projectDocs/dev/developerGuide/sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # A part of NonVisual Desktop Access (NVDA) # Copyright (C) 2019-2026 NV Access Limited # This file may be used under the terms of the GNU General Public License, version 2 or later, as modified by the NVDA license. @@ -27,7 +28,9 @@ htmlFile = env.Command( action=[f'@"{sys.executable}" source/md2html.py -t developerGuide "$SOURCE" "$TARGET"'], ) devGuide = env.Command( - target=userDocsDir.File("developerGuide.html"), source=htmlFile, action=Move("$TARGET", "$SOURCE") + target=userDocsDir.File("developerGuide.html"), + source=htmlFile, + action=Move("$TARGET", "$SOURCE"), ) env.Alias("developerGuide", devGuide) @@ -71,7 +74,7 @@ sphinxAPIDocs = env.Command( "$TARGET", "$SOURCE", # Module sources ] - + [f"{sourceDir}\\{f}" for f in ignorePaths] + + [f"{sourceDir}\\{f}" for f in ignorePaths], ], ) sphinxHtml = env.Command( @@ -86,7 +89,7 @@ sphinxHtml = env.Command( "html", "projectDocs/dev/developerGuide", # Source directory "$TARGET", # Build directory - ] + ], ], ) devDocs_nvda = env.Command(devDocsOutputDir.Dir("NVDA"), sphinxHtml, Move("$TARGET", "$SOURCE")) diff --git a/sconstruct b/sconstruct index e904a03f4f9..201bfa5085a 100755 --- a/sconstruct +++ b/sconstruct @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # A part of NonVisual Desktop Access (NVDA) # Copyright (C) 2010-2025 NV Access Limited, James Teh, Michael Curran, Peter Vágner, Joseph Lee, # Reef Turner, Babbage B.V., Leonard de Ruijter, Łukasz Golonka, Accessolutions, Julien Cochuyt, @@ -5,15 +6,12 @@ # 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 copy import multiprocessing import os -import shutil import platform import sys from pathlib import Path -from SCons.Errors import UserError # Ensure we are inside the Python virtual environment, and that it is started with uv virtualEnv = os.getenv("VIRTUAL_ENV") @@ -21,13 +19,12 @@ uv = os.getenv("uv") if not virtualEnv or not uv or Path.cwd() != Path(virtualEnv).parent: print( "Error: SCons was started outside NVDA's build system Python virtual environment.\n" - "SCons must be executed using scons.bat in the root of this repository." + "SCons must be executed using scons.bat in the root of this repository.", ) sys.exit(1) import time # noqa: E402 import importlib.util # noqa: E402 -import winreg # noqa: E402 def recursiveCopy(env, targetDir, sourceDir): @@ -77,7 +74,7 @@ vars.Add( "The certificate file with which to sign executables", "", lambda key, val, env: not val or PathVariable.PathIsFile(key, val, env), - ) + ), ) vars.Add("certPassword", "The password for the private key in the signing certificate", "") vars.Add( @@ -92,7 +89,7 @@ vars.Add( "The directory where the final built archives and such will be placed", "output", PathVariable.PathIsDirCreate, - ) + ), ) vars.Add( ListVariable( @@ -100,7 +97,7 @@ vars.Add( "a list of debugging features you require", "none", ["debugCRT", "RTC", "analyze"], - ) + ), ) vars.Add( EnumVariable( @@ -108,7 +105,7 @@ vars.Add( "The level of logging you wish to see, lower is more verbose", "15", allowed_values=[str(x) for x in range(60)], - ) + ), ) # Base environment for this and sub sconscripts @@ -268,7 +265,9 @@ projectRCSubstDict = { resFile = env.RES( target="build/nvda.res", source=env.Substfile( - target="build/nvda.rc", source="nvdaHelper/nvda.rc.subst", SUBST_DICT=projectRCSubstDict + target="build/nvda.rc", + source="nvdaHelper/nvda.rc.subst", + SUBST_DICT=projectRCSubstDict, ), ) env32["projectResFile"] = resFile @@ -310,7 +309,11 @@ envArm64.SConscript( ) envArm64EC.SConscript( "nvdaHelper/archBuild_sconscript", - exports={"env": envArm64EC, "clientInstallDir": clientDir.Dir("arm64ec"), "libInstallDir": sourceLibDirArm64EC}, + exports={ + "env": envArm64EC, + "clientInstallDir": clientDir.Dir("arm64ec"), + "libInstallDir": sourceLibDirArm64EC, + }, variant_dir="build/arm64ec", ) @@ -390,20 +393,22 @@ def NVDADistGenerator(target, source, env, for_signature): updateVersionType = env["updateVersionType"] or None # 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, + 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, + ), ) - ) - # In Python 3 write returns the number of characters written, - # which scons treats as an error code. - and None + # In Python 3 write returns the number of characters written, + # which scons treats as an error code. + and None + ), ] buildCmd = ["cd", source[0].path, "&&", sys.executable] @@ -428,9 +433,9 @@ def NVDADistGenerator(target, source, env, for_signature): for prog in executablesToSign: path = os.path.join(target[0].abspath, prog) action.append( - lambda target, source, env, pathByVal=path: env["signExec"]( - [File(pathByVal)], source, env - ) if os.path.isfile(pathByVal) else None + lambda target, source, env, pathByVal=path: ( + env["signExec"]([File(pathByVal)], source, env) if os.path.isfile(pathByVal) else None + ), ) action.extend((Delete(buildVersionFn), Delete(importlib.util.cache_from_source(buildVersionFn)))) @@ -506,7 +511,7 @@ uninstGen = env.Command( "/DUNINSTEXE=%s" % uninstFile.abspath, "/DINSTEXE=${TARGET.abspath}", "$SOURCE", - ] + ], ], ) uninstaller = env.Command(uninstFile, uninstGen, [uninstGen]) @@ -514,7 +519,8 @@ if certFile or apiSigningToken: env.AddPostAction(uninstaller, [env["signExec"]]) devDocTargets = env.SConscript( - "projectDocs/dev/developerGuide/sconscript", exports=["env", "outputDir", "sourceDir", "userDocsDir"] + "projectDocs/dev/developerGuide/sconscript", + exports=["env", "outputDir", "sourceDir", "userDocsDir"], ) dist = env.NVDADist("dist", [sourceDir, userDocsDir], uiAccess=bool(certFile) or bool(apiSigningToken)) env.Depends(dist, uninstaller) @@ -543,7 +549,7 @@ launcher = env.Command( "/DNVDADistDir=${SOURCES[1].abspath}", "/DLAUNCHEREXE=${TARGET.abspath}", "$SOURCE", - ] + ], ], ) if certFile or apiSigningToken: @@ -551,12 +557,16 @@ if certFile or apiSigningToken: env.Alias("launcher", launcher) clientArchive = env.ZipArchive( - outputDir.File("%s_controllerClient.zip" % outFilePrefix), clientDir, relativeTo=clientDir + outputDir.File("%s_controllerClient.zip" % outFilePrefix), + clientDir, + relativeTo=clientDir, ) env.Alias("client", clientArchive) outputStylesFile = env.Command( - outputDir.File("styles.css"), userDocsDir.File("styles.css"), Copy("$TARGET", "$SOURCE") + outputDir.File("styles.css"), + userDocsDir.File("styles.css"), + Copy("$TARGET", "$SOURCE"), ) outputHeadingStylesFile = env.Command( outputDir.File("numberedHeadings.css"), @@ -573,13 +583,17 @@ env.Depends(changesFile, outputStylesFile) env.Alias("changes", changesFile) userGuideFile = env.Command( - outputDir.File("userGuide.html"), userDocsDir.File("en/userGuide.html"), Copy("$TARGET", "$SOURCE") + outputDir.File("userGuide.html"), + userDocsDir.File("en/userGuide.html"), + Copy("$TARGET", "$SOURCE"), ) env.Depends(userGuideFile, outputStylesFile) env.Alias("userGuide", userGuideFile) keyCommandsFile = env.Command( - outputDir.File("keyCommands.html"), userDocsDir.File("en/keyCommands.html"), Copy("$TARGET", "$SOURCE") + outputDir.File("keyCommands.html"), + userDocsDir.File("en/keyCommands.html"), + Copy("$TARGET", "$SOURCE"), ) env.Depends(keyCommandsFile, outputStylesFile) env.Depends(keyCommandsFile, userGuideFile) @@ -620,8 +634,8 @@ def makePot(target, source, env): "--language=python", # Too many files to list on commandline, use a file list instead. f"--files-from={potSourceFileList.abspath}", - ] - ] + ], + ], ) != 0 ): @@ -708,22 +722,22 @@ synthDriverHost32Runtime = env.Command( source="#runtime-builders/synthDriverHost32/setup-runtime.py", chdir=Dir("#runtime-builders/synthDriverHost32"), action=[ - [ - "uv", - "run", - "-v", - "--no-active", - "--directory", - ".", - "python", - "setup-runtime.py", - "--dest-dir", - "dist", - "--version", - version, - "--publisher", - publisher, - ], + [ + "uv", + "run", + "-v", + "--no-active", + "--directory", + ".", + "python", + "setup-runtime.py", + "--dest-dir", + "dist", + "--version", + version, + "--publisher", + publisher, + ], r"rmdir /s /q ..\..\source\lib\x86\synthDriverHost-runtime || exit 0", r"xcopy /e /i /y dist ..\..\source\lib\x86\synthDriverHost-runtime", ], @@ -734,9 +748,25 @@ env.Alias("synthDriverHost32Runtime", synthDriverHost32Runtime) # Copy sapi5 and sonic Python files to the _synthDrivers32 directory # As they require no changes, but need to be in an isolated directory for 32 bit. -env.Command(sourceDir.File('_synthDrivers32/_sonic.py'), sourceDir.File('synthDrivers/_sonic.py'), Copy("$TARGET", "$SOURCE")) -env.Command(sourceDir.File('_synthDrivers32/_sapi5.py'), sourceDir.File('synthDrivers/sapi5.py'), Copy("$TARGET", "$SOURCE")) +env.Command( + sourceDir.File("_synthDrivers32/_sonic.py"), + sourceDir.File("synthDrivers/_sonic.py"), + Copy("$TARGET", "$SOURCE"), +) +env.Command( + sourceDir.File("_synthDrivers32/_sapi5.py"), + sourceDir.File("synthDrivers/sapi5.py"), + Copy("$TARGET", "$SOURCE"), +) # Parts of the speech package are quired by the 32 bit synthDriver host tunrime -env.Command(sourceDir.File('_bridge/runtimes/synthDriverHost/speech/commands.py'), sourceDir.File('speech/commands.py'), Copy("$TARGET", "$SOURCE")) -env.Command(sourceDir.File('_bridge/runtimes/synthDriverHost/speech/types.py'), sourceDir.File('speech/types.py'), Copy("$TARGET", "$SOURCE")) +env.Command( + sourceDir.File("_bridge/runtimes/synthDriverHost/speech/commands.py"), + sourceDir.File("speech/commands.py"), + Copy("$TARGET", "$SOURCE"), +) +env.Command( + sourceDir.File("_bridge/runtimes/synthDriverHost/speech/types.py"), + sourceDir.File("speech/types.py"), + Copy("$TARGET", "$SOURCE"), +) diff --git a/source/_bridge/runtimes/synthDriverHost/main.pyw b/source/_bridge/runtimes/synthDriverHost/main.pyw index 5a10acdf5b5..ddabb48f192 100644 --- a/source/_bridge/runtimes/synthDriverHost/main.pyw +++ b/source/_bridge/runtimes/synthDriverHost/main.pyw @@ -12,6 +12,8 @@ import tempfile from winBindings.kernel32 import GetCurrentProcessId oldRecordFactory = logging.getLogRecordFactory() + + def recordFactory(*args, **kwargs): record = oldRecordFactory(*args, **kwargs) frame = inspect.currentframe() @@ -27,6 +29,8 @@ def recordFactory(*args, **kwargs): # co_qualname may be unavailable for some frames; in that case, keep the default record.name pass return record + + logging.setLogRecordFactory(recordFactory) exeName = os.path.splitext(os.path.basename(sys.executable))[0] @@ -36,7 +40,7 @@ logging.basicConfig( filename=logPath, filemode="w", level=logging.DEBUG, - format="%(levelname)s - %(module)s.%(name)s (%(asctime)s):\n%(message)s" + format="%(levelname)s - %(module)s.%(name)s (%(asctime)s):\n%(message)s", ) log = logging.getLogger(exeName) # No comtypes debug logging @@ -46,6 +50,7 @@ log.info(f"Logging initialized, log file: {logPath}") try: gettext.install("nvda", names=["pgettext", "npgettext", "ngettext"]) import core + core.main() except Exception: log.exception("Unhandled exception") diff --git a/source/comInterfaces_sconscript b/source/comInterfaces_sconscript index 58f2b4240bc..92ce5c7a193 100755 --- a/source/comInterfaces_sconscript +++ b/source/comInterfaces_sconscript @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ### # This file is a part of the NVDA project. # URL: http://www.nvda-project.org/ @@ -101,7 +102,8 @@ else: with open(path, "r") as interfaceFile: fileContent = interfaceFile.read() fileContent = importPattern.sub( - codeReplacer(importTemplate, indentedGroups=("importList",)), fileContent + codeReplacer(importTemplate, indentedGroups=("importList",)), + fileContent, ) with open(path, "w") as interfaceFile: