Skip to content
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

Python 3.8/gettext: replace custom pgettext implementation with built--in pgettext #12109

Merged
merged 7 commits into from
Mar 11, 2021

Conversation

josephsl
Copy link
Collaborator

@josephsl josephsl commented Mar 1, 2021

Hi,

This will impact localization and resolves a long-standing issue with it:

Link to issue number:

Closes #9207

Summary of the issue:

Python 3.8 introduces gettext.pgettext to obtain translated text based on context. Prior to this, NVDA defined a custom implementation of pgettext function.

Description of how this pull request fixes the issue:

Replace custom pgettext implementation and built-in namespace assignment with Python 3.8's gettext.pgettext by using translation.install function's "names" sequence parameter.

Testing strategy:

Two ways:

  1. Perform a diff between current master and this PR's locale/* data after generating pot files.
  2. Manual: have translators test this change to make sure localizations are correct.

Known issues with pull request:

None

Change log entry:

None needed, unless a note to developers is needed to highlight pgettext function.

Code Review Checklist:

This checklist is a reminder of things commonly forgotten in a new PR.
Authors, please do a self-review and confirm you have considered the following items.
Mark items you have considered by checking them.
You can do this when editing the Pull request description with an x: [ ] becomes [x].
You can also check the checkboxes after the PR is created.

  • Pull Request description is up to date.
  • Unit tests.
  • System (end to end) tests.
  • Manual tests.
  • User Documentation.
  • Change log entry.
  • Context sensitive help for GUI changes.

…ccess#9207.

As gettext.pgettext is present, there is no need to manually assign NVDA's own pgettext function to built-in namespace for add-ons. Therefore remove this assignment.
…vaccess#9207.

As Python 3.8 includes gettext.pgettext, there is no need for NVDA's implementation of pgettext function. Therefore remove makePgettext and builtins namespace assignment from language handler.
…vaccess#9207.

As Python 3.8 includes gettext.pgettext, add it to built-in namespace by using 'names' parameter of translation.install method.
@josephsl
Copy link
Collaborator Author

josephsl commented Mar 1, 2021

Hi,

Note that this change may affect add-ons. As far as I know, all add-ons hosted on community add-ons website are not affected.

Thanks.

@CyrilleB79
Copy link
Collaborator

Hi

You write:

Note that this change may affect add-ons.

In this case, a point should be added in the changes for developpers describing what is the impact on add-ons. Thanks.

@josephsl
Copy link
Collaborator Author

josephsl commented Mar 1, 2021 via email

@lukaszgo1
Copy link
Contributor

Have you tested that with this change `pgettext`` works correctly when used for translatable strings in add-ons?

…. Re nvaccess#9207."

This reverts commit 991de43 so add-on translations will work.
@josephsl
Copy link
Collaborator Author

josephsl commented Mar 1, 2021 via email

…hon's pgettext function. Re nvaccess#9207.

Add-on initialization will still require assigning pgettext to add-on namespace, therefore use translations.pgettext instead of now removed NVDA-specific implementation.
@michaelDCurran michaelDCurran merged commit 0b78587 into nvaccess:py3.8 Mar 11, 2021
@nvaccessAuto nvaccessAuto added this to the 2021.1 milestone Mar 11, 2021
@josephsl josephsl deleted the i9207pgettext branch April 5, 2021 13:12
michaelDCurran added a commit that referenced this pull request Apr 15, 2021
michaelDCurran added a commit that referenced this pull request Apr 20, 2021
Fixes #12152
Fixes #12154

Since upgrading to Python 3.8, several serious crashes in NVDA have been reported. Specifically:
• NVDA crashing when using the SAPI4 speech synthesizer: #12152
• NVDA crashing when using Windows Explorer on Windows Server 2012: #12154
Both of these issues were traced to stack corruption after a Python callback of NVDA's was called from external libraries. In SAPI4's case, after calling NVDA's implementation of ITTSBufNotifySink::TextDataStarted, and in the Windows Server 2012 case: IUIAutomationPropertyChangedEventHandler::handlePropertyChangedEvent.
It seems as though libFFI / Python ctypes is not cleaning the stack properly after executing a Python callback with the stdcall calling convention (ctypes WINFUNCTYPE), where the callback contained at least one argument larger than 4 bytes (E.g. a long long, or a VARIANT struct), and the arguments preceding it were such that this argument was not aligned to an 8 byte boundary. E.g. the callback might be:
• callback(void*, long long) or
• callback(void*, void*, int, VARIANT)
See Python bug: https://bugs.python.org/issue38748
On that bug I have attached a minimal testcase.
This bug affects both Python 3.8 and Python 3.9.
The bug is most likely in the libFFI project used by Python's ctypes module. Python 3.8 switched to a much more recent and official version of libFFI I believe.
Although we do really want to move to Python 3.8+ as soon as we can, right now this bug makes it impossible to do so. We could specifically work around the currently known manifestations by moving some of that code into C++, but that brings its own risks, and we still don't know where else this issue may appear in our code. The appropriate thing to do right now is stay on Python 3.7 until we can work with Python / libFFI to get this resolved.

Description of how this pull request fixes the issue:
Downgrades to Python 3.7 by referencing Python 3.7 (rather than 3.8) in NVDA's build system.
The existing PRs that needed to be reverted were:
• Updating brlAPI to a Python 3.8 build: nvaccess/nvda-misc-deps#20
• Switching to using Python's own pgettext: #12109
• calling os.add_dll_directory when loading liblouis: #12020
None of these PRs provided any user visible changes.
The rest of the Python 3.8 work, including the switch to a virtual
environment etc is all compatible with Python 3.7 and can remain.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants