Repository: nvaccess/nvda

Issue:
NVDA alpha does not speak single letters when editing text with speech viewer enabled
<!--
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. Run the latest Alpha build of NVDA.
2. Enable the speech viewer utility by checking the item from the tools menu of the NVDA menu.
3. Open a text editor like notepad and write some text.
4. Try to navigate letter by letter using the left and right arrows.

### Actual behavior:
NVDA stays silent and does not report the character that the cursor reached
### Expected behavior:
NVDA should report characters in the same way it does when the speech viewer utility is not enabled
### System configuration
#### NVDA installed/portable/running from source:
Portable, but getting the same results with the installed copy
#### NVDA version:
alpha-19604,7773e8ff
#### Windows version:
Windows 10, version 1909
#### Name and version of other software in use when reproducing the issue:
None
#### Other information about your system:

### 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.
The issue cannot  be reproduced on 2019.3 beta 4

[nvda broken caret speech.log](https://github.com/nvaccess/nvda/files/4141359/nvda.broken.caret.speech.log)



Discussion:
I'm having this issue with the latest alpha builds.
cc: @feerrenrut this might also be important for fix in 2019.3?
I have just tried and the issue does not occur on 2019.3 beta 4.
Thanks for reporting. Closing as works for me
Confused. The issue does not occur on Beta as I said, but it can be reproduced on latest Alpha releases, so I don't believe it should be closed.
Oh sorry, I reopen this.
This problem does not appear to be in Version: alpha-19604,7773e8ff. @nidza07 nidza07 can you check it?
Yes, I have checked and I can still reproduce the issue as soon as I enable speech viewer and try to navigate character by character, I do not get any spoken feedback.
Any updates on this one? It can still be reproduced on alpha-19724,2c4caa62 latest at the time of this comment.
I can also duplicate this with NVDA Version alpha-19724,2c4caa62.
On the addons list, some people should be more specific when speaking about the error. 
it is reproducible, snapshot version:
NVDA version alpha-19755,6d40a54e

I can reproduce this in latest alpha: `alpha-19755,6d40a54e` I haven't done a full bisect, the earliest version where someone is reporting this behavior is in alpha-`19604,7773e8ff`. The problem does not occur in 2019.3.

Some have suggested that this issue requires "speech" to be checked in the debug logging under advanced settings, this seemed to make no difference to me.
It took a while, but I have tracked this down to a generator being exhausted in SpeechViewer.appendSpeechSequence.
SpeechViewer.appendSpeechSequence iterates through the given speech sequence in order to break it up in to chunks to write to the viewer control. However, in the case of speaking single letters, the speech sequence given seems to be a
```
<class 'generator'> <generator object getSpellingSpeech at 0x07EC28B0>
```
I'm assuming that getSpellingSpeech has been changed recently to return a generator.
Problem is that SpeechViewer.appendSpeechSequence exhausts it while iterating, and therefore there is nothing left further on when sending to the synth.
In short, getSpellingspeech really can't be a generator... 
@michaelDCurran When writing a fix for this please ensure that single letters are again announced when speech is checked in debug logs categories in the advanced settings.

Resolving patch:
diff --git a/source/speech/__init__.py b/source/speech/__init__.py
--- a/source/speech/__init__.py
+++ b/source/speech/__init__.py
@@ -7,6 +7,7 @@
 """High-level functions to speak information.
 """ 
 
+import collections
 import itertools
 import weakref
 import unicodedata
@@ -695,6 +696,13 @@ def speak(  # noqa: C901
 	@param symbolLevel: The symbol verbosity level; C{None} (default) to use the user's configuration.
 	@param priority: The speech priority.
 	"""
+	# speechSequence may be a generator.
+	#  As speechViewer needs to iterate over it
+	# before it is iterated over for actual speaking,
+	# Or similarly it may be iterated over for logging bad sequence types,
+	# Flatten it into a list first.
+	if isinstance(speechSequence, collections.abc.Generator):
+		speechSequence = [i for i in speechSequence]
 	types.logBadSequenceTypes(speechSequence)
 	if priority is None:
 		priority = Spri.NORMAL


Test patch: