Repository: nvaccess/nvda

Issue:
In Firefox, when opening or closing a Gmail conversation, NVDA emits an error
<!--
Please thoroughly read NVDA's wiki article on how to fill in this template, including how to provide the required files.
Issues may be closed if the required information is not present.
https://github.com/nvaccess/nvda/wiki/Github-issue-template-explanation-and-examples
-->

### Steps to reproduce:

1. Start Firefox and open Gmail.
2. Focus a conversation and press Enter.

### Actual behavior:

The conversation opens, and NVDA issues an error sound. The log shows:

ERROR - eventHandler.executeEvent (16:00:40.562):
error executing event: typedCharacter on <NVDAObjects.IAccessible.mozilla.BrokenFocusedState object at 0x00A90570> with extra args of {'ch': 'u'}
Traceback (most recent call last):
  File "eventHandler.pyc", line 155, in executeEvent
  File "eventHandler.pyc", line 92, in __init__
  File "eventHandler.pyc", line 100, in next
  File "NVDAObjects\__init__.pyc", line 980, in event_typedCharacter
  File "speech\__init__.pyc", line 695, in speakTypedCharacters
  File "api.pyc", line 247, in isTypingProtected
  File "baseObject.pyc", line 46, in __get__
  File "baseObject.pyc", line 149, in _getPropertyViaCache
  File "NVDAObjects\__init__.pyc", line 854, in _get_isProtected
  File "baseObject.pyc", line 46, in __get__
  File "baseObject.pyc", line 149, in _getPropertyViaCache
  File "NVDAObjects\IAccessible\mozilla.pyc", line 71, in _get_states
  File "baseObject.pyc", line 46, in __get__
  File "baseObject.pyc", line 149, in _getPropertyViaCache
  File "NVDAObjects\IAccessible\ia2Web.pyc", line 58, in _get_states
  File "baseObject.pyc", line 46, in __get__
  File "baseObject.pyc", line 149, in _getPropertyViaCache
  File "NVDAObjects\IAccessible\__init__.pyc", line 866, in _get_states
  File "comtypesMonkeyPatches.pyc", line 22, in __call__
_ctypes.COMError: (-2147467262, 'Schnittstelle nicht unterstützt', (None, None, None, 0, None))

### Expected behavior:

Conversation should open, but this error should not occur.

### System configuration
#### NVDA installed/portable/running from source:

Installed.

#### NVDA version:

NVDA version alpha-18195,fa7f6438

#### Windows version:

10 19h1

#### Name and version of other software in use when reproducing the issue:

Firefox 69 beta.

#### Other information about your system:

NVDA uses the Microsoft OneCore voices and the Freedom Scientific Focus braille display driver, detected via auto detect.

### Other questions
#### Does the issue still occur after restarting your PC?

Yes.

#### Have you tried any other versions of NVDA? If so, please report their behaviors.

Yes, this is new after the speech refactor/Python 3 update. Does not happen in earlier alphas or the 2019.2beta3 versions.



Discussion:
More places where I hear the error sound is in new Twitter, when browse mode is off and I use g then h to go to home, g then n to go to Notifications etc. Also when pressing n to start a new tweet, r to reply to one etc., before the input field is announced, an error occurs. I suspect the stacks all look similar. Looks like ComTypes or some other interaction doesn't handle dynamic web updates that well yet.

CC @leonardder @feerrenrut 
One of the most recent Non py3 threshold snapshots is [18065](https://ci.appveyor.com/api/buildjobs/8rp0a21cqwyb1a7i/artifacts/output/nvda_snapshot_threshold-18065,ddec4297.exe)

@MarcoZehe: Could you please have a test of this This will at least help us find out whether this is Python 3 or speech refactor related.
@leonardder It is Python3. With build 18065, this error does not occur.
Fixing this issue seems pretty easy. In iaccessible/__init__.py, line 866, change the if not hasattr check to `if not isinstance(self.IAccessibleObject,IAccessibleHandler.IAccessible2):`. That's actually the way how this check should have been from the start.
I can file a pr for this. However, what really worries me is that using hasattr on a com object can somehow raise an interface not supported error. That is pretty unexpected IMO.

Resolving patch:
diff --git a/source/NVDAObjects/IAccessible/__init__.py b/source/NVDAObjects/IAccessible/__init__.py
--- a/source/NVDAObjects/IAccessible/__init__.py
+++ b/source/NVDAObjects/IAccessible/__init__.py
@@ -863,7 +863,7 @@ def _get_states(self):
 			log.debugWarning("could not get IAccessible states",exc_info=True)
 		else:
 			states.update(IAccessibleHandler.IAccessibleStatesToNVDAStates[x] for x in (y for y in (1<<z for z in range(32)) if y&IAccessibleStates) if x in IAccessibleHandler.IAccessibleStatesToNVDAStates)
-		if not hasattr(self.IAccessibleObject,'states'):
+		if not isinstance(self.IAccessibleObject,IAccessibleHandler.IAccessible2):
 			# Not an IA2 object.
 			return states
 		IAccessible2States=self.IA2States


Test patch: