|
17 | 17 | import sys |
18 | 18 | from types import ModuleType |
19 | 19 | from typing import ( |
| 20 | + Any, |
20 | 21 | Dict, |
21 | 22 | List, |
22 | 23 | Optional, |
|
42 | 43 | import exceptions |
43 | 44 | import extensionPoints |
44 | 45 | from fileUtils import getFileVersionInfo |
| 46 | +import globalVars |
| 47 | + |
45 | 48 |
|
46 | 49 | _KNOWN_IMPORTERS_T = Union[importlib.machinery.FileFinder, zipimport.zipimporter] |
47 | 50 | # Dictionary of processID:appModule pairs used to hold the currently running modules |
48 | 51 | runningTable: Dict[int, AppModule] = {} |
49 | | -#: The process ID of NVDA itself. |
50 | | -NVDAProcessID=None |
51 | 52 | _CORE_APP_MODULES_PATH: os.PathLike = appModules.__path__[0] |
52 | 53 | _importers: Optional[List[_KNOWN_IMPORTERS_T]] = None |
53 | 54 | _getAppModuleLock=threading.RLock() |
@@ -80,6 +81,22 @@ class processEntry32W(ctypes.Structure): |
80 | 81 | ] |
81 | 82 |
|
82 | 83 |
|
| 84 | +def __getattr__(attrName: str) -> Any: |
| 85 | + """Module level `__getattr__` used to preserve backward compatibility. |
| 86 | + The module level variable `NVDAProcessID` is deprecated |
| 87 | + and usages should be replaced with `globalVars.appPid`. |
| 88 | + We cannot simply assign the value from `globalVars` to the old attribute |
| 89 | + since add-ons are initialized before `appModuleHandler` |
| 90 | + and when `appModuleHandler` was not yet initialized the variable was set to `None`. |
| 91 | + """ |
| 92 | + if attrName == "NVDAProcessID": |
| 93 | + log.warning("appModuleHandler.NVDAProcessID is deprecated, use globalVars.appPid instead.") |
| 94 | + if initialize._alreadyInitialized: |
| 95 | + return globalVars.appPid |
| 96 | + return None |
| 97 | + raise AttributeError(f"module {repr(__name__)} has no attribute {repr(attrName)}") |
| 98 | + |
| 99 | + |
83 | 100 | def _warnDeprecatedAliasAppModule() -> None: |
84 | 101 | """This function should be executed at the top level of an alias App Module, |
85 | 102 | to log a deprecation warning when the module is imported. |
@@ -195,7 +212,7 @@ def getAppNameFromProcessID(processID: int, includeExt: bool = False) -> str: |
195 | 212 | C{False} to exclude it. |
196 | 213 | @returns: application name |
197 | 214 | """ |
198 | | - if processID==NVDAProcessID: |
| 215 | + if processID == globalVars.appPid: |
199 | 216 | return "nvda.exe" if includeExt else "nvda" |
200 | 217 | FSnapshotHandle = winKernel.kernel32.CreateToolhelp32Snapshot (2,0) |
201 | 218 | FProcessEntry32 = processEntry32W() |
@@ -345,13 +362,19 @@ def reloadAppModules(): |
345 | 362 | # Fetch and cache right away; the process could die any time. |
346 | 363 | obj.appModule |
347 | 364 |
|
| 365 | + |
348 | 366 | def initialize(): |
349 | 367 | """Initializes the appModule subsystem. |
350 | 368 | """ |
351 | | - global NVDAProcessID,_importers |
352 | | - NVDAProcessID=os.getpid() |
| 369 | + global _importers |
353 | 370 | config.addConfigDirsToPythonPackagePath(appModules) |
354 | 371 | _importers=list(pkgutil.iter_importers("appModules.__init__")) |
| 372 | + if not initialize._alreadyInitialized: |
| 373 | + initialize._alreadyInitialized = True |
| 374 | + |
| 375 | + |
| 376 | +initialize._alreadyInitialized = False |
| 377 | + |
355 | 378 |
|
356 | 379 | def terminate(): |
357 | 380 | for processID, app in runningTable.items(): |
|
0 commit comments