-
-
Notifications
You must be signed in to change notification settings - Fork 641
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve flexibility of appModules discovery by allowing to map arbitrary appModule to a given executable. #13366
Conversation
Hi, another use case: some app executable names conflict with built-in module names e.g. time.exe for Clock app in Windows 10 and later. Thanks for looking into this.
|
Hi, Does the custom app module mapping succeed when NVDA is restarted while focused on an app module requiring a custom mapping for the executable name? A good app to test this is with Microsoft Weather app where it contains periods in the middle of the executable name. Also, note that this change will require changes to global plugins, too which are loaded way later than app module for the focused control. Thanks. |
Yes, it does.
Not really. To test this I've commented out the mapping for Media Player x64 in |
Hi, An issue that should be resolved from add-ons themselves: suppose an app module bundled with an add-on imports everything from an app module that was deleted with this PR. This will cause the add-on version of the app module to fail to load because Python could not import a nonexistent module. This affects Windows App Essentials add-on as my policy is to import from the app module with the executable name that's included in supported Windows 10/11 releases (take modern keyboard, for example where TextInputHost.exe is the executable name of the emoji panel included in Windows 10 Version 2004 and later which are releases supported by the add-on). I will be able to change this from the add-on side as soon as this PR is approved and merged provided that I can also resolve the resulting lint issue from add-on code. Also, can you provide code examples for use by add-on writers for sake of completeness? Thanks. |
Co-authored-by: Marco Zehe <MarcoZehe@users.noreply.github.com>
See test results for failed build of commit 287d1713d7 |
Please see #13364 (comment) regarding the possibility to import a module containing an unusable character in its name, e.g. '+' or '.'. It's a bit ugly but this seems doable. |
Has the new API been tested with an addon yet? The App Modules sections of the developer guide will need updating and potentially other documentation. Is it possible that addons rely on extending aliases? If so, we need to include a changelog item for that. |
Hi, yes I have tested this change with Windows App Essentials which relies on aliased app modules. Any add-on which includes app modules that derive from alias app modules from NVDA Core must now derive from base app modules (say, hxmail instead of hxoutlook), a change I think is the responsibility of the add-on authors (I have prepared a change in Windows App Essentials add-on that was tested and ready to go as soon as this PR is reviewed, approved, and merged). Note that it might be possible that the executable name for a derive module may change in the future, in which case add-on authors may need to either register the new executable name with an existing app module or import the base app module from Core. A simpler approach would have been to define a list of characters that should be replaced by underscores or an acceptable character (say, calling Notepad++.exe app module notepad__.py), but this PR does open a possibility where it becomes possible to load an app module with executable names that conflict with built-in Python module names such as Windows 10/11 Clock app (time.exe and time.py cannot be used because it conflicts with built-in time.py module from Python library). I understand that this is a late change, but given that people use Notepad++ for various tasks (including NVDA Core and add-on development), I advise reviewing this soon. Thanks.
|
Isn't that a similar problem to existing aliases? If an executable name changes, we need to create a new alias. This is a backwards compatible action. |
Hi, perhaps – I guess real-life data will tell us the full story (after this PR is merged). Thanks.
|
is this an API breaking change? does it have to be? |
Yes, it is, since some add-on may rely on one of the alias appModules removed in this PR
No, it is possible not to remove these alias appModules in this PR, and delay the removal to 2023.1. |
I've marked this as a draft for now since an issue with this implementation has been found when testing with the notepad++ add-on. Before this PR appModules in add-ons or in the scratchpad folder were prioritized over the one included in NVDA. While this is still the case when the appModule has the same name as the executable for which it is used, this does not work when there is appModule in NVDA which is registered in
|
… add-opns to overwrite the core module for a given program.
This is now implemented. |
@seanbudd This is ready for review.
Yes, I've implemented this in the latest commits.
As far as I can tell the part about which we may not be confident enough is "Is the API proposed in this PR good enough for add-on authors?". Even if it turns out we need to change the way in which binaries are mapped to the modules this should not make a difference to what happens to the alias modules which are currently in core (they should be removed regardless of how exactly binaries are mapped to the App Modules. |
@XLTechie Many thanks for your linguistic corrections! |
Hi, as far as Windows App Essentials goes (which employs alias app modules), I have resolved compatibility issues in dev snapshots and plan to release needed changes to stable channel this summer. Thanks.
|
@XLTechie Many thanks for your linguistic corrections!
You're welcome. :)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally LGTM, some minor fixes suggested. I agree that the aliases should be removed, but we should create a new issue to track / discuss the removal plan.
As @XLTechie mentioned, there's several instances where a third casing "app Module" has been introduced. I suggest a case sensitive find and replace to "App Module".
source/appModuleHandler.py
Outdated
# Broad except since we do not know | ||
# what exceptions may be thrown during import / construction of the app Module. | ||
except Exception: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Broad except since we do not know | |
# what exceptions may be thrown during import / construction of the app Module. | |
except Exception: | |
except Exception: | |
# Broad except since we do not know | |
# what exceptions may be thrown during import / construction of the app Module. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow why this improves things. Usually the comment explaining why something needs to be done precedes the code which is explained i.e. docstring is at the top of the described method etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is just a personal opinion sorry, couldn't find anything PEP related.
I've found commenting within the scope to be generally more pythonic.
In your example, the docstring is under the function header, in this case, it's within the scope of the exception.
I've applied them.
Please see #13627
Fixed as well. |
See test results for failed build of commit 1c000cc410 |
…k if the given App Module exists to work around bug in the Python import system (#13814) Fix-up of #13366 Fixes #13813 Summary of the issue: As part of PR #13366 I've modified the code responsible for retrieving application name from process id so that it no longer tries to import an App Module for a hosting process if it does not exist. Unfortunately Python find_Module method seems to have a bug - it returns a module when the provided string contains dots and the file named exactly like the last segment of the provided name exists in the package. For example if you have module named qq in the package, and you would like to check if the module named 6.5.qq exists True is returned even though there is no such module. I haven't yet tested how this behaves with more recent versions of Python nor opened an issue against them. Description of user facing changes NVDA no longer fails to work in applications containing dots in their file names in cases where you have an App Module for an application named exactly like the last segment of the application name. Description of development approach Dots are normalized to underscores before checking if the given module exists. While we did this already before trying to import a standard App Module this has not been done before trying to get module for a hosting process.
Closes #15618 Summary of the issue: PR #13366 changed a way in which NVDA maps an app module to a given executable. In the process several old app modules were marked as deprecated (they show warnings on import). This is pretty noticeable when building developer documentation scons devDocs. Description of user facing changes None Description of development approach Deprecated app modules and supporting functions from appModuleHandler were removed. The app Module for Azardi which cannot be imported by Sphinx was renamed, and mapped to Azardi's binary.
Link to issue number:
Related to #13364
Summary of the issue:
Currently when NVDA tries to load an appModule for a given program it just looks for a Python module of the same name as the program's executable. This has its limitations in particular:
importlib
they may contain characters which are invalid in ordinary import statements (for one example see Fix crashes in 64-bit builds of Notepad++ 8.3 and later #13364 where the apModule is called "notepad++"). Since "+" is invalid in Python's import statement add-on developers cannot import this module fromnvdaBuiltin
which means that it cannot be extended in an add-on.Description of how this pull request fixes the issue:
This PR introduces a mapping of executable names to appModules which is consulted before the given module is imported. It also adds a convenience functions for add-on developers which can be used to register or unregister a specific module for a given program. All alias apModules currently present in the source are marked as deprecated and application's for which they were loaded are mapped to the right appModule using the new map.
Since we cannot remove the old alias app modules care has been taken not to use them - they' re kept only for add-ons developers.
Testing strategy:
Made sure that right modules are loaded for Visual Studio Code Insiders and Media Player Classic Home Cinema x64 - both of these were using alias appModules previously.
Known issues with pull request:
None known
Change log entries:
For Developers
registerExecutableWithAppModule
andunregisterExecutable
were added to theappModuleHandler
module. They can be used to use a single appModule with multiple executable's.Code Review Checklist: