Skip to content

Python 3/NVDAObjects.IAccessible modules: absolute import fails if a given IAccessible class implementation is located outside the main module #8712

@josephsl

Description

@josephsl

Hi,

A note about the title: suffice to say that pre-transition research has progressed to a point where imports and small things can be tested here and there.

Background:

Building on #8590:

In NVDAObjects/IAccessible module, when loading a support class for a control NvDA has just encountered, it'll check class name and role inside a static map, which is then used to direct NVDA as to where the support routine can be found. In case the resulting class string is "mod.class", NVDA will use import machinery (import function) to load the appropriate module.

However, as noted in #8590, because Python 3 does not allow import of the form "from foo import something" when "foo" is to be imported from a module located in the same location, a dot is placed in front of the module name. Unfortunately, NvDAObjects/IAccessible does not know that this is the case in Python 3, so it raises "ModuleNotFoundError" when trying to import an MSAA module from init.py (for example, when importing sysListView.32.List, it works in Python 2, but does not in Python 3).

Steps to reproduce:

  1. Create a package inside a folder with an init.py file and another module.
  2. Try using the import of the form in python 3:

mod=import(modString,globals(),locals(),[])

Where "modString" is the name of the module inside the same folder as init.py.

Actual behavior:

Does not work in Python 3.

Expected behavior:

Works in Python 3.

System configuration:

NVDA Installed/portable/running from source:

N/A

NVDA version:

N/A

Windows version:

N/A

Name and version of other software in use when reproducing the issue:

Python 2.7.15, 3.7.0

Other information about your system:

N/A

Other questions:

Does the issue still occur after restarting your PC?

Not applicable

Have you tried any other versions of NVDA?

Not applicable

Possible solutions:

  1. Force Python to load the modules in question by manipulating sys.path.
  2. Insert a dot when encountering class string of the form "mod.class" so import function can import .mod instead.
  3. Try using importlib (Python 3).

Thanks.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions