utils package

Submodules

utils.blockUntilConditionMet module

utils.blockUntilConditionMet.DEFAULT_INTERVAL_BETWEEN_EVAL_SECONDS = 0.1

The default interval (in seconds) between calls to the evaluator.

utils.blockUntilConditionMet._MIN_INTERVAL_BETWEEN_EVAL_SECONDS = 0.01

The minimum interval (in seconds) between calls to the evaluator. Small values for the interval can starve NVDA core, preventing it from being able to process queued events.

utils.blockUntilConditionMet.blockUntilConditionMet(getValue: ~typing.Callable[[], ~typing.Any], giveUpAfterSeconds: float, shouldStopEvaluator: ~typing.Callable[[~typing.Any], bool] = <function <lambda>>, intervalBetweenSeconds: float = 0.1) Tuple[bool, Any | None]

Repeatedly tries to get a value up until a time limit expires. Tries are separated by a time interval. The call will block until shouldStopEvaluator returns True when given the value, the default evaluator just returns the value converted to a boolean. @param getValue: Get the value to be tested by shouldStopEvaluator. @param giveUpAfterSeconds: The max number of seconds to block for. @param shouldStopEvaluator: Given the last value from getValue, is the condition met? When True is returned, stop blocking. @param intervalBetweenSeconds: The approximate period (seconds) between each test of getValue. Small values can starve NVDA core preventing it from being able to process queued events. Must be greater than _MIN_INTERVAL_BETWEEN_EVAL_SECONDS, higher is recommended. @return: A tuple, (True, value) if evaluator condition is met, otherwise (False, None)

utils.caseInsensitiveCollections module

class utils.caseInsensitiveCollections.CaseInsensitiveSet(*args: Iterable[str])

Bases: set

add(_CaseInsensitiveSet__element: str) None

Add an element to a set.

This has no effect if the element is already present.

discard(_CaseInsensitiveSet__element: str) None

Remove an element from a set if it is a member.

Unlike set.remove(), the discard() method does not raise an exception when an element is missing from the set.

remove(_CaseInsensitiveSet__element: str) None

Remove an element from a set; it must be a member.

If the element is not a member, raise a KeyError.

utils.displayString module

class utils.displayString._DisplayStringEnumMixinMeta(name, bases, namespace, /, **kwargs)

Bases: ABCMeta, EnumType

This helps correct the Method Resolution Order (MRO) when using the _DisplayStringEnumMixin. When creating an Enum with a Mixin, Python suggest an ordering of class EnumWithMixin(Mixin, type, EnumClass):. This creates a metaclass conflict as both _DisplayStringEnumMixin and Enum both have metaclasses, ABCMeta and EnumMeta. This requires a new MetaClass which subclasses both of these. This follows the same ordering of the EnumWithMixin usage. See _DisplayStringEnumMixin.

class utils.displayString._DisplayStringEnumMixin

Bases: ABC

This mixin can be used with a class which subclasses Enum to provided translated display strings for members of the enum. The abstract properties must be overridden. To be used with _DisplayStringEnumMixinMeta. Usage: ``` class ExampleEnum(_DisplayStringEnumMixin, str, Enum, metaclass=_DisplayStringEnumMixinMeta):

pass

class ExampleIntEnum(_DisplayStringEnumMixin, IntEnum, metaclass=_DisplayStringEnumMixinMeta):

pass

```

abstract property _displayStringLabels: dict[Self, str]

Specify a dictionary which takes members of the Enum and returns the translated display string.

property displayString: str

@return: The translated UI display string that should be used for this value of the enum.

_abc_impl = <_abc._abc_data object>
class utils.displayString.DisplayStringEnum(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: _DisplayStringEnumMixin, Enum

An Enum class that adds a displayString property defined by _displayStringLabels

_generate_next_value_(start, count, last_values)

Generate the next value when not given.

name: the name of the member start: the initial start value or None count: the number of existing members last_values: the list of values assigned

_new_member_(**kwargs)

Create and return a new object. See help(type) for accurate signature.

_use_args_ = False
_member_names_ = []
_member_map_ = {}
_value2member_map_ = {}
_unhashable_values_ = []
_member_type_

alias of object

_value_repr_ = None
class utils.displayString.DisplayStringFlag(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: _DisplayStringEnumMixin, Flag

A Flag class that adds a displayString property defined by _displayStringLabels

_generate_next_value_(start, count, last_values)

Generate the next value when not given.

name: the name of the member start: the initial start value or None count: the number of existing members last_values: the last value assigned or None

_new_member_(**kwargs)

Create and return a new object. See help(type) for accurate signature.

_use_args_ = False
_member_names_ = []
_member_map_ = {}
_value2member_map_ = {}
_unhashable_values_ = []
_member_type_

alias of object

_value_repr_ = None
_boundary_ = 'strict'
_flag_mask_ = 0
_singles_mask_ = 0
_all_bits_ = 0
_inverted_ = None
class utils.displayString.DisplayStringStrEnum(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: _DisplayStringEnumMixin, str, Enum

A str Enum class that adds a displayString property defined by _displayStringLabels

_generate_next_value_(start, count, last_values)

Generate the next value when not given.

name: the name of the member start: the initial start value or None count: the number of existing members last_values: the list of values assigned

_new_member_(**kwargs)

Create and return a new object. See help(type) for accurate signature.

_use_args_ = True
_member_names_ = []
_member_map_ = {}
_value2member_map_ = {}
_unhashable_values_ = []
_member_type_

alias of str

_value_repr_()

Return repr(self).

class utils.displayString.DisplayStringIntEnum(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: _DisplayStringEnumMixin, IntEnum

An IntEnum class that adds a displayString property defined by _displayStringLabels

_generate_next_value_(start, count, last_values)

Generate the next value when not given.

name: the name of the member start: the initial start value or None count: the number of existing members last_values: the list of values assigned

_new_member_(**kwargs)

Create and return a new object. See help(type) for accurate signature.

_use_args_ = True
_member_names_ = []
_member_map_ = {}
_value2member_map_ = {}
_unhashable_values_ = []
_member_type_

alias of int

_value_repr_()

Return repr(self).

class utils.displayString.DisplayStringIntFlag(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: _DisplayStringEnumMixin, IntFlag

An IntFlag class that adds a displayString property defined by _displayStringLabels

_generate_next_value_(start, count, last_values)

Generate the next value when not given.

name: the name of the member start: the initial start value or None count: the number of existing members last_values: the last value assigned or None

_new_member_(**kwargs)

Create and return a new object. See help(type) for accurate signature.

_use_args_ = True
_member_names_ = []
_member_map_ = {}
_value2member_map_ = {}
_unhashable_values_ = []
_member_type_

alias of int

_value_repr_()

Return repr(self).

_boundary_ = 'keep'
_flag_mask_ = 0
_singles_mask_ = 0
_all_bits_ = 0
_inverted_ = None

utils.localisation module

class utils.localisation.TimeOutputFormat(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: DisplayStringEnum

SECONDS = 1
MINUTES = 2
HOURS = 3
DAY = 4
DAYS = 5
property _displayStringLabels: Dict[TimeOutputFormat, str]

Specify a dictionary which takes members of the Enum and returns the translated display string.

static convertTimeDeltaToTimeOutputFormat(td: timedelta) TimeOutputFormat

Returns a TimeOutputFormat with the least leading zeros.

static parseTimeDeltaToFormatted(td: timedelta) str

utils.schedule module

class utils.schedule.ThreadTarget(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: Enum

When running a task, specify the thread to run the task on. ScheduleThread blocks until the scheduled task is complete. To avoid blocking the ScheduleThread, all tasks should be run on a separate thread. Using GUI or DAEMON thread targets ensures that the ScheduleThread is not blocked. CUSTOM thread target is used for tasks where the supplier of the task is responsible for running the task on a separate thread.

GUI = 1

Uses wx.CallAfter to run the job on the GUI thread. This is encouraged for tasks that interact with the GUI, such as dialogs.

DAEMON = 2

Uses threading.Thread(daemon=True) to run the job in the background.

CUSTOM = 3

No thread target. Runs directly and blocks scheduleThread. Authors of tasks are responsible for running the task on a separate thread to ensure that scheduleThread is not blocked.

exception utils.schedule.JobClashError

Bases: Exception

Raised when a job time clashes with an existing job.

class utils.schedule.ScheduleThread(*args, **kwargs)

Bases: Thread

This constructor should always be called with keyword arguments. Arguments are:

group should be None; reserved for future extension when a ThreadGroup class is implemented.

target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called.

name is the thread name. By default, a unique name is constructed of the form “Thread-N” where N is a small decimal number.

args is a list or tuple of arguments for the target invocation. Defaults to ().

kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}.

If a subclass overrides the constructor, it must make sure to invoke the base class constructor (Thread.__init__()) before doing anything else to the thread.

name = 'ScheduleThread'
KILL = <threading.Event at 0x16d95e90: unset>

Event which can be set to cease continuous run.

SLEEP_INTERVAL_SECS = 0.5

Note that the behaviour of ScheduleThread is to not run missed jobs. For example, if you’ve registered a job that should run every minute and you set a continuous run interval of one hour then your job won’t be run 60 times at each interval but only once.

DAILY_JOB_MINUTE_OFFSET = 3

Offset in minutes to schedule daily jobs. Daily scheduled jobs occur offset by X minutes to avoid overlapping jobs.

classmethod run()

Method representing the thread’s activity.

You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.

_calculateDailyTimeOffset() str
scheduleDailyJobAtStartUp(task: Callable, queueToThread: ThreadTarget, *args, **kwargs) Job

Schedule a daily job to run at startup. Designed to handle clashes in a smart way to offset jobs. :param task: The task to run. :param queueToThread: The thread to run the task on. :param args: Arguments to pass to the task. :param kwargs: Keyword arguments to pass to the task. :return: The scheduled job.

scheduleDailyJob(task: Callable, cronTime: str, queueToThread: ThreadTarget, *args, **kwargs) Job

Schedule a daily job to run at specific times. :param task: The task to run. :param cronTime: The time to run the job using a valid cron string. It is recommended to use minute level precision at most. https://schedule.readthedocs.io/en/stable/examples.html#run-a-job-every-x-minute :param queueToThread: The thread to run the task on. :param args: Arguments to pass to the task. :param kwargs: Keyword arguments to pass to the task. :return: The scheduled job. :raises JobClashError: If the job’s next run clashes with an existing job’s next run.

scheduleJob(task: Callable, jobSchedule: Job, queueToThread: ThreadTarget, *args, **kwargs) Job

Schedule a job to run at specific times. :param task: The task to run. :param jobSchedule: The schedule to run the task on. Constructed using schedule e.g. schedule.every().day.at("**:15"). :param cronTime: The time to run the job at using a valid cron string. https://schedule.readthedocs.io/en/stable/examples.html#run-a-job-every-x-minute :param queueToThread: The thread to run the task on. :param args: Arguments to pass to the task. :param kwargs: Keyword arguments to pass to the task. :return: The scheduled job. :raises JobClashError: If the job’s next run clashes with an existing job’s next run.

utils.schedule.initialize()
utils.schedule.terminate()

utils.security module

utils.security.post_sessionLockStateChanged = <extensionPoints.Action object>

Notifies when a session lock or unlock event occurs.

Usage: ``` def onSessionLockStateChange(isNowLocked: bool):

‘’’ @param isNowLocked: True if new state is locked, False if new state is unlocked ‘’’ pass

post_sessionLockStateChanged.register(onSessionLockStateChange) post_sessionLockStateChanged.notify(isNowLocked=False) post_sessionLockStateChanged.unregister(onSessionLockStateChange) ```

utils.security.getSafeScripts() Set[scriptHandler._ScriptFunctionT]

Returns scripts which are safe to use on the Windows lockscreen. Not to be confused with the Windows sign-in screen, a secure screen.

utils.security.objectBelowLockScreenAndWindowsIsLocked(obj: NVDAObjects.NVDAObject, shouldLog: bool = True) bool

While Windows is locked, the current user session is still running, and below the lock screen exists the current user’s desktop.

Windows 10 and 11 doesn’t prevent object navigation below the lock screen.

If an object is above the lock screen, it is accessible and visible to the user through the Windows UX while Windows is locked. An object below the lock screen should only be accessible when Windows is unlocked, as it may contain sensitive information.

As such, NVDA must prevent accessing and reading objects below the lock screen when Windows is locked. @return: C{True} if the Windows 10/11 lockscreen is active and C{obj} is below the lock screen.

utils.security._isObjectAboveLockScreen(obj: NVDAObjects.NVDAObject) bool
utils.security._isObjectBelowLockScreen(obj: NVDAObjects.NVDAObject) bool

While Windows is locked, the current user session is still running, and below the lockscreen exists the current user’s desktop.

When Windows is locked, the foreground Window is usually LockApp, but other Windows can be focused (e.g. Windows Magnifier, reset PIN workflow).

If an object is above the lockscreen, it is accessible and visible to the user through the Windows UX while Windows is locked. An object below the lockscreen should only be accessible when Windows is unlocked, as it may contain sensitive information.

utils.security._isObjectBelowLockScreenCheckZOrder(objWindowHandle: int) bool

This is a risky hack. If the order is incorrectly detected, secure information may become accessible.

If these functions fail, where possible, NVDA should make NVDA objects accessible.

exception utils.security._UnexpectedWindowCountError

Bases: Exception

Raised when a window which matches the expected condition is not found by _isWindowBelowWindowMatchesCond

utils.security._isWindowBelowWindowMatchesCond(window: int, matchCond: Callable[[int], bool]) bool

This is a risky hack. The order may be incorrectly detected.

@returns: True if window is below a window that matches matchCond. If the first window is not found, but the second window is, it is assumed that the first window is above the second window.

In the context of _isObjectBelowLockScreenCheckZOrder, NVDA starts at the lowest window, and searches up towards the closest/lowest lock screen window. If the lock screen window is found before the NVDAObject, then the NVDAObject is above the lock screen, or not present at all, and therefore the NVDAObject should be made accessible. This is because if the NVDAObject is not present, we want to make it accessible by default. If the lock screen window is not present at all, we also want to make the NVDAObject accessible, so the lock screen window must be comprehensively searched for. If the NVDAObject is found, and then a lock screen window, the object is not made accessible as it is below the lock screen. Edge cases and failures should be handled by making the object accessible.

Refer to test_security for testing cases which demonstrate this behaviour.

utils.security._hasSessionLockStateUnknownWarningBeenGiven = False

Track whether the user has been notified.

utils.security.warnSessionLockStateUnknown() None

Warn the user that the lock state of the computer can not be determined. NVDA will not be able to determine if Windows is on the lock screen (LockApp on Windows 10/11), and will not be able to ensure privacy/security of the signed-in user against unauthenticated users. @note Only warn the user once.

utils.security.SHA_BLOCK_SIZE = 65536

The read size for each chunk read from the file, prevents memory overuse with large files.

utils.security.sha256_checksum(binaryReadModeFile: BinaryIO, blockSize: int = 65536) str

@param binaryReadModeFile: An open file (mode==’rb’). Calculate its sha256 hash. @param blockSize: The size of each read. @returns: The sha256 hex digest.

utils.security.isRunningOnSecureDesktop() bool

When NVDA is running on a secure screen, it is running on the secure desktop. When the serviceDebug parameter is not set, NVDA should run in secure mode when on the secure desktop. globalVars.appArgs.secure being set to True means NVDA is running in secure mode.

For more information, refer to projectDocs/design/technicalDesignOverview.md ‘Logging in secure mode’ and the following userGuide sections:

  • SystemWideParameters (information on the serviceDebug parameter)

  • SecureMode and SecureScreens

utils.tempFile module

utils.tempFile._createEmptyTempFileForDeletingFile(dir: str | None = None, prefix: str | None = None, suffix: str | None = None) str

Create an empty temporary file and return its path.

tempfile.mktemp is deprecated as creating a temp file in the system’s temp directory is a security risk, without holding it open, as the file could be created by an attacker with the same name. mkstemp / NamedTemporaryFile was created for the purpose of creating temporary files securely. However, we do not need this secure behaviour, as we are just creating a temp file to move a file to for future deletion. As such, we close the file handle and return the path.