addonHandler package

class addonHandler.AddonsState(dict=None, /, **kwargs)

Bases: UserDict[AddonStateCategory, CaseInsensitiveSet[str]]

Subclasses collections.UserDict to preserve backwards compatibility. AddonStateCategory string enums mapped to a set of the add-on “name/id” currently in that state. Add-ons that have the same ID except differ in casing cause a path collision, as add-on IDs are installed to a case insensitive path. Therefore add-on IDs should be treated as case insensitive.

static _generateDefaultStateContent() Dict[AddonStateCategory, CaseInsensitiveSet[str]]
data: Dict[AddonStateCategory, CaseInsensitiveSet[str]]
manualOverridesAPIVersion: MajorMinorPatch
property statePath: PathLike

Returns path to the state file.

setDefaultStateValues() None
fromPickledDict(pickledState: Dict[str, Set[str] | Tuple[int, int, int] | MajorMinorPatch]) None
toDict() Dict[str, Set[str] | Tuple[int, int, int]]
load() None

Populates state with the default content and then loads values from the config.

removeStateFile() None
save() None

Saves content of the state to a file unless state is empty in which case this would be pointless.

cleanupRemovedDisabledAddons() None

Versions of NVDA before #12792 failed to remove add-on from list of disabled add-ons during uninstallation. As a result after reinstalling add-on with the same name it was disabled by default confusing users. Fix this by removing all add-ons no longer present in the config from the list of disabled add-ons in the state.

_cleanupCompatibleAddonsFromDowngrade() None
_abc_impl = <_abc._abc_data object>
addonHandler.getRunningAddons() AddonHandlerModelGeneratorT

Returns currently loaded add-ons.

addonHandler.getIncompatibleAddons(currentAPIVersion=(2024, 4, 0), backCompatToAPIVersion=(2024, 1, 0)) AddonHandlerModelGeneratorT

Returns a generator of the add-ons that are not compatible.

addonHandler.removeFailedDeletion(path: PathLike)
addonHandler.disableAddonsIfAny()

Disables add-ons if told to do so by the user from add-on store. This is usually executed before refreshing the list of available add-ons.

addonHandler.initialize()

Initializes the add-ons subsystem.

addonHandler.terminate()

Terminates the add-ons subsystem.

addonHandler._getDefaultAddonPaths() list[str]

Returns paths where addons can be found. For now, only <userConfig>addons is supported.

addonHandler._getAvailableAddonsFromPath(path: str, isFirstLoad: bool = False) AddonHandlerModelGeneratorT

Gets available add-ons from path. An addon is only considered available if the manifest file is loaded with no errors. @param path: path from where to find addon directories.

addonHandler.getAvailableAddons(refresh: bool = False, filterFunc: Callable[['Addon'], bool] | None = None, isFirstLoad: bool = False) AddonHandlerModelGeneratorT

Gets all available addons on the system. @param refresh: Whether or not to query the file system for available add-ons. @param filterFunc: A function that allows filtering of add-ons. It takes an L{Addon} as its only argument and returns a C{bool} indicating whether the add-on matches the provided filter. : isFirstLoad: Should add-ons that are pending installations / removal from the file system be installed / removed.

addonHandler.installAddonBundle(bundle: AddonBundle) Addon | None

Extracts an Addon bundle in to a unique subdirectory of the user addons directory, marking the addon as needing ‘install completion’ on NVDA restart.

Parameters:

bundle – The add-on bundle to install.

The bundle._installExceptions property is modified to store any raised exceptions during the installation process.

Returns:

The extracted add-on object, or None if the add-on bundle fails to be extracted.

Regardless if the add-on installation failed, the created add-on object from the bundle should be returned to give caller a chance to clean-up modules imported as part of install tasks. This clean-up cannot be done here, as install tasks are blocking, and this function returns as soon as they’re started, so removing modules before they’re done may cause unpredictable effects.

exception addonHandler.AddonError

Bases: Exception

Represents an exception coming from the addon subsystem.

class addonHandler.AddonBase(*args, **kwargs)

Bases: SupportsAddonState, SupportsVersionCheck, ABC

The base class for functionality that is available both for add-on bundles and add-ons on the file system. Subclasses should at least implement L{manifest}.

property name: str

A unique name, the id of the add-on.

property version: str

A display version. Not necessarily semantic

property minimumNVDAVersion: Tuple[int, int, int]
property lastTestedNVDAVersion: Tuple[int, int, int]
abstract property manifest: AddonManifest
property _addonStoreData: 'InstalledAddonStoreModel' | None
property _addonGuiModel: AddonManifestModel
_abc_impl = <_abc._abc_data object>
_is_protocol = False
class addonHandler.Addon(path: str)

Bases: AddonBase

Represents an Add-on available on the file system.

Constructs an L{Addon} from. @param path: the base directory for the addon data.

property manifest: AddonManifest
completeInstall() str | None
requestRemove()

Marks this addon for removal on NVDA restart.

completeRemove(runUninstallTask: bool = True) None
addToPackagePath(package)

Adds this L{Addon} extensions to the specific package path if those exist. This allows the addon to “run” / be available because the package is able to search its path, looking for particular modules. This is used by the following: - globalPlugins - appModules - synthDrivers - brailleDisplayDrivers @param package: the python module representing the package. @type package: python module.

property _canBeEnabled: bool
enable(shouldEnable: bool) None

Sets this add-on to be disabled or enabled when NVDA restarts. @raises: AddonError on failure.

_getPathForInclusionInPackage(package)
loadModule(name: str) module

loads a python module from the addon directory @param name: the module name @raises: Any exception that can be raised when importing a module,

such as NameError, AttributeError, ImportError, etc. a ValueError is raised when the module name is invalid.

getTranslationsInstance(domain='nvda')

Gets the gettext translation instance for this add-on. <addon-path>locale will be used to find .mo files, if exists. If a translation file is not found the default fallback null translation is returned. @param domain: the translation domain to retrieve. The ‘nvda’ default should be used in most cases. @returns: the gettext translation class.

runInstallTask(taskName: Literal['onInstall', 'onUninstall'], *args, **kwargs) None

Executes the function having the given taskName with the given args and kwargs, in the add-on’s installTasks module if it exists.

_cleanupAddonImports() None
getDocFilePath(fileName: str | None = None) str | None

Get the path to a documentation file for this add-on. The file should be located in C{doclangfile} inside the add-on, where C{lang} is the language code and C{file} is the requested file name. Failing that, the language without country is tried. English is tried as a last resort. An add-on can specify a default documentation file name via the docFileName parameter in its manifest. @param fileName: The requested file name or C{None} for the add-on’s default. @return: The path to the requested file or C{None} if it wasn’t found.

property isPendingInstall: bool

True if this addon has not yet been fully installed.

_abc_impl = <_abc._abc_data object>
_is_protocol = False
addonHandler.getCodeAddon(obj=None, frameDist=1)

Returns the L{Addon} where C{obj} is defined. If obj is None the caller code frame is assumed to allow simple retrieval of “current calling addon”. @param obj: python object or None for default behaviour. @param frameDist: how many frames is the caller code. Only change this for functions in this module. @return: L{Addon} instance or None if no code does not belong to a add-on package. @rtype: C{Addon}

addonHandler.initTranslation()

Initializes the translation of an add-on so that the Gettext functions (_, ngettext, npgettext and pgettext) point to the add-on’s translation rather than to NVDA’s one. This function should be called at the top of any module containing translatable strings and belonging to an add-on. It cannot be called in a module that does not belong to an add-on (e.g. in a subdirectory of the scratchpad).

addonHandler._translatedManifestPaths(lang=None, forBundle=False)
class addonHandler.AddonBundle(bundlePath: str)

Bases: AddonBase

Represents the contents of an NVDA addon suitable for distribution. The bundle is compressed using the zip file format. Manifest information is available without the need for extraction.

Constructs an L{AddonBundle} from a filename. @param bundlePath: The path for the bundle file.

_installExceptions: list[Exception]

Exceptions thrown during the installation process.

extract(addonPath: str | None = None)

Extracts the bundle content to the specified path. The addon will be extracted to L{addonPath} @param addonPath: Path where to extract contents.

property manifest: AddonManifest

Gets the manifest for the represented Addon.

_abc_impl = <_abc._abc_data object>
_is_protocol = False
addonHandler.createAddonBundleFromPath(path, destDir=None)

Creates a bundle from a directory that contains a a addon manifest file.

addonHandler._report_manifest_errors(manifest)
class addonHandler.AddonManifest(input, translatedInput=None)

Bases: ConfigObj

Add-on manifest file. It contains metadata about an NVDA add-on package.

Constructs an L{AddonManifest} instance from manifest string data @param input: data to read the manifest information @type input: a fie-like object. @param translatedInput: translated manifest input @type translatedInput: file-like object

configspec = {'author': 'string()', 'brailleTables': {'__many__': {'contracted': 'boolean(default=false)', 'displayName': 'string()', 'input': 'boolean(default=true)', 'output': 'boolean(default=true)'}}, 'description': 'string(default=None)', 'docFileName': 'string(default=None)', 'lastTestedNVDAVersion': 'apiVersion(default="0.0.0")', 'minimumNVDAVersion': 'apiVersion(default="0.0.0")', 'name': 'string()', 'summary': 'string()', 'symbolDictionaries': {'__many__': {'displayName': 'string()', 'mandatory': 'boolean(default=false)'}}, 'url': 'string(default=None)', 'version': 'string()'}
property errors
_validateApiVersionRange()
addonHandler.validate_apiVersionString(value: str) Tuple[int, int, int]

@raises: configobj.validate.ValidateError on validation error

Submodules

addonHandler.addonVersionCheck module

addonHandler.addonVersionCheck.hasAddonGotRequiredSupport(addon: SupportsVersionCheck, currentAPIVersion: Tuple[int, int, int] = (2024, 4, 0)) bool

True if NVDA provides the add-on with an API version high enough to meet the add-on’s minimum requirements

addonHandler.addonVersionCheck.isAddonTested(addon: SupportsVersionCheck, backwardsCompatToVersion: Tuple[int, int, int] = (2024, 1, 0)) bool

True if this add-on is tested for the given API version. By default, the current version of NVDA is evaluated.

addonHandler.addonVersionCheck.isAddonCompatible(addon: SupportsVersionCheck, currentAPIVersion: Tuple[int, int, int] = (2024, 4, 0), backwardsCompatToVersion: Tuple[int, int, int] = (2024, 1, 0)) bool

Tests if the addon is compatible. The compatibility is defined by having the required features in NVDA, and by having been tested / built against an API version that is still supported by this version of NVDA.

addonHandler.packaging module

Functions to add python modules within addon directories to python module paths.

addonHandler.packaging.iskeyword()

x.__contains__(y) <==> y in x.

addonHandler.packaging.initializeModulePackagePaths()

Initializes the module package paths for drivers and plugins. This ensures that drivers (such as braille display drivers) or plugins (such as app modules) can be discovered by NVDA.

addonHandler.packaging.addDirsToPythonPackagePath(module: module, subdir: str | None = None)

Add add-on and scratchpath directories for a module to the search path (__path__) of a Python package. C{subdir} is added to each directory. It defaults to the name of the Python package. @param module: The root module of the package. @param subdir: The subdirectory to be used, C{None} for the name of C{module}.

addonHandler.packaging.isModuleName(name: str) bool

When adding a module to sys.modules, it is important to check module name validity. the L{str.isidentifier} method checks whether a string is a valid python identifier, however this includes identifiers like ‘def’ and ‘class’, which are definitely invalid module names. Therefore a valid module name should be an identifier but not a keyword. A valid module name can also contain dots, but a dot is considered invalid in identifiers. Therefore, use dot as a split separator and check all the name parts independently. @param moduleName: De module name to check for naming conventions. @returns: Whether the module name is valid.