From 6c2beb87d80f4e69fe80266ea619e8f2cf331f67 Mon Sep 17 00:00:00 2001 From: Michael Curran Date: Wed, 12 Jun 2019 10:36:49 +1000 Subject: [PATCH 1/5] Convert all usage of unichr to chr. --- source/XMLFormatting.py | 2 +- source/appModules/powerpnt.py | 2 +- source/brailleInput.py | 6 +++--- source/browseMode.py | 2 +- source/displayModel.py | 2 +- source/keyboardHandler.py | 6 +++--- source/speechXml.py | 2 +- source/winConsoleHandler.py | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/source/XMLFormatting.py b/source/XMLFormatting.py index af294b53170..5661b7d55e9 100755 --- a/source/XMLFormatting.py +++ b/source/XMLFormatting.py @@ -16,7 +16,7 @@ def _startElementHandler(self,tagName,attrs): data=attrs.get('value',None) if data is not None: try: - data=unichr(int(data)) + data=chr(int(data)) except ValueError: data=u'\ufffd' self._CharacterDataHandler(data) diff --git a/source/appModules/powerpnt.py b/source/appModules/powerpnt.py index 9d169bc65ff..62a58bf3455 100644 --- a/source/appModules/powerpnt.py +++ b/source/appModules/powerpnt.py @@ -244,7 +244,7 @@ def getBulletText(ppBulletFormat): if t==ppBulletNumbered: return "%d."%ppBulletFormat.number #(ppBulletFormat.startValue+(ppBulletFormat.number-1)) elif t: - return unichr(ppBulletFormat.character) + return chr(ppBulletFormat.character) def walkPpShapeRange(ppShapeRange): for ppShape in ppShapeRange: diff --git a/source/brailleInput.py b/source/brailleInput.py index c90afb1b6e2..641d609aa6e 100644 --- a/source/brailleInput.py +++ b/source/brailleInput.py @@ -126,7 +126,7 @@ def _translate(self, endWord): self.bufferText = u"" oldTextLen = len(self.bufferText) pos = self.untranslatedStart + self.untranslatedCursorPos - data = u"".join([unichr(cell | LOUIS_DOTS_IO_START) for cell in self.bufferBraille[:pos]]) + data = u"".join([chr(cell | LOUIS_DOTS_IO_START) for cell in self.bufferBraille[:pos]]) mode = louis.dotsIO | louis.noUndefinedDots if (not self.currentFocusIsTextObj or self.currentModifiers) and self._table.contracted: mode |= louis.partialTrans @@ -178,7 +178,7 @@ def _translateForReportContractedCell(self, pos): @rtype: unicode """ cells = self.bufferBraille[:pos + 1] - data = u"".join([unichr(cell | LOUIS_DOTS_IO_START) for cell in cells]) + data = u"".join([chr(cell | LOUIS_DOTS_IO_START) for cell in cells]) oldText = self.bufferText text = louis.backTranslate( [os.path.join(brailleTables.TABLES_DIR, self._table.fileName), @@ -293,7 +293,7 @@ def _updateUntranslated(self): if api.isTypingProtected(): self.untranslatedBraille = UNICODE_BRAILLE_PROTECTED * (len(self.bufferBraille) - self.untranslatedStart) else: - self.untranslatedBraille = "".join([unichr(UNICODE_BRAILLE_START + dots) for dots in self.bufferBraille[self.untranslatedStart:]]) + self.untranslatedBraille = "".join([chr(UNICODE_BRAILLE_START + dots) for dots in self.bufferBraille[self.untranslatedStart:]]) def updateDisplay(self): """Update the braille display to reflect untranslated input. diff --git a/source/browseMode.py b/source/browseMode.py index ae969d34a13..6c1ffcb571d 100644 --- a/source/browseMode.py +++ b/source/browseMode.py @@ -1025,7 +1025,7 @@ def onTreeChar(self, evt): else: # Search the list. # We have to implement this ourselves, as tree views don't accept space as a search character. - char = unichr(evt.UnicodeKey).lower() + char = chr(evt.UnicodeKey).lower() # IF the same character is typed twice, do the same search. if self._searchText != char: self._searchText += char diff --git a/source/displayModel.py b/source/displayModel.py index deda6365cd5..f5495173796 100644 --- a/source/displayModel.py +++ b/source/displayModel.py @@ -42,7 +42,7 @@ def normalizeRtlString(s): d=unicodedata.decomposition(c) d=d.split(' ') if d else None if d and len(d)==2 and d[0] in ('','','',''): - c=unichr(int(d[1],16)) + c=chr(int(d[1],16)) l.append(c) return u"".join(l) diff --git a/source/keyboardHandler.py b/source/keyboardHandler.py index b30dc8fdf45..6a95812c007 100644 --- a/source/keyboardHandler.py +++ b/source/keyboardHandler.py @@ -395,16 +395,16 @@ def _get_mainKeyName(self): return name if 32 < self.vkCode < 128: - return unichr(self.vkCode).lower() + return chr(self.vkCode).lower() if self.vkCode == vkCodes.VK_PACKET: # Unicode character from non-keyboard input. - return unichr(self.scanCode) + return chr(self.scanCode) vkChar = winUser.user32.MapVirtualKeyExW(self.vkCode, winUser.MAPVK_VK_TO_CHAR, getInputHkl()) if vkChar>0: if vkChar == 43: # "+" # A gesture identifier can't include "+" except as a separator. return "plus" - return unichr(vkChar).lower() + return chr(vkChar).lower() if self.vkCode == 0xFF: # #3468: This key is unknown to Windows. diff --git a/source/speechXml.py b/source/speechXml.py index 3453d0bee12..11f0a3a492f 100644 --- a/source/speechXml.py +++ b/source/speechXml.py @@ -28,7 +28,7 @@ def _buildInvalidXmlRegexp(): # Ranges of invalid characters. # Both start and end are inclusive; i.e. they are both themselves considered invalid. ranges = ((0x00, 0x08), (0x0B, 0x0C), (0x0E, 0x1F), (0x7F, 0x84), (0x86, 0x9F), (0xFDD0, 0xFDDF), (0xFFFE, 0xFFFF)) - rangeExprs = [u"%s-%s" % (unichr(start), unichr(end)) + rangeExprs = [u"%s-%s" % (chr(start), chr(end)) for start, end in ranges] leadingSurrogate = u"[\uD800-\uDBFF]" trailingSurrogate = u"[\uDC00-\uDFFF]" diff --git a/source/winConsoleHandler.py b/source/winConsoleHandler.py index a434d56af3c..bf06cf96828 100755 --- a/source/winConsoleHandler.py +++ b/source/winConsoleHandler.py @@ -147,7 +147,7 @@ def consoleWinEventHook(handle,eventID,window,objectID,childID,threadID,timestam y=winUser.GET_Y_LPARAM(objectID) consoleScreenBufferInfo=wincon.GetConsoleScreenBufferInfo(consoleOutputHandle) if x Date: Wed, 12 Jun 2019 11:11:35 +1000 Subject: [PATCH 2/5] Replace basestring with str. --- source/NVDAObjects/IAccessible/MSHTML.py | 2 +- source/NVDAObjects/IAccessible/__init__.py | 16 +++++++-------- .../NVDAObjects/IAccessible/ia2TextMozilla.py | 2 +- source/NVDAObjects/IAccessible/mozilla.py | 2 +- source/NVDAObjects/IAccessible/winword.py | 2 +- source/NVDAObjects/UIA/edge.py | 4 ++-- source/NVDAObjects/UIA/wordDocument.py | 2 +- source/NVDAObjects/__init__.py | 20 +++++++++---------- source/NVDAObjects/window/excel.py | 2 +- source/NVDAObjects/window/winword.py | 2 +- source/XMLFormatting.py | 2 +- source/addonHandler/__init__.py | 4 ++-- source/api.py | 4 ++-- source/appModules/msnmsgr.py | 2 +- source/baseObject.py | 2 +- source/bdDetect.py | 2 +- source/braille.py | 10 +++++----- source/brailleDisplayDrivers/eurobraille.py | 2 +- source/brailleTables.py | 2 +- source/browseMode.py | 2 +- source/compoundDocuments.py | 2 +- source/config/__init__.py | 16 +++++++-------- source/displayModel.py | 20 +++++++++---------- source/globalCommands.py | 10 +++++----- source/gui/settingsDialogs.py | 2 +- source/inputCore.py | 18 ++++++++--------- source/mathPres/__init__.py | 8 ++++---- source/nvwave.py | 4 ++-- source/oleacc.py | 2 +- source/speech/__init__.py | 20 +++++++++---------- source/speechViewer.py | 2 +- source/speechXml.py | 4 ++-- source/synthDriverHandler.py | 2 +- source/synthDrivers/espeak.py | 2 +- source/synthDrivers/oneCore.py | 6 +++--- source/synthDrivers/sapi4.py | 2 +- source/synthDrivers/sapi5.py | 2 +- source/textInfos/__init__.py | 2 +- source/virtualBuffers/MSHTML.py | 2 +- source/windowUtils.py | 2 +- 40 files changed, 107 insertions(+), 107 deletions(-) diff --git a/source/NVDAObjects/IAccessible/MSHTML.py b/source/NVDAObjects/IAccessible/MSHTML.py index dd71569cde3..b98c745fdfa 100644 --- a/source/NVDAObjects/IAccessible/MSHTML.py +++ b/source/NVDAObjects/IAccessible/MSHTML.py @@ -670,7 +670,7 @@ def _get_name(self): title=self.HTMLAttributes['title'] # #2121: MSHTML sometimes returns a node for the title attribute. # This doesn't make any sense, so ignore it. - if title and isinstance(title,basestring): + if title and isinstance(title,str): return title return "" return super(MSHTML,self).name diff --git a/source/NVDAObjects/IAccessible/__init__.py b/source/NVDAObjects/IAccessible/__init__.py index ef55eb865a8..d4b095921e9 100644 --- a/source/NVDAObjects/IAccessible/__init__.py +++ b/source/NVDAObjects/IAccessible/__init__.py @@ -326,7 +326,7 @@ def _iterTextWithEmbeddedObjects(self, withFields, formatConfig=None): items = [self.text] offset = self._startOffset for item in items: - if not isinstance(item, basestring): + if not isinstance(item, str): # This is a field. yield item continue @@ -741,14 +741,14 @@ def _get_name(self): res=self.IAccessibleObject.accName(self.IAccessibleChildID) except COMError: res=None - return res if isinstance(res,basestring) and not res.isspace() else None + return res if isinstance(res,str) and not res.isspace() else None def _get_value(self): try: res=self.IAccessibleObject.accValue(self.IAccessibleChildID) except COMError: res=None - return res if isinstance(res,basestring) and not res.isspace() else None + return res if isinstance(res,str) and not res.isspace() else None def _get_actionCount(self): if hasattr(self,'IAccessibleActionObject'): @@ -824,7 +824,7 @@ def _get_role(self): superRole=super(IAccessible,self).role if superRole!=controlTypes.ROLE_WINDOW: return superRole - if isinstance(IARole,basestring): + if isinstance(IARole,str): IARole=IARole.split(',')[0].lower() log.debug("IARole: %s"%IARole) return IAccessibleHandler.IAccessibleRolesToNVDARoles.get(IARole,controlTypes.ROLE_UNKNOWN) @@ -904,7 +904,7 @@ def _get_decodedAccDescription(self): def _get_description(self): if self.hasEncodedAccDescription: d=self.decodedAccDescription - if isinstance(d,basestring): + if isinstance(d,str): return d else: return "" @@ -912,14 +912,14 @@ def _get_description(self): res=self.IAccessibleObject.accDescription(self.IAccessibleChildID) except COMError: res=None - return res if isinstance(res,basestring) and not res.isspace() else None + return res if isinstance(res,str) and not res.isspace() else None def _get_keyboardShortcut(self): try: res=self.IAccessibleObject.accKeyboardShortcut(self.IAccessibleChildID) except COMError: res=None - return res if isinstance(res,basestring) and not res.isspace() else None + return res if isinstance(res,str) and not res.isspace() else None def _get_childCount(self): if self.IAccessibleChildID!=0: @@ -1379,7 +1379,7 @@ def _get_positionInfo(self): pass if self.hasEncodedAccDescription: d=self.decodedAccDescription - if d and not isinstance(d,basestring): + if d and not isinstance(d,str): groupdict=d.groupdict() return {x:int(y) for x,y in groupdict.items() if y is not None} if self.allowIAccessibleChildIDAndChildCountForPositionInfo and self.IAccessibleChildID>0: diff --git a/source/NVDAObjects/IAccessible/ia2TextMozilla.py b/source/NVDAObjects/IAccessible/ia2TextMozilla.py index 77ab540ae9c..015f31c229b 100644 --- a/source/NVDAObjects/IAccessible/ia2TextMozilla.py +++ b/source/NVDAObjects/IAccessible/ia2TextMozilla.py @@ -232,7 +232,7 @@ def _iterRecursiveText(self, ti, controlStack, formatConfig): for item in ti._iterTextWithEmbeddedObjects(controlStack is not None, formatConfig=formatConfig): if item is None: yield u"" - elif isinstance(item, basestring): + elif isinstance(item, str): yield item elif isinstance(item, int): # Embedded object. embedded = _getEmbedded(ti.obj, item) diff --git a/source/NVDAObjects/IAccessible/mozilla.py b/source/NVDAObjects/IAccessible/mozilla.py index 690a2c75cc9..55f899f75db 100755 --- a/source/NVDAObjects/IAccessible/mozilla.py +++ b/source/NVDAObjects/IAccessible/mozilla.py @@ -88,7 +88,7 @@ class Gecko1_9(Mozilla): def _get_description(self): rawDescription=super(Mozilla,self).description - if isinstance(rawDescription,basestring) and rawDescription.startswith('Description: '): + if isinstance(rawDescription,str) and rawDescription.startswith('Description: '): return rawDescription[13:] else: return "" diff --git a/source/NVDAObjects/IAccessible/winword.py b/source/NVDAObjects/IAccessible/winword.py index 02810f0876b..4c81ee81fe2 100644 --- a/source/NVDAObjects/IAccessible/winword.py +++ b/source/NVDAObjects/IAccessible/winword.py @@ -410,7 +410,7 @@ def _get_errorText(self): inBold=False textList=[] for field in fields: - if isinstance(field,basestring): + if isinstance(field,str): if inBold: textList.append(field) elif field.field: inBold=field.field.get('bold',False) diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py index 990eff87756..6df923c9536 100644 --- a/source/NVDAObjects/UIA/edge.py +++ b/source/NVDAObjects/UIA/edge.py @@ -202,7 +202,7 @@ def getTextWithFields(self,formatConfig=None): index=0 while index1 and isinstance(field,basestring) and field.isspace(): + if index>1 and isinstance(field,str) and field.isspace(): prevField=fields[index-2] if isinstance(prevField,textInfos.FieldCommand) and prevField.command=="controlEnd": del fields[index-1:index+1] @@ -214,7 +214,7 @@ def getTextWithFields(self,formatConfig=None): numFields=len(fields) for index in range(numFields-1,-1,-1): field=fields[index] - if isinstance(field,basestring): + if isinstance(field,str): break elif isinstance(field,textInfos.FieldCommand) and field.command=="controlStart" and not field.field.get('embedded'): startCount+=1 diff --git a/source/NVDAObjects/UIA/wordDocument.py b/source/NVDAObjects/UIA/wordDocument.py index ee2926b75f8..5bbddc6fb74 100644 --- a/source/NVDAObjects/UIA/wordDocument.py +++ b/source/NVDAObjects/UIA/wordDocument.py @@ -212,7 +212,7 @@ def getTextWithFields(self,formatConfig=None): elif isinstance(field,textInfos.FieldCommand) and field.command=="formatChange": # This is the most recent formatField we have seen. lastFormatField=field.field - elif listItemStarted and isinstance(field,basestring): + elif listItemStarted and isinstance(field,str): # This is the first text string within the list. # Remove the text up to the first space, and store it as line-prefix which NVDA will appropriately speak/braille as a bullet. try: diff --git a/source/NVDAObjects/__init__.py b/source/NVDAObjects/__init__.py index e2a454380c3..f68b8ca0fec 100644 --- a/source/NVDAObjects/__init__.py +++ b/source/NVDAObjects/__init__.py @@ -387,7 +387,7 @@ def _get_appModule(self): def _get_name(self): """The name or label of this object (example: the text of a button). - @rtype: basestring + @rtype: str """ return "" @@ -408,13 +408,13 @@ def _get_roleText(self): def _get_value(self): """The value of this object (example: the current percentage of a scrollbar, the selected option in a combo box). - @rtype: basestring + @rtype: str """ return "" def _get_description(self): """The description or help text of this object. - @rtype: basestring + @rtype: str """ return "" @@ -432,7 +432,7 @@ def getActionName(self,index=None): @param index: the optional 0-based index of the wanted action. @type index: int @return: the action's name - @rtype: basestring + @rtype: str """ raise NotImplementedError @@ -448,7 +448,7 @@ def _get_defaultActionIndex(self): def _get_keyboardShortcut(self): """The shortcut key that activates this object(example: alt+t). - @rtype: basestring + @rtype: str """ return "" @@ -1098,7 +1098,7 @@ def _get_basicText(self): newTime=time.time() oldTime=getattr(self,'_basicTextTime',0) if newTime-oldTime>0.5: - self._basicText=u" ".join(x for x in (self.name, self.value, self.description) if isinstance(x, basestring) and len(x) > 0 and not x.isspace()) + self._basicText=u" ".join(x for x in (self.name, self.value, self.description) if isinstance(x, str) and len(x) > 0 and not x.isspace()) if len(self._basicText)==0: self._basicText=u"" else: @@ -1120,13 +1120,13 @@ def _formatLongDevInfoString(string, truncateLen=250): If the string is too long to be useful, it will be truncated. This string should be included as returned. There is no need to call repr. @param string: The string to format. - @type string: nbasestring + @type string: nstr @param truncateLen: The length at which to truncate the string. @type truncateLen: int @return: The formatted string. - @rtype: basestring + @rtype: str """ - if isinstance(string, basestring) and len(string) > truncateLen: + if isinstance(string, str) and len(string) > truncateLen: return "%r (truncated)" % string[:truncateLen] return repr(string) @@ -1238,7 +1238,7 @@ def _get_mathMl(self): raise NotImplementedError #: The language/locale of this object. - #: @type: basestring + #: @type: str language = None def _get__hasNavigableText(self): diff --git a/source/NVDAObjects/window/excel.py b/source/NVDAObjects/window/excel.py index 8d6b317dd75..87ea5eadb5d 100755 --- a/source/NVDAObjects/window/excel.py +++ b/source/NVDAObjects/window/excel.py @@ -1538,7 +1538,7 @@ def _get_children(self): background=item.field.get('background-color',None) if (background,foreground)==self._highlightColors: states.add(controlTypes.STATE_SELECTED) - if isinstance(item,basestring): + if isinstance(item,str): obj=ExcelDropdownItem(parent=self,name=item,states=states,index=index) children.append(obj) index+=1 diff --git a/source/NVDAObjects/window/winword.py b/source/NVDAObjects/window/winword.py index dfbb07770b8..0b43944728e 100755 --- a/source/NVDAObjects/window/winword.py +++ b/source/NVDAObjects/window/winword.py @@ -721,7 +721,7 @@ def getTextWithFields(self,formatConfig=None): item.field=self._normalizeControlField(field) elif isinstance(field,textInfos.FormatField): item.field=self._normalizeFormatField(field,extraDetail=extraDetail) - elif index>0 and isinstance(item,basestring) and item.isspace(): + elif index>0 and isinstance(item,str) and item.isspace(): #2047: don't expose language for whitespace as its incorrect for east-asian languages lastItem=commandList[index-1] if isinstance(lastItem,textInfos.FieldCommand) and isinstance(lastItem.field,textInfos.FormatField): diff --git a/source/XMLFormatting.py b/source/XMLFormatting.py index 5661b7d55e9..a27a4c5a823 100755 --- a/source/XMLFormatting.py +++ b/source/XMLFormatting.py @@ -50,7 +50,7 @@ def _EndElementHandler(self,tagName): def _CharacterDataHandler(self,data): cmdList=self._commandList - if cmdList and isinstance(cmdList[-1],basestring): + if cmdList and isinstance(cmdList[-1],str): cmdList[-1]+=data else: cmdList.append(data) diff --git a/source/addonHandler/__init__.py b/source/addonHandler/__init__.py index f555ea28324..0af4c3822e0 100644 --- a/source/addonHandler/__init__.py +++ b/source/addonHandler/__init__.py @@ -474,9 +474,9 @@ def getDocFilePath(self, fileName=None): An add-on can specify a default documentation file name via the docFileName parameter in its manifest. @param fileName: The requested file name or C{None} for the add-on's default. - @type fileName: basestring + @type fileName: str @return: The path to the requested file or C{None} if it wasn't found. - @rtype: basestring + @rtype: str """ if not fileName: fileName = self.manifest["docFileName"] diff --git a/source/api.py b/source/api.py index ec929bbac07..3c6a68f9581 100644 --- a/source/api.py +++ b/source/api.py @@ -285,7 +285,7 @@ def copyToClip(text): @param text: the text which will be copied to the clipboard @type text: string """ - if not isinstance(text,basestring) or len(text)==0: + if not isinstance(text,str) or len(text)==0: return False import gui with winUser.openClipboard(gui.mainFrame.Handle): @@ -335,7 +335,7 @@ def getStatusBarText(obj): text = obj.name or "" if text: text += " " - return text + " ".join(chunk for child in obj.children for chunk in (child.name, child.value) if chunk and isinstance(chunk, basestring) and not chunk.isspace()) + return text + " ".join(chunk for child in obj.children for chunk in (child.name, child.value) if chunk and isinstance(chunk, str) and not chunk.isspace()) def filterFileName(name): """Replaces invalid characters in a given string to make a windows compatible file name. diff --git a/source/appModules/msnmsgr.py b/source/appModules/msnmsgr.py index cefca969d55..5ec21fccf84 100755 --- a/source/appModules/msnmsgr.py +++ b/source/appModules/msnmsgr.py @@ -52,7 +52,7 @@ def _get_basicText(self): def _get_value(self): value=super(OldMSNHistory,self).value - if not isinstance(value,basestring): + if not isinstance(value,str): value="" return value diff --git a/source/baseObject.py b/source/baseObject.py index 865ff75cd17..0781a1403db 100755 --- a/source/baseObject.py +++ b/source/baseObject.py @@ -197,7 +197,7 @@ class ScriptableObject(with_metaclass(ScriptableType, AutoPropertyObject)): e.g. in the Input Gestures dialog. This can be overridden for individual scripts by setting a C{category} attribute on the script method. - @type scriptCategory: basestring + @type scriptCategory: str """ def __init__(self): diff --git a/source/bdDetect.py b/source/bdDetect.py index 1ac7db2a66b..049e6050063 100644 --- a/source/bdDetect.py +++ b/source/bdDetect.py @@ -83,7 +83,7 @@ def addUsbDevices(driver, type, ids): @type ids: set of str @raise ValueError: When one of the provided IDs is malformed. """ - malformedIds = [id for id in ids if not isinstance(id, basestring) or not USB_ID_REGEX.match(id)] + malformedIds = [id for id in ids if not isinstance(id, str) or not USB_ID_REGEX.match(id)] if malformedIds: raise ValueError("Invalid IDs provided for driver %s, type %s: %s" % (driver, type, ", ".join(wrongIds))) diff --git a/source/braille.py b/source/braille.py index e5e154c0c53..2ba2c111a81 100644 --- a/source/braille.py +++ b/source/braille.py @@ -810,7 +810,7 @@ def _addTextWithFields(self, info, formatConfig, isSelection=False): # When true, we are inside a clickable field, and should therefore not report any more new clickable fields inClickable=False for command in info.getTextWithFields(formatConfig=formatConfig): - if isinstance(command, basestring): + if isinstance(command, str): # Text should break a run of clickables inClickable=False self._isFormatFieldAtStart = False @@ -2296,7 +2296,7 @@ def getManualPorts(cls): This is for ports which cannot be detected automatically such as serial ports. @return: The name and description for each port. - @rtype: iterable of basestring, basestring + @rtype: iterable of str, str """ raise NotImplementedError @@ -2305,13 +2305,13 @@ def _getTryPorts(cls, port): """Returns the ports for this driver to which a connection attempt should be made. This generator function is usually used in L{__init__} to connect to the desired display. @param port: the port to connect to. - @type port: one of basestring or L{bdDetect.DeviceMatch} + @type port: one of str or L{bdDetect.DeviceMatch} @return: The name and description for each port. - @rtype: iterable of basestring, basestring + @rtype: iterable of str, str """ if isinstance(port, bdDetect.DeviceMatch): yield port - elif isinstance(port, basestring): + elif isinstance(port, str): isUsb = port in (AUTOMATIC_PORT[0], USB_PORT[0]) isBluetooth = port in (AUTOMATIC_PORT[0], BLUETOOTH_PORT[0]) if not isUsb and not isBluetooth: diff --git a/source/brailleDisplayDrivers/eurobraille.py b/source/brailleDisplayDrivers/eurobraille.py index 393b6705de5..f4bf9a7a83f 100644 --- a/source/brailleDisplayDrivers/eurobraille.py +++ b/source/brailleDisplayDrivers/eurobraille.py @@ -128,7 +128,7 @@ } def bytesToInt(bytes): - """Converts a basestring to its integral equivalent.""" + """Converts a bytes object to its integral equivalent.""" return int(bytes.encode('hex'), 16) class BrailleDisplayDriver(braille.BrailleDisplayDriver, ScriptableObject): diff --git a/source/brailleTables.py b/source/brailleTables.py index 51fbc79ecb5..ff1b4354b35 100644 --- a/source/brailleTables.py +++ b/source/brailleTables.py @@ -28,7 +28,7 @@ def addTable(fileName, displayName, contracted=False, output=True, input=True): """Register a braille translation table. At least one of C{input} or C{output} must be C{True}. @param fileName: The file name of the table. - @type fileName: basestring + @type fileName: str @param displayname: The name of the table as displayed to the user. This should be translatable. @type displayName: unicode @param contracted: C{True} if the table is contracted, C{False} if uncontracted. diff --git a/source/browseMode.py b/source/browseMode.py index 6c1ffcb571d..1f5d54f2002 100644 --- a/source/browseMode.py +++ b/source/browseMode.py @@ -1648,7 +1648,7 @@ def _get_shouldRememberCaretPositionAcrossLoads(self): docConstId = self.documentConstantIdentifier # Return True if the URL indicates that this is probably a web browser document. # We do this check because we don't want to remember caret positions for email messages, etc. - return isinstance(docConstId, basestring) and docConstId.split("://", 1)[0] in ("http", "https", "ftp", "ftps", "file") + return isinstance(docConstId, str) and docConstId.split("://", 1)[0] in ("http", "https", "ftp", "ftps", "file") def _getInitialCaretPos(self): """Retrieve the initial position of the caret after the buffer has been loaded. diff --git a/source/compoundDocuments.py b/source/compoundDocuments.py index 360609c5fc7..c424ba1bec2 100644 --- a/source/compoundDocuments.py +++ b/source/compoundDocuments.py @@ -268,7 +268,7 @@ def getTextWithFields(self, formatConfig=None): embedIndex = None for ti in self._getTextInfos(): for field in ti._iterTextWithEmbeddedObjects(True, formatConfig=formatConfig): - if isinstance(field, basestring): + if isinstance(field, str): fields.append(field) elif isinstance(field, int): # Embedded object if embedIndex is None: diff --git a/source/config/__init__.py b/source/config/__init__.py index 8ad389f09a0..4f8b8378844 100644 --- a/source/config/__init__.py +++ b/source/config/__init__.py @@ -153,7 +153,7 @@ def initConfigPath(configPath=None): """ Creates the current configuration path if it doesn't exist. Also makes sure that various sub directories also exist. @param configPath: an optional path which should be used instead (only useful when being called from outside of NVDA) - @type configPath: basestring + @type configPath: str """ if not configPath: configPath=globalVars.appArgs.configPath @@ -505,7 +505,7 @@ def getProfile(self, name): """Get a profile given its name. This is useful for checking whether a profile has been manually activated or triggered. @param name: The name of the profile. - @type name: basestring + @type name: str @return: The profile object. @raise KeyError: If the profile is not loaded. """ @@ -517,7 +517,7 @@ def manualActivateProfile(self, name): If another profile was manually activated, deactivate it first. If C{name} is C{None}, a profile will not be activated. @param name: The name of the profile or C{None} for no profile. - @type name: basestring + @type name: str """ if len(self.profiles) > 1: profile = self.profiles[-1] @@ -577,7 +577,7 @@ def reset(self, factoryDefaults=False): def createProfile(self, name): """Create a profile. @param name: The name of the profile to create. - @type name: basestring + @type name: str @raise ValueError: If a profile with this name already exists. """ if globalVars.appArgs.secure: @@ -596,7 +596,7 @@ def createProfile(self, name): def deleteProfile(self, name): """Delete a profile. @param name: The name of the profile to delete. - @type name: basestring + @type name: str @raise LookupError: If the profile doesn't exist. """ if globalVars.appArgs.secure: @@ -644,9 +644,9 @@ def deleteProfile(self, name): def renameProfile(self, oldName, newName): """Rename a profile. @param oldName: The current name of the profile. - @type oldName: basestring + @type oldName: str @param newName: The new name for the profile. - @type newName: basestring + @type newName: str @raise LookupError: If the profile doesn't exist. @raise ValueError: If a profile with the new name already exists. """ @@ -1131,7 +1131,7 @@ class ProfileTrigger(object): def spec(self): """The trigger specification. This is a string used to search for this trigger in the user's configuration. - @rtype: basestring + @rtype: str """ raise NotImplementedError diff --git a/source/displayModel.py b/source/displayModel.py index f5495173796..854ee9480d7 100644 --- a/source/displayModel.py +++ b/source/displayModel.py @@ -56,7 +56,7 @@ def processWindowChunksInLine(commandList,rects,startIndex,startOffset,endIndex, lastHwnd=None for index in range(startIndex,endIndex+1): item=commandList[index] if index=1: if curObject.TextInfo!=NVDAObjectTextInfo: textList=[] - if curObject.name and isinstance(curObject.name, basestring) and not curObject.name.isspace(): + if curObject.name and isinstance(curObject.name, str) and not curObject.name.isspace(): textList.append(curObject.name) try: info=curObject.makeTextInfo(textInfos.POSITION_SELECTION) @@ -793,7 +793,7 @@ def script_navigatorObject_current(self,gesture): # No caret or selection on this object. pass else: - textList=[prop for prop in (curObject.name, curObject.value) if prop and isinstance(prop, basestring) and not prop.isspace()] + textList=[prop for prop in (curObject.name, curObject.value) if prop and isinstance(prop, str) and not prop.isspace()] text=" ".join(textList) if len(text)>0 and not text.isspace(): if scriptHandler.getLastScriptRepeatCount()==1: @@ -1498,9 +1498,9 @@ def script_toggleMouseTextResolution(self,gesture): def script_title(self,gesture): obj=api.getForegroundObject() title=obj.name - if not isinstance(title,basestring) or not title or title.isspace(): + if not isinstance(title,str) or not title or title.isspace(): title=obj.appModule.appName if obj.appModule else None - if not isinstance(title,basestring) or not title or title.isspace(): + if not isinstance(title,str) or not title or title.isspace(): # Translators: Reported when there is no title text for current program or window. title=_("No title") repeatCount=scriptHandler.getLastScriptRepeatCount() @@ -1920,7 +1920,7 @@ def script_reportClipboardText(self,gesture): text = api.getClipData() except: text = None - if not text or not isinstance(text,basestring) or text.isspace(): + if not text or not isinstance(text,str) or text.isspace(): # Translators: Presented when there is no text on the clipboard. ui.message(_("There is no text on the clipboard")) return diff --git a/source/gui/settingsDialogs.py b/source/gui/settingsDialogs.py index 143dba8c699..1e13fbf7342 100644 --- a/source/gui/settingsDialogs.py +++ b/source/gui/settingsDialogs.py @@ -3270,7 +3270,7 @@ def onTreeSelect(self, evt): return data = self.tree.GetItemData(item) isCommand = isinstance(data, inputCore.AllGesturesScriptInfo) - isGesture = isinstance(data, basestring) + isGesture = isinstance(data, str) self.addButton.Enabled = isCommand or isGesture self.removeButton.Enabled = isGesture diff --git a/source/inputCore.py b/source/inputCore.py index 793b8917070..5b248d8084b 100644 --- a/source/inputCore.py +++ b/source/inputCore.py @@ -84,7 +84,7 @@ def _get_identifiers(self): Subclasses must implement this method. @return: One or more identifiers which uniquely identify this gesture. - @rtype: list or tuple of basestring + @rtype: list or tuple of str """ raise NotImplementedError @@ -95,7 +95,7 @@ def _get_normalizedIdentifiers(self): These normalized identifiers can be directly looked up in input gesture maps. Subclasses should not override this method. @return: One or more normalized identifiers which uniquely identify this gesture. - @rtype: list of basestring + @rtype: list of str """ return [normalizeGestureIdentifier(identifier) for identifier in self.identifiers] @@ -167,9 +167,9 @@ def getDisplayTextForIdentifier(cls, identifier): the gesture's source (e.g. "laptop keyboard") and the specific gesture (e.g. "alt+tab"). @param identifier: The normalized gesture identifier in question. - @type identifier: basestring + @type identifier: str @return: A tuple of (source, specificGesture). - @rtype: tuple of (basestring, basestring) + @rtype: tuple of (str, str) @raise Exception: If no display text can be determined. """ raise NotImplementedError @@ -191,7 +191,7 @@ def __init__(self, entries=None): #: @type: bool self.lastUpdateContainedError = False #: The file name for this gesture map, if any. - #: @type: basestring + #: @type: str self.fileName = None if entries: self.update(entries) @@ -280,7 +280,7 @@ def update(self, entries): script = None if gestures == "": gestures = () - elif isinstance(gestures, basestring): + elif isinstance(gestures, str): gestures = [gestures] for gesture in gestures: try: @@ -733,7 +733,7 @@ def registerGestureSource(source, gestureCls): "br" will be used if it is registered. This registration is used, for example, to get the display text for a gesture identifier. @param source: The source prefix for associated gesture identifiers. - @type source: basestring + @type source: str @param gestureCls: The input gesture class. @type gestureCls: L{InputGesture} """ @@ -761,9 +761,9 @@ def getDisplayTextForGestureIdentifier(identifier): the gesture's source (e.g. "laptop keyboard") and the specific gesture (e.g. "alt+tab"). @param identifier: The normalized gesture identifier in question. - @type identifier: basestring + @type identifier: str @return: A tuple of (source, specificGesture). - @rtype: tuple of (basestring, basestring) + @rtype: tuple of (str, str) @raise LookupError: If no display text can be determined. """ gcls = _getGestureClsForIdentifier(identifier) diff --git a/source/mathPres/__init__.py b/source/mathPres/__init__.py index cf0cb52c823..2e874131905 100644 --- a/source/mathPres/__init__.py +++ b/source/mathPres/__init__.py @@ -29,7 +29,7 @@ class MathPresentationProvider(object): def getSpeechForMathMl(self, mathMl): """Get speech output for specified MathML markup. @param mathMl: The MathML markup. - @type mathMl: basestring + @type mathMl: str @return: A speech sequence. @rtype: list of unicode and/or L{speech.SpeechCommand} """ @@ -38,7 +38,7 @@ def getSpeechForMathMl(self, mathMl): def getBrailleForMathMl(self, mathMl): """Get braille output for specified MathML markup. @param mathMl: The MathML markup. - @type mathMl: basestring + @type mathMl: str @return: A string of Unicode braille. @rtype: unicode """ @@ -136,7 +136,7 @@ def getMathMlFromTextInfo(pos): @param pos: The TextInfo in question. @type pos: L{textInfos.TextInfo} @return: The MathML or C{None} if there is no math. - @rtype: basestring + @rtype: str """ pos = pos.copy() pos.expand(textInfos.UNIT_CHARACTER) @@ -172,7 +172,7 @@ def interactWithMathMl(mathMl): def getLanguageFromMath(mathMl): """Get the language specified in a math tag. @return: The language or C{None} if unspeicifed. - @rtype: basestring + @rtype: str """ m = RE_MATH_LANG.search(mathMl) if m: diff --git a/source/nvwave.py b/source/nvwave.py index 076f25eafb1..f06033f5483 100644 --- a/source/nvwave.py +++ b/source/nvwave.py @@ -117,7 +117,7 @@ def __init__(self, channels, samplesPerSec, bitsPerSample, @param bitsPerSample: The number of bits per sample. @type bitsPerSample: int @param outputDevice: The device ID or name of the audio output device to use. - @type outputDevice: int or basestring + @type outputDevice: int or str @param closeWhenIdle: If C{True}, close the output device when no audio is being played. @type closeWhenIdle: bool @param wantDucking: if true then background audio will be ducked on Windows 8 and higher @@ -130,7 +130,7 @@ def __init__(self, channels, samplesPerSec, bitsPerSample, self.channels=channels self.samplesPerSec=samplesPerSec self.bitsPerSample=bitsPerSample - if isinstance(outputDevice, basestring): + if isinstance(outputDevice, str): outputDevice = outputDeviceNameToID(outputDevice, True) self.outputDeviceID = outputDevice if wantDucking: diff --git a/source/oleacc.py b/source/oleacc.py index d97ec999dbf..260470df755 100644 --- a/source/oleacc.py +++ b/source/oleacc.py @@ -192,7 +192,7 @@ def CreateStdAccessibleProxy(hwnd,className,objectID,interface=IAccessible): @param hwnd: the handle of the window this accessible object should represent. @type hwnd: int @param className: the window class name to use. - @type className: basestring + @type className: str @param objectID: an OBJID_* constant or custom value stating the specific object in the window. @type objectID: int @param interface: the requested COM interface for this object. Defaults to IAccessible. diff --git a/source/speech/__init__.py b/source/speech/__init__.py index b3162c54cc1..fea6253052c 100755 --- a/source/speech/__init__.py +++ b/source/speech/__init__.py @@ -138,7 +138,7 @@ def spellTextInfo(info,useCharacterDescriptions=False,priority=None): return curLanguage=None for field in info.getTextWithFields({}): - if isinstance(field,basestring): + if isinstance(field,str): speakSpelling(field,curLanguage,useCharacterDescriptions=useCharacterDescriptions,priority=priority) elif isinstance(field,textInfos.FieldCommand) and field.command=="formatChange": curLanguage=field.field.get('language') @@ -430,9 +430,9 @@ def speakText(text,reason=controlTypes.REASON_MESSAGE,symbolLevel=None,priority= def splitTextIndentation(text): """Splits indentation from the rest of the text. @param text: The text to split. - @type text: basestring + @type text: str @return: Tuple of indentation and content. - @rtype: (basestring, basestring) + @rtype: (str, str) """ return RE_INDENTATION_SPLIT.match(text).groups() @@ -502,7 +502,7 @@ def speak(speechSequence, symbolLevel=None, priority=None): import speechViewer if speechViewer.isActive: for item in speechSequence: - if isinstance(item, basestring): + if isinstance(item, str): speechViewer.appendText(item) global beenCanceled if speechMode==speechMode_off: @@ -528,7 +528,7 @@ def speak(speechSequence, symbolLevel=None, priority=None): curLanguage=item.lang if not curLanguage or (not autoDialectSwitching and curLanguage.split('_')[0]==defaultLanguageRoot): curLanguage=defaultLanguage - elif isinstance(item,basestring): + elif isinstance(item,str): if not item: continue if autoLanguageSwitching and curLanguage!=prevLanguage: speechSequence.append(LangChangeCommand(curLanguage)) @@ -553,7 +553,7 @@ def speak(speechSequence, symbolLevel=None, priority=None): inCharacterMode=item.state if autoLanguageSwitching and isinstance(item,LangChangeCommand): curLanguage=item.lang - if isinstance(item,basestring): + if isinstance(item,str): speechSequence[index]=processText(curLanguage,item,symbolLevel) if not inCharacterMode: speechSequence[index]+=CHUNK_SEPARATOR @@ -884,7 +884,7 @@ def speakTextInfo(info, useCache=True, formatConfig=None, unit=None, reason=cont if onlyInitialFields or (unit in (textInfos.UNIT_CHARACTER,textInfos.UNIT_WORD) and len(textWithFields)>0 and len(textWithFields[0])==1 and all((isinstance(x,textInfos.FieldCommand) and x.command=="controlEnd") for x in itertools.islice(textWithFields,1,None) )): if not onlyCache: - if onlyInitialFields or any(isinstance(x,basestring) for x in speechSequence): + if onlyInitialFields or any(isinstance(x,str) for x in speechSequence): speak(speechSequence,priority=priority) if not onlyInitialFields: speakSpelling(textWithFields[0],locale=language if autoLanguageSwitching else None,priority=priority) @@ -906,7 +906,7 @@ def speakTextInfo(info, useCache=True, formatConfig=None, unit=None, reason=cont allIndentation="" indentationDone=False for command in textWithFields: - if isinstance(command,basestring): + if isinstance(command,str): # Text should break a run of clickables inClickable=False if reportIndentation and not indentationDone: @@ -985,7 +985,7 @@ def speakTextInfo(info, useCache=True, formatConfig=None, unit=None, reason=cont # Don't add this text if it is blank. relativeBlank=True for x in relativeSpeechSequence: - if isinstance(x,basestring) and not isBlank(x): + if isinstance(x,str) and not isBlank(x): relativeBlank=False break if not relativeBlank: @@ -1772,7 +1772,7 @@ def speakWithoutPauses(speechSequence,detectBreaks=True): #And place the final incomplete phrase in pendingSpeechSequence for index in range(len(speechSequence)-1,-1,-1): item=speechSequence[index] - if isinstance(item,basestring): + if isinstance(item,str): m=re_last_pause.match(item) if m: before,after=m.groups() diff --git a/source/speechViewer.py b/source/speechViewer.py index d2e60f55f43..d520b720fb1 100644 --- a/source/speechViewer.py +++ b/source/speechViewer.py @@ -90,7 +90,7 @@ def _setActive(isNowActive, speechViewerFrame=None): def appendText(text): if not isActive: return - if not isinstance(text,basestring): + if not isinstance(text,str): return #If the speech viewer text control has the focus, we want to disable updates #Otherwise it would be impossible to select text, or even just read it (as a blind person). diff --git a/source/speechXml.py b/source/speechXml.py index 11f0a3a492f..43b7040a8ee 100644 --- a/source/speechXml.py +++ b/source/speechXml.py @@ -154,7 +154,7 @@ def generateXml(self, commands): """Generate XML from a sequence of balancer commands and text. """ for command in commands: - if isinstance(command, basestring): + if isinstance(command, str): self._outputTags() self._text(command) elif isinstance(command, EncloseAllCommand): @@ -206,7 +206,7 @@ def generateBalancerCommands(self, speechSequence): @rtype: generator """ for item in speechSequence: - if isinstance(item, basestring): + if isinstance(item, str): yield item elif isinstance(item, speech.SpeechCommand): name = type(item).__name__ diff --git a/source/synthDriverHandler.py b/source/synthDriverHandler.py index a2b35cb2ecf..d4574bd3953 100644 --- a/source/synthDriverHandler.py +++ b/source/synthDriverHandler.py @@ -275,7 +275,7 @@ def speak(self,speechSequence): if item is None: # No more items. break - if isinstance(item,basestring): + if isinstance(item,str): # Merge the text between commands into a single chunk. text+=item elif isinstance(item,speech.IndexCommand): diff --git a/source/synthDrivers/espeak.py b/source/synthDrivers/espeak.py index a72a7c950e1..4119878f0e3 100644 --- a/source/synthDrivers/espeak.py +++ b/source/synthDrivers/espeak.py @@ -90,7 +90,7 @@ def speak(self,speechSequence): # . # However, eSpeak doesn't seem to mind. for item in speechSequence: - if isinstance(item,basestring): + if isinstance(item,str): textList.append(self._processText(item)) elif isinstance(item,speech.IndexCommand): textList.append(""%item.index) diff --git a/source/synthDrivers/oneCore.py b/source/synthDrivers/oneCore.py index 11894bef05f..02d3f888eb5 100644 --- a/source/synthDrivers/oneCore.py +++ b/source/synthDrivers/oneCore.py @@ -204,7 +204,7 @@ def cancel(self): if self.supportsProsodyOptions: # In this case however, we must keep any parameter changes. self._queuedSpeech = [item for item in self._queuedSpeech - if not isinstance(item, basestring)] + if not isinstance(item, str)] else: self._queuedSpeech = [] if self._player: @@ -405,7 +405,7 @@ def _isVoiceValid(self,ID): except WindowsError as e: log.debugWarning("Could not open registry value 'langDataPath', %r" % e) return False - if not langDataPath or not isinstance(langDataPath[0], basestring): + if not langDataPath or not isinstance(langDataPath[0], str): log.debugWarning("Invalid langDataPath value") return False if not os.path.isfile(os.path.expandvars(langDataPath[0])): @@ -416,7 +416,7 @@ def _isVoiceValid(self,ID): except WindowsError as e: log.debugWarning("Could not open registry value 'langDataPath', %r" % e) return False - if not voicePath or not isinstance(voicePath[0],basestring): + if not voicePath or not isinstance(voicePath[0],str): log.debugWarning("Invalid voicePath value") return False if not os.path.isfile(os.path.expandvars(voicePath[0] + '.apm')): diff --git a/source/synthDrivers/sapi4.py b/source/synthDrivers/sapi4.py index 4e75af9b783..21d33cd8ee9 100755 --- a/source/synthDrivers/sapi4.py +++ b/source/synthDrivers/sapi4.py @@ -88,7 +88,7 @@ def speak(self,speechSequence): charMode=False item=None for item in speechSequence: - if isinstance(item,basestring): + if isinstance(item,str): textList.append(item.replace('\\','\\\\')) elif isinstance(item,speech.IndexCommand): textList.append("\\mrk=%d\\"%item.index) diff --git a/source/synthDrivers/sapi5.py b/source/synthDrivers/sapi5.py index d183007742b..36c412301be 100644 --- a/source/synthDrivers/sapi5.py +++ b/source/synthDrivers/sapi5.py @@ -286,7 +286,7 @@ def outputTags(): volume = self.volume for item in speechSequence: - if isinstance(item, basestring): + if isinstance(item, str): outputTags() textList.append(item.replace("<", "<")) elif isinstance(item, speech.IndexCommand): diff --git a/source/textInfos/__init__.py b/source/textInfos/__init__.py index e0a0364c1f0..3a006833fa0 100755 --- a/source/textInfos/__init__.py +++ b/source/textInfos/__init__.py @@ -484,7 +484,7 @@ def getFormatFieldSpeech(self, attrs, attrsCache=None, formatConfig=None, reason If extended, the superclass should be called first. @param separator: The text used to separate chunks of format information; defaults to L{speech.CHUNK_SEPARATOR}. - @type separator: basestring + @type separator: str """ # Import late to avoid circular import. import speech diff --git a/source/virtualBuffers/MSHTML.py b/source/virtualBuffers/MSHTML.py index df759ba70dc..fcb93c6d908 100644 --- a/source/virtualBuffers/MSHTML.py +++ b/source/virtualBuffers/MSHTML.py @@ -57,7 +57,7 @@ def _normalizeControlField(self,attrs): if placeholder: attrs['placeholder']=placeholder accRole=attrs.get('IAccessible::role',0) - accRole=int(accRole) if isinstance(accRole,basestring) and accRole.isdigit() else accRole + accRole=int(accRole) if isinstance(accRole,str) and accRole.isdigit() else accRole nodeName=attrs.get('IHTMLDOMNode::nodeName',"") ariaRoles=attrs.get("HTMLAttrib::role", "").split(" ") #choose role diff --git a/source/windowUtils.py b/source/windowUtils.py index 672cb908804..691c72c62c8 100644 --- a/source/windowUtils.py +++ b/source/windowUtils.py @@ -23,7 +23,7 @@ def findDescendantWindow(parent, visible=None, controlID=None, className=None): @param controlID: The control ID of the window or C{None} if irrelevant. @type controlID: int @param className: The class name of the window or C{None} if irrelevant. - @type className: basestring + @type className: str @return: The handle of the matching descendant window. @rtype: int @raise LookupError: if no matching window is found. From 97f43800cb5da933707fdd0d116e9b4644081a0f Mon Sep 17 00:00:00 2001 From: Michael Curran Date: Wed, 12 Jun 2019 16:10:28 +1000 Subject: [PATCH 3/5] Remove usage of unicode() which is not available in Python3. --- source/NVDAObjects/window/edit.py | 3 ++- source/NVDAObjects/window/scintilla.py | 5 ++-- source/addonHandler/__init__.py | 7 +++--- source/appModuleHandler.py | 14 ++++------- source/appModules/winamp.py | 6 ++++- source/bdDetect.py | 4 ++-- source/braille.py | 2 +- source/brailleInput.py | 8 +++---- source/brailleTables.py | 2 +- source/buildVersion.py | 2 -- source/characterProcessing.py | 2 +- source/config/__init__.py | 4 +--- source/contentRecog/uwpOcr.py | 2 +- source/core.py | 2 +- source/hwIo.py | 4 ++-- source/installer.py | 2 +- source/languageHandler.py | 2 +- source/louisHelper.py | 2 +- source/mathPres/__init__.py | 2 +- source/nvda.pyw | 4 ++-- source/nvda_slave.pyw | 2 +- source/nvwave.py | 8 +++---- source/scriptHandler.py | 3 --- source/speech/__init__.py | 12 +++++----- source/speech/commands.py | 4 ++-- source/speechXml.py | 2 +- source/synthDrivers/_espeak.py | 32 ++++++++++++++++---------- source/synthDrivers/espeak.py | 11 ++++----- source/textInfos/__init__.py | 4 ++-- source/textInfos/offsets.py | 10 ++++---- source/ui.py | 8 +++---- source/virtualBuffers/__init__.py | 12 +++++----- source/winKernel.py | 2 +- source/winUser.py | 2 +- source/windowUtils.py | 6 ++--- tests/unit/textProvider.py | 4 ++-- 36 files changed, 101 insertions(+), 100 deletions(-) diff --git a/source/NVDAObjects/window/edit.py b/source/NVDAObjects/window/edit.py index 17d98443d62..7de6a696d9a 100644 --- a/source/NVDAObjects/window/edit.py +++ b/source/NVDAObjects/window/edit.py @@ -372,7 +372,8 @@ def _getTextRange(self,start,end): if self.obj.isWindowUnicode or (res>1 and (buf[res]!=0 or buf[res+1]!=0)): text=ctypes.cast(buf,ctypes.c_wchar_p).value else: - text=unicode(ctypes.cast(buf,ctypes.c_char_p).value, errors="replace", encoding=locale.getlocale()[1]) + encoding=locale.getlocale()[1] + text=ctypes.cast(buf,ctypes.c_char_p).value.decode(encoding,errors="replace") # #4095: Some protected richEdit controls do not hide their password characters. # We do this specifically. # Note that protected standard edit controls get characters hidden in _getStoryText. diff --git a/source/NVDAObjects/window/scintilla.py b/source/NVDAObjects/window/scintilla.py index 8527d03f1e0..fc6741f2ce2 100755 --- a/source/NVDAObjects/window/scintilla.py +++ b/source/NVDAObjects/window/scintilla.py @@ -176,9 +176,10 @@ def _getTextRange(self,start,end): winKernel.virtualFreeEx(processHandle,internalBuf,0,winKernel.MEM_RELEASE) cp=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETCODEPAGE,0,0) if cp==SC_CP_UTF8: - return unicode(buf.value, errors="replace", encoding="utf-8") + encoding="utf-8" else: - return unicode(buf.value, errors="replace", encoding=locale.getlocale()[1]) + encoding=locale.getlocale()[1] + return buf.value.decode(encoding,errors="replace") def _getWordOffsets(self,offset): start=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDSTARTPOSITION,offset,0) diff --git a/source/addonHandler/__init__.py b/source/addonHandler/__init__.py index 0af4c3822e0..6158e6fbe5f 100644 --- a/source/addonHandler/__init__.py +++ b/source/addonHandler/__init__.py @@ -363,7 +363,6 @@ def addToPackagePath(self, package): if not os.path.isdir(extension_path): # This addon does not have extension points for this package return - # Python 2.x doesn't properly handle unicode import paths, so convert them before adding. converted_path = self._getPathForInclusionInPackage(package) package.__path__.insert(0, converted_path) self._extendedPackages.add(package) @@ -507,7 +506,7 @@ def getCodeAddon(obj=None, frameDist=1): if obj is None: obj = sys._getframe(frameDist) fileName = inspect.getfile(obj) - dir= unicode(os.path.abspath(os.path.dirname(fileName)), "mbcs") + dir= os.path.abspath(os.path.dirname(fileName)) # if fileName is not a subdir of one of the addon paths # It does not belong to an addon. for p in _getDefaultAddonPaths(): @@ -558,7 +557,7 @@ def __init__(self, bundlePath): """ Constructs an L{AddonBundle} from a filename. @param bundlePath: The path for the bundle file. """ - self._path = bundlePath if isinstance(bundlePath, unicode) else unicode(bundlePath, "mbcs") + self._path = bundlePath # Read manifest: translatedInput=None with zipfile.ZipFile(self._path, 'r') as z: @@ -581,7 +580,7 @@ def extract(self, addonPath): """ with zipfile.ZipFile(self._path, 'r') as z: for info in z.infolist(): - if isinstance(info.filename, str): + if isinstance(info.filename, bytes): # #2505: Handle non-Unicode file names. # Most archivers seem to use the local OEM code page, even though the spec says only cp437. # HACK: Overriding info.filename is a bit ugly, but it avoids a lot of code duplication. diff --git a/source/appModuleHandler.py b/source/appModuleHandler.py index 759cbb84921..130caa90688 100644 --- a/source/appModuleHandler.py +++ b/source/appModuleHandler.py @@ -70,7 +70,7 @@ def getAppNameFromProcessID(processID,includeExt=False): @param includeExt: C{True} to include the extension of the application's executable filename, C{False} to exclude it. @type window: bool @returns: application name - @rtype: unicode or str + @rtype: str """ if processID==NVDAProcessID: return "nvda.exe" if includeExt else "nvda" @@ -78,7 +78,7 @@ def getAppNameFromProcessID(processID,includeExt=False): FProcessEntry32 = processEntry32W() FProcessEntry32.dwSize = ctypes.sizeof(processEntry32W) ContinueLoop = winKernel.kernel32.Process32FirstW(FSnapshotHandle, ctypes.byref(FProcessEntry32)) - appName = unicode() + appName = str() while ContinueLoop: if FProcessEntry32.th32ProcessID == processID: appName = FProcessEntry32.szExeFile @@ -93,8 +93,6 @@ def getAppNameFromProcessID(processID,includeExt=False): # This might be an executable which hosts multiple apps. # Try querying the app module for the name of the app being hosted. try: - # Python 2.x can't properly handle unicode module names, so convert them. - # #8768 (Py3 review required): no longer the case in Python 3. mod = importlib.import_module("appModules.%s" % appName, package="appModules") return mod.getAppNameFromHost(processID) except (ImportError, AttributeError, LookupError): @@ -162,23 +160,21 @@ def fetchAppModule(processID,appName): @param processID: process ID for it to be associated with @type processID: integer @param appName: the application name for which an appModule should be found. - @type appName: unicode or str + @type appName: str @returns: the appModule, or None if not found @rtype: AppModule """ # First, check whether the module exists. # We need to do this separately because even though an ImportError is raised when a module can't be found, it might also be raised for other reasons. - # Python 2.x can't properly handle unicode module names, so convert them. - modName = appName.encode("mbcs") + modName = appName if doesAppModuleExist(modName): try: return importlib.import_module("appModules.%s" % modName, package="appModules").AppModule(processID, appName) except: log.error("error in appModule %r"%modName, exc_info=True) - # We can't present a message which isn't unicode, so use appName, not modName. # Translators: This is presented when errors are found in an appModule (example output: error in appModule explorer). - ui.message(_("Error in appModule %s")%appName) + ui.message(_("Error in appModule %s")%modName) # Use the base AppModule. return AppModule(processID, appName) diff --git a/source/appModules/winamp.py b/source/appModules/winamp.py index 5e252b7c373..a155fc8b766 100644 --- a/source/appModules/winamp.py +++ b/source/appModules/winamp.py @@ -115,7 +115,11 @@ def _get_name(self): winKernel.readProcessMemory(self.processHandle,internalInfo,byref(info),sizeof(info),None) finally: winKernel.virtualFreeEx(self.processHandle,internalInfo,0,winKernel.MEM_RELEASE) - return unicode("%d.\t%s\t%s"%(curIndex+1,info.filetitle,info.filelength), errors="replace", encoding=locale.getlocale()[1]) + # file title is fetched in the current locale encoding. + # We need to decode it to unicode first. + encoding=locale.getlocale()[1] + fileTitle=info.filetitle.decode(encoding,errors="replace") + return "%d.\t%s\t%s"%(curIndex+1,fileTitle,info.filelength) def _get_role(self): return controlTypes.ROLE_LISTITEM diff --git a/source/bdDetect.py b/source/bdDetect.py index 049e6050063..3f5229a7439 100644 --- a/source/bdDetect.py +++ b/source/bdDetect.py @@ -40,9 +40,9 @@ class DeviceMatch( ): """Represents a detected device. @ivar id: The identifier of the device. - @type id: unicode + @type id: str @ivar port: The port that can be used by a driver to communicate with a device. - @type port: unicode + @type port: str @ivar deviceInfo: all known information about a device. @type deviceInfo: dict """ diff --git a/source/braille.py b/source/braille.py index 2ba2c111a81..2b36760e950 100644 --- a/source/braille.py +++ b/source/braille.py @@ -330,7 +330,7 @@ def getDisplayList(excludeNegativeChecks=True): @param excludeNegativeChecks: excludes all drivers for which the check method returns C{False}. @type excludeNegativeChecks: bool @return: list of tuples with driver names and descriptions. - @rtype: [(str,unicode)] + @rtype: [(str,str)] """ displayList = [] # The display that should be placed at the end of the list. diff --git a/source/brailleInput.py b/source/brailleInput.py index 641d609aa6e..af5c559d101 100644 --- a/source/brailleInput.py +++ b/source/brailleInput.py @@ -36,7 +36,7 @@ #: @type: int UNICODE_BRAILLE_START = 0x2800 #: The Unicode braille character to use when masking cells in protected fields. -#: @type: unicode +#: @type: str UNICODE_BRAILLE_PROTECTED = u"⣿" # All dots down #: The singleton BrailleInputHandler instance. @@ -82,7 +82,7 @@ def __init__(self): #: or were translated but did not produce any text. #: This is used to show these cells to the user while they're entering braille. #: This is a string of Unicode braille. - #: @type: unicode + #: @type: str self.untranslatedBraille = "" #: The position in L{brailleBuffer} where untranslated braille begins. self.untranslatedStart = 0 @@ -175,7 +175,7 @@ def _translate(self, endWord): def _translateForReportContractedCell(self, pos): """Translate text for current input as required by L{_reportContractedCell}. @return: The previous translated text. - @rtype: unicode + @rtype: str """ cells = self.bufferBraille[:pos + 1] data = u"".join([chr(cell | LOUIS_DOTS_IO_START) for cell in cells]) @@ -385,7 +385,7 @@ def emulateKey(self, key, withModifiers=True): def sendChars(self, chars): """Sends the provided unicode characters to the system. @param chars: The characters to send to the system. - @type chars: unicode + @type chars: str """ inputs = [] for ch in chars: diff --git a/source/brailleTables.py b/source/brailleTables.py index ff1b4354b35..a43cc8ea00f 100644 --- a/source/brailleTables.py +++ b/source/brailleTables.py @@ -30,7 +30,7 @@ def addTable(fileName, displayName, contracted=False, output=True, input=True): @param fileName: The file name of the table. @type fileName: str @param displayname: The name of the table as displayed to the user. This should be translatable. - @type displayName: unicode + @type displayName: str @param contracted: C{True} if the table is contracted, C{False} if uncontracted. @type cContracted: bool @param output: C{True} if this table can be used for output, C{False} if not. diff --git a/source/buildVersion.py b/source/buildVersion.py index 130bc3072d4..975583b1be4 100644 --- a/source/buildVersion.py +++ b/source/buildVersion.py @@ -63,8 +63,6 @@ def formatVersionForGUI(year, major, minor): return "{y}.{M}.{m}".format(y=year, M=major, m=minor) -# ticket:3763#comment:19: name must be str, not unicode. -# Otherwise, py2exe will break. name="NVDA" version_year=2019 version_major=4 diff --git a/source/characterProcessing.py b/source/characterProcessing.py index 6a55f61dc8d..f0f1d3b9dfa 100644 --- a/source/characterProcessing.py +++ b/source/characterProcessing.py @@ -618,7 +618,7 @@ def deleteSymbol(self, symbol): def isBuiltin(self, symbolIdentifier): """Determine whether a symbol is built in. @param symbolIdentifier: The identifier of the symbol in question. - @type symbolIdentifier: unicode + @type symbolIdentifier: str @return: C{True} if the symbol is built in, C{False} if it was added by the user. @rtype: bool diff --git a/source/config/__init__.py b/source/config/__init__.py index 4f8b8378844..f3a3984d41a 100644 --- a/source/config/__init__.py +++ b/source/config/__init__.py @@ -94,7 +94,7 @@ def isInstalledCopy(): #: When setting it manually, a DWORD value is prefered. #: A value of 0 will evaluate to loading the configuration from the roaming application data (default). #: A value of 1 means loading the configuration from the local application data folder. -#: @type: unicode +#: @type: str CONFIG_IN_LOCAL_APPDATA_SUBKEY=u"configInLocalAppData" def getInstalledUserConfigPath(): @@ -338,8 +338,6 @@ def addConfigDirsToPythonPackagePath(module, subdir=None): if not subdir: subdir = module.__name__ fullPath=os.path.join(getScratchpadDir(),subdir) - # Python 2.x doesn't properly handle unicode import paths, so convert them. - fullPath=fullPath.encode("mbcs") # Insert this path at the beginning of the module's search paths. # The module's search paths may not be a mutable list, so replace it with a new one pathList=[fullPath] diff --git a/source/contentRecog/uwpOcr.py b/source/contentRecog/uwpOcr.py index 119470fb774..2db83e5cae4 100644 --- a/source/contentRecog/uwpOcr.py +++ b/source/contentRecog/uwpOcr.py @@ -21,7 +21,7 @@ def getLanguages(): @return: A list of language codes suitable to be passed to L{UwpOcr}'s constructor. These need to be normalized with L{languageHandler.normalizeLanguage} for use as NVDA language codes. - @rtype: list of unicode + @rtype: list of str """ dll = NVDAHelper.getHelperLocalWin10Dll() dll.uwpOcr_getLanguages.restype = NVDAHelper.bstrReturn diff --git a/source/core.py b/source/core.py index 3503a4a3c0e..608fbc1dadc 100644 --- a/source/core.py +++ b/source/core.py @@ -376,7 +376,7 @@ def handlePowerStatusChange(self): #Translators: Reported when the battery is no longer plugged in, and now is not charging. ui.message(_("Not charging battery. %d percent") %sps.BatteryLifePercent) - messageWindow = MessageWindow(unicode(versionInfo.name)) + messageWindow = MessageWindow(versionInfo.name) # initialize wxpython localization support locale = wx.Locale() diff --git a/source/hwIo.py b/source/hwIo.py index 4403518ec8b..4ffc739b7d9 100644 --- a/source/hwIo.py +++ b/source/hwIo.py @@ -248,7 +248,7 @@ def __init__(self, path, onReceive, exclusive=True): """Constructor. @param path: The device path. This can be retrieved using L{hwPortUtils.listHidDevices}. - @type path: unicode + @type path: str @param onReceive: A callable taking a received input report as its only argument. @type onReceive: callable(str) @param exclusive: Whether to block other application's access to this device. @@ -349,7 +349,7 @@ class Bulk(IoBase): def __init__(self, path, epIn, epOut, onReceive, onReceiveSize=1, writeSize=None): """Constructor. @param path: The device path. - @type path: unicode + @type path: str @param epIn: The endpoint to read data from. @type epIn: int @param epOut: The endpoint to write data to. diff --git a/source/installer.py b/source/installer.py index cd53ddb85b6..a368ebc9194 100644 --- a/source/installer.py +++ b/source/installer.py @@ -358,7 +358,7 @@ def tryRemoveFile(path,numRetries=6,retryInterval=0.5,rebootOK=False): time.sleep(retryInterval) if rebootOK: log.debugWarning("Failed to delete file %s, marking for delete on reboot"%tempPath) - MoveFileEx=windll.kernel32.MoveFileExW if isinstance(tempPath,unicode) else windll.kernel32.MoveFileExA + MoveFileEx=windll.kernel32.MoveFileExW MoveFileEx("\\\\?\\"+tempPath,None,4) return try: diff --git a/source/languageHandler.py b/source/languageHandler.py index 10ec72ee191..72cf24c0250 100644 --- a/source/languageHandler.py +++ b/source/languageHandler.py @@ -37,7 +37,7 @@ def localeNameToWindowsLCID(localeName): # Windows Vista (NT 6.0) and later is able to convert locale names to LCIDs. # Because NVDA supports Windows 7 (NT 6.1) SP1 and later, just use it directly. localeName=localeName.replace('_','-') - LCID=ctypes.windll.kernel32.LocaleNameToLCID(unicode(localeName),0) + LCID=ctypes.windll.kernel32.LocaleNameToLCID(localeName,0) # #6259: In Windows 10, LOCALE_CUSTOM_UNSPECIFIED is returned for any locale name unknown to Windows. # This was observed for Aragonese ("an"). # See https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.lcid(v=vs.110).aspx. diff --git a/source/louisHelper.py b/source/louisHelper.py index 1cd21f42c58..6843c017336 100644 --- a/source/louisHelper.py +++ b/source/louisHelper.py @@ -55,7 +55,7 @@ def translate(tableList, inbuf, typeform=None, cursorPos=None, mode=0): * returns a list of integers instead of an string with cells, and * distinguishes between cursor position 0 (cursor at first character) and None (no cursor at all) """ - text = unicode(inbuf).replace('\0','') + text = inbuf.replace('\0','') braille, brailleToRawPos, rawToBraillePos, brailleCursorPos = louis.translate( tableList, text, diff --git a/source/mathPres/__init__.py b/source/mathPres/__init__.py index 2e874131905..5b55d706985 100644 --- a/source/mathPres/__init__.py +++ b/source/mathPres/__init__.py @@ -31,7 +31,7 @@ def getSpeechForMathMl(self, mathMl): @param mathMl: The MathML markup. @type mathMl: str @return: A speech sequence. - @rtype: list of unicode and/or L{speech.SpeechCommand} + @rtype: list of str and/or L{speech.SpeechCommand} """ raise NotImplementedError diff --git a/source/nvda.pyw b/source/nvda.pyw index 42ad41eab07..4fbe401ebb7 100755 --- a/source/nvda.pyw +++ b/source/nvda.pyw @@ -54,14 +54,14 @@ class NoConsoleOptionParser(argparse.ArgumentParser): def print_help(self, file=None): """Shows help in a standard Windows message dialog""" - winUser.MessageBox(0, unicode(self.format_help()), u"Help", 0) + winUser.MessageBox(0, self.format_help(), u"Help", 0) def error(self, message): """Shows an error in a standard Windows message dialog, and then exits NVDA""" out = "" out = self.format_usage() out += "\nerror: %s" % message - winUser.MessageBox(0, unicode(out), u"Error", 0) + winUser.MessageBox(0, out, u"Error", 0) sys.exit(2) globalVars.startTime=time.time() diff --git a/source/nvda_slave.pyw b/source/nvda_slave.pyw index e4fc0d79431..33d6fec4b3c 100755 --- a/source/nvda_slave.pyw +++ b/source/nvda_slave.pyw @@ -69,7 +69,7 @@ def main(): shellapi.ShellExecute(0,None,path,None,None,winUser.SW_SHOWNORMAL) elif action == "addons_installAddonPackage": try: - addonPath=unicode(args[0], "mbcs") + addonPath=args[0] except IndexError: raise ValueError("Addon path was not provided.") #Load nvdaHelperRemote.dll but with an altered search path so it can pick up other dlls in lib diff --git a/source/nvwave.py b/source/nvwave.py index f06033f5483..6e61b685b18 100644 --- a/source/nvwave.py +++ b/source/nvwave.py @@ -146,7 +146,7 @@ def __init__(self, channels, samplesPerSec, bitsPerSample, BITS_PER_BYTE = 8 MS_PER_SEC = 1000 self._minBufferSize = samplesPerSec * channels * (bitsPerSample / BITS_PER_BYTE) / MS_PER_SEC * self.MIN_BUFFER_MS - self._buffer = "" + self._buffer = b"" else: self._minBufferSize = None #: Function to call when the previous chunk of audio has finished playing. @@ -198,7 +198,7 @@ def feed(self, data, onDone=None): # so we can accurately call onDone at the end of this chunk. if onDone or len(self._buffer) > self._minBufferSize: self._feedUnbuffered(self._buffer, onDone=onDone) - self._buffer = "" + self._buffer = b"" def _feedUnbuffered(self, data, onDone=None): if self._audioDucker and not self._audioDucker.enable(): @@ -277,7 +277,7 @@ def idle(self): return self._idleUnbuffered() if self._buffer: self._feedUnbuffered(self._buffer) - self._buffer = "" + self._buffer = b"" return self._idleUnbuffered() def _idleUnbuffered(self): @@ -295,7 +295,7 @@ def stop(self): """ if self._audioDucker: self._audioDucker.disable() if self._minBufferSize: - self._buffer = "" + self._buffer = b"" with self._waveout_lock: if not self._waveout: return diff --git a/source/scriptHandler.py b/source/scriptHandler.py index 39e78ee90b5..aeb5038078c 100644 --- a/source/scriptHandler.py +++ b/source/scriptHandler.py @@ -32,9 +32,6 @@ def _makeKbEmulateScript(scriptName): keyName = scriptName[3:] emuGesture = keyboardHandler.KeyboardInputGesture.fromName(keyName) func = lambda gesture: inputCore.manager.emulateGesture(emuGesture) - if isinstance(scriptName, unicode): - # __name__ must be str; i.e. can't be unicode. - scriptName = scriptName.encode("mbcs") func.__name__ = "script_%s" % scriptName func.__doc__ = _("Emulates pressing %s on the system keyboard") % emuGesture.displayName return func diff --git a/source/speech/__init__.py b/source/speech/__init__.py index fea6253052c..64a9752a6d9 100755 --- a/source/speech/__init__.py +++ b/source/speech/__init__.py @@ -443,11 +443,11 @@ def splitTextIndentation(text): def getIndentationSpeech(indentation, formatConfig): """Retrieves the phrase to be spoken for a given string of indentation. @param indentation: The string of indentation. - @type indentation: unicode + @type indentation: str @param formatConfig: The configuration to use. @type formatConfig: dict @return: The phrase to be spoken. - @rtype: unicode + @rtype: str """ speechIndentConfig = formatConfig["reportLineIndentation"] toneIndentConfig = formatConfig["reportLineIndentationWithTones"] and speechMode == speechMode_talk @@ -1412,9 +1412,9 @@ def getFormatFieldSpeech(attrs,attrsCache=None,formatConfig=None,reason=None,uni backgroundColor2=attrs.get("background-color2") oldBackgroundColor2=attrsCache.get("background-color2") if attrsCache is not None else None bgColorChanged=backgroundColor!=oldBackgroundColor or backgroundColor2!=oldBackgroundColor2 - bgColorText=backgroundColor.name if isinstance(backgroundColor,colors.RGB) else unicode(backgroundColor) + bgColorText=backgroundColor.name if isinstance(backgroundColor,colors.RGB) else backgroundColor if backgroundColor2: - bg2Name=backgroundColor2.name if isinstance(backgroundColor2,colors.RGB) else unicode(backgroundColor2) + bg2Name=backgroundColor2.name if isinstance(backgroundColor2,colors.RGB) else backgroundColor2 # Translators: Reported when there are two background colors. # This occurs when, for example, a gradient pattern is applied to a spreadsheet cell. # {color1} will be replaced with the first background color. @@ -1425,12 +1425,12 @@ def getFormatFieldSpeech(attrs,attrsCache=None,formatConfig=None,reason=None,uni # {color} will be replaced with the text color. # {backgroundColor} will be replaced with the background color. textList.append(_("{color} on {backgroundColor}").format( - color=color.name if isinstance(color,colors.RGB) else unicode(color), + color=color.name if isinstance(color,colors.RGB) else color, backgroundColor=bgColorText)) elif color and color!=oldColor: # Translators: Reported when the text color changes (but not the background color). # {color} will be replaced with the text color. - textList.append(_("{color}").format(color=color.name if isinstance(color,colors.RGB) else unicode(color))) + textList.append(_("{color}").format(color=color.name if isinstance(color,colors.RGB) else color)) elif backgroundColor and bgColorChanged: # Translators: Reported when the background color changes (but not the text color). # {backgroundColor} will be replaced with the background color. diff --git a/source/speech/commands.py b/source/speech/commands.py index 0578db6bc3c..2aa1e10687a 100644 --- a/source/speech/commands.py +++ b/source/speech/commands.py @@ -214,11 +214,11 @@ class PhonemeCommand(SynthCommand): def __init__(self, ipa, text=None): """ @param ipa: Unicode IPA characters. - @type ipa: unicode + @type ipa: str @param text: Text to speak if the synthesizer does not support some or all of the specified IPA characters, C{None} to ignore this command instead. - @type text: unicode + @type text: str """ self.ipa = ipa self.text = text diff --git a/source/speechXml.py b/source/speechXml.py index 43b7040a8ee..34ad31c58f2 100644 --- a/source/speechXml.py +++ b/source/speechXml.py @@ -73,7 +73,7 @@ def toXmlLang(nvdaLang): StandAloneTagCommand = namedtuple("StandAloneTagCommand", ("tag", "attrs", "content")) def _escapeXml(text): - text = unicode(text).translate(XML_ESCAPES) + text = str(text).translate(XML_ESCAPES) text = RE_INVALID_XML_CHARS.sub(REPLACEMENT_CHAR, text) return text diff --git a/source/synthDrivers/_espeak.py b/source/synthDrivers/_espeak.py index b63977a1898..71e012b4c60 100755 --- a/source/synthDrivers/_espeak.py +++ b/source/synthDrivers/_espeak.py @@ -122,6 +122,12 @@ def __eq__(self, other): CALLBACK_CONTINUE_SYNTHESIS=0 CALLBACK_ABORT_SYNTHESIS=1 +def encodeEspeakString(text): + return text.encode('utf8') + +def decodeEspeakString(data): + return data.decode('utf8') + t_espeak_callback=CFUNCTYPE(c_int,POINTER(c_short),c_int,POINTER(espeak_EVENT)) @t_espeak_callback @@ -133,12 +139,12 @@ def callback(wav,numsamples,event): indexes = [] for e in event: if e.type==espeakEVENT_MARK: - indexNum = int(e.id.name) + indexNum = int(decodeEspeakString(e.id.name)) # e.audio_position is ms since the start of this utterance. # Convert to bytes since the start of the utterance. BYTES_PER_SAMPLE = 2 MS_PER_SEC = 1000 - bytesPerMS = player.samplesPerSec * BYTES_PER_SAMPLE / MS_PER_SEC + bytesPerMS = player.samplesPerSec * BYTES_PER_SAMPLE // MS_PER_SEC indexByte = e.audio_position * bytesPerMS # Subtract bytes in the utterance that have already been handled # to give us the byte offset into the samples for this callback. @@ -151,7 +157,7 @@ def callback(wav,numsamples,event): onIndexReached(None) isSpeaking = False return CALLBACK_CONTINUE_SYNTHESIS - wav = string_at(wav, numsamples * sizeof(c_short)) if numsamples>0 else "" + wav = string_at(wav, numsamples * sizeof(c_short)) if numsamples>0 else b"" prevByte = 0 for indexNum, indexByte in indexes: player.feed(wav[prevByte:indexByte], @@ -261,10 +267,11 @@ def setVoice(voice): setVoiceByName(voice.identifier) def setVoiceByName(name): - _execWhenDone(espeakDLL.espeak_SetVoiceByName,name) + _execWhenDone(espeakDLL.espeak_SetVoiceByName,encodeEspeakString(name)) def _setVoiceAndVariant(voice=None, variant=None): - res = getCurrentVoice().identifier.split("+") + v=getCurrentVoice() + res = decodeEspeakString(v.identifier).split("+") if not voice: voice = res[0] if not variant: @@ -273,12 +280,12 @@ def _setVoiceAndVariant(voice=None, variant=None): else: variant = "none" if variant == "none": - espeakDLL.espeak_SetVoiceByName(voice) + espeakDLL.espeak_SetVoiceByName(encodeEspeakString(voice)) else: try: - espeakDLL.espeak_SetVoiceByName("%s+%s" % (voice, variant)) + espeakDLL.espeak_SetVoiceByName(encodeEspeakString("%s+%s" % (voice, variant))) except: - espeakDLL.espeak_SetVoiceByName(voice) + espeakDLL.espeak_SetVoiceByName(encodeEspeakString(voice)) def setVoiceAndVariant(voice=None, variant=None): _execWhenDone(_setVoiceAndVariant, voice=voice, variant=variant) @@ -286,11 +293,11 @@ def setVoiceAndVariant(voice=None, variant=None): def _setVoiceByLanguage(lang): v=espeak_VOICE() lang=lang.replace('_','-') - v.languages=lang + v.languages=encodeEspeakString(lang) try: espeakDLL.espeak_SetVoiceByProperties(byref(v)) except: - v.languages="en" + v.languages=encodeEspeakString("en") espeakDLL.espeak_SetVoiceByProperties(byref(v)) def setVoiceByLanguage(lang): @@ -318,8 +325,9 @@ def initialize(indexCallback=None): espeakDLL.espeak_ListVoices.restype=POINTER(POINTER(espeak_VOICE)) espeakDLL.espeak_GetCurrentVoice.restype=POINTER(espeak_VOICE) espeakDLL.espeak_SetVoiceByName.argtypes=(c_char_p,) + eSpeakPath=os.path.abspath("synthDrivers") sampleRate=espeakDLL.espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS,300, - os.path.abspath("synthDrivers"),0) + os.fsencode(eSpeakPath),0) if sampleRate<0: raise OSError("espeak_Initialize %d"%sampleRate) player = nvwave.WavePlayer(channels=1, samplesPerSec=sampleRate, bitsPerSample=16, @@ -354,7 +362,7 @@ def getVariantDict(): variantDict={"none": pgettext("espeakVarient", "none")} for fileName in os.listdir(dir): if os.path.isfile("%s\\%s"%(dir,fileName)): - file=codecs.open("%s\\%s"%(dir,fileName)) + file=open("%s\\%s"%(dir,fileName)) for line in file: if line.startswith('name '): temp=line.split(" ") diff --git a/source/synthDrivers/espeak.py b/source/synthDrivers/espeak.py index 4119878f0e3..2f2ad27b54c 100644 --- a/source/synthDrivers/espeak.py +++ b/source/synthDrivers/espeak.py @@ -72,7 +72,6 @@ def _get_language(self): } def _processText(self, text): - text = unicode(text) # We need to make several replacements. return text.translate({ 0x1: None, # used for embedded commands @@ -123,7 +122,7 @@ def speak(self,speechSequence): textList.append(' %s="%d%%"'%(attr,val)) textList.append(">") elif isinstance(item,speech.PhonemeCommand): - # We can't use unicode.translate because we want to reject unknown characters. + # We can't use str.translate because we want to reject unknown characters. try: phonemes="".join([self.IPA_TO_ESPEAK[char] for char in item.ipa]) # There needs to be a space after the phoneme command. @@ -199,11 +198,11 @@ def _set_volume(self,volume): def _getAvailableVoices(self): voices=OrderedDict() for v in _espeak.getVoiceList(): - l=v.languages[1:] + l=_espeak.decodeEspeakString(v.languages[1:]) # #7167: Some languages names contain unicode characters EG: Norwegian Bokmål - name=v.name.decode("UTF-8") + name=_espeak.decodeEspeakString(v.name) # #5783: For backwards compatibility, voice identifies should always be lowercase - identifier=os.path.basename(v.identifier).lower() + identifier=os.path.basename(_espeak.decodeEspeakString(v.identifier)).lower() voices[identifier]=VoiceInfo(identifier,name,l) return voices @@ -214,7 +213,7 @@ def _get_voice(self): if not curVoice: return "" # #5783: For backwards compatibility, voice identifies should always be lowercase - return curVoice.identifier.split('+')[0].lower() + return _espeak.decodeEspeakString(curVoice.identifier).split('+')[0].lower() def _set_voice(self, identifier): if not identifier: diff --git a/source/textInfos/__init__.py b/source/textInfos/__init__.py index 3a006833fa0..8c1e7b87389 100755 --- a/source/textInfos/__init__.py +++ b/source/textInfos/__init__.py @@ -257,7 +257,7 @@ def _get_text(self): """The text with in this range. Subclasses must implement this. @return: The text. - @rtype: unicode + @rtype: str @note: The text is not guaranteed to be the exact length of the range in offsets. """ raise NotImplementedError @@ -268,7 +268,7 @@ def getTextWithFields(self,formatConfig=None): @param formatConfig: Document formatting configuration, useful if you wish to force a particular configuration for a particular task. @type formatConfig: dict @return: A sequence of text strings interspersed with associated field commands. - @rtype: list of unicode and L{FieldCommand} + @rtype: list of str and L{FieldCommand} """ return [self.text] diff --git a/source/textInfos/offsets.py b/source/textInfos/offsets.py index 15c9bea218f..8fbcbcb517f 100755 --- a/source/textInfos/offsets.py +++ b/source/textInfos/offsets.py @@ -71,7 +71,7 @@ def findStartOfLine(text,offset,lineLength=None): def findEndOfLine(text,offset,lineLength=None): """Searches forwards through the given text from the given offset, until it finds the offset that is the start of the next line. With out a set line length, it searches for new line / cariage return characters, with a set line length it simply moves forward to sit on a multiple of the line length. @param text: the text to search -@type text: unicode +@type text: str @param offset: the offset of the text to start at @type offset: int @param lineLength: The number of characters that makes up a line, None if new line characters should be looked at instead @@ -98,7 +98,7 @@ def findEndOfLine(text,offset,lineLength=None): def findStartOfWord(text,offset,lineLength=None): """Searches backwards through the given text from the given offset, until it finds the offset that is the start of the word. It checks to see if a character is alphanumeric, or is another symbol , or is white space. @param text: the text to search -@type text: unicode +@type text: str @param offset: the offset of the text to start at @type offset: int @param lineLength: The number of characters that makes up a line, None if new line characters should be looked at instead @@ -120,7 +120,7 @@ def findStartOfWord(text,offset,lineLength=None): def findEndOfWord(text,offset,lineLength=None): """Searches forwards through the given text from the given offset, until it finds the offset that is the start of the next word. It checks to see if a character is alphanumeric, or is another symbol , or is white space. @param text: the text to search -@type text: unicode +@type text: str @param offset: the offset of the text to start at @type offset: int @param lineLength: The number of characters that makes up a line, None if new line characters should be looked at instead @@ -270,7 +270,7 @@ def _getStoryLength(self): def _getStoryText(self): """Retrieve the entire text of the object. @return: The entire text of the object. - @rtype: unicode + @rtype: str """ raise NotImplementedError @@ -281,7 +281,7 @@ def _getTextRange(self,start,end): @param end: The end offset (exclusive). @type end: int @return: The text contained in the requested range. - @rtype: unicode + @rtype: str """ text=self._getStoryText() return text[start:end] if text else u"" diff --git a/source/ui.py b/source/ui.py index eab3dc45070..4a36f436ed7 100644 --- a/source/ui.py +++ b/source/ui.py @@ -36,9 +36,9 @@ def browseableMessage(message,title=None,isHtml=False): """Present a message to the user that can be read in browse mode. The message will be presented in an HTML document. @param message: The message in either html or text. - @type message: unicode + @type message: str @param title: The title for the message. - @type title: unicode + @type title: str @param isHtml: Whether the message is html @type isHtml: boolean """ @@ -46,7 +46,7 @@ def browseableMessage(message,title=None,isHtml=False): if not os.path.isfile(htmlFileName ): raise LookupError(htmlFileName ) moniker = POINTER(IUnknown)() - windll.urlmon.CreateURLMonikerEx(0, unicode( htmlFileName ) , byref(moniker), URL_MK_UNIFORM) + windll.urlmon.CreateURLMonikerEx(0, htmlFileName, byref(moniker), URL_MK_UNIFORM) if not title: # Translators: The title for the dialog used to present general NVDA messages in browse mode. title = _("NVDA Message") @@ -54,7 +54,7 @@ def browseableMessage(message,title=None,isHtml=False): dialogString = u"{isHtml};{title};{message}".format( isHtml = isHtmlArgument , title=title , message=message ) dialogArguements = automation.VARIANT( dialogString ) gui.mainFrame.prePopup() - windll.mshtml.ShowHTMLDialogEx( gui.mainFrame.Handle , moniker , HTMLDLG_MODELESS , addressof( dialogArguements ) , unicode(DIALOG_OPTIONS ), None) + windll.mshtml.ShowHTMLDialogEx( gui.mainFrame.Handle , moniker , HTMLDLG_MODELESS , addressof( dialogArguements ) , DIALOG_OPTIONS, None) gui.mainFrame.postPopup() def message(text): diff --git a/source/virtualBuffers/__init__.py b/source/virtualBuffers/__init__.py index 2e39ccb6264..1fe4af51b14 100644 --- a/source/virtualBuffers/__init__.py +++ b/source/virtualBuffers/__init__.py @@ -44,7 +44,7 @@ VBufRemote_nodeHandle_t=ctypes.c_ulonglong -class VBufStorage_findMatch_word(unicode): +class VBufStorage_findMatch_word(str): pass VBufStorage_findMatch_notEmpty = object() @@ -57,7 +57,7 @@ class VBufStorage_findMatch_word(unicode): # Symbols that must be escaped for a regular expression. FINDBYATTRIBS_ESCAPE_TABLE.update({(ord(s), u"\\" + s) for s in u"^$.*+?()[]{}|"}) def _prepareForFindByAttributes(attribs): - escape = lambda text: unicode(text).translate(FINDBYATTRIBS_ESCAPE_TABLE) + escape = lambda text: text.translate(FINDBYATTRIBS_ESCAPE_TABLE) reqAttrs = [] regexp = [] if isinstance(attribs, dict): @@ -67,7 +67,7 @@ def _prepareForFindByAttributes(attribs): # so first build the list of requested attributes. for option in attribs: for name in option: - reqAttrs.append(unicode(name)) + reqAttrs.append(name) # Now build the regular expression. for option in attribs: optRegexp = [] @@ -436,7 +436,7 @@ def _loadBuffer(self): try: if log.isEnabledFor(log.DEBUG): startTime = time.time() - self.VBufHandle=NVDAHelper.localLib.VBuf_createBuffer(self.rootNVDAObject.appModule.helperLocalBindingHandle,self.rootDocHandle,self.rootID,unicode(self.backendName)) + self.VBufHandle=NVDAHelper.localLib.VBuf_createBuffer(self.rootNVDAObject.appModule.helperLocalBindingHandle,self.rootDocHandle,self.rootID,self.backendName) if not self.VBufHandle: raise RuntimeError("Could not remotely create virtualBuffer") except: @@ -477,7 +477,7 @@ def unloadBuffer(self): def isNVDAObjectPartOfLayoutTable(self,obj): docHandle,ID=self.getIdentifierFromNVDAObject(obj) - ID=unicode(ID) + ID=str(ID) info=self.makeTextInfo(obj) info.collapse() info.expand(textInfos.UNIT_CHARACTER) @@ -682,7 +682,7 @@ def _handleUpdate(self): def getControlFieldForNVDAObject(self, obj): docHandle, objId = self.getIdentifierFromNVDAObject(obj) - objId = unicode(objId) + objId = str(objId) info = self.makeTextInfo(obj) info.collapse() info.expand(textInfos.UNIT_CHARACTER) diff --git a/source/winKernel.py b/source/winKernel.py index b1e4b95cb4a..66ddb257315 100644 --- a/source/winKernel.py +++ b/source/winKernel.py @@ -83,7 +83,7 @@ def createWaitableTimer(securityAttributes=None, manualReset=False, name=None): If C{True}, the timer is a manual-reset notification timer. @type manualReset: bool @param name: Defaults to C{None}, the timer object is created without a name. - @type name: unicode + @type name: str """ res = kernel32.CreateWaitableTimerW(securityAttributes, manualReset, name) if res==0: diff --git a/source/winUser.py b/source/winUser.py index 776e9b89e75..9834d47999f 100644 --- a/source/winUser.py +++ b/source/winUser.py @@ -656,7 +656,7 @@ def setClipboardData(format,data): # For now only unicode is a supported format if format!=CF_UNICODETEXT: raise ValueError("Unsupported format") - text=unicode(data) + text = data # Allocate global memory h=winKernel.HGLOBAL.alloc(winKernel.GMEM_MOVEABLE,(len(text)+1)*2) # Acquire a lock to the global memory receiving a local memory address diff --git a/source/windowUtils.py b/source/windowUtils.py index 691c72c62c8..406460c8586 100644 --- a/source/windowUtils.py +++ b/source/windowUtils.py @@ -138,7 +138,7 @@ class CustomWindow(object): """ #: The class name of this window. - #: @type: unicode + #: @type: str className = None _hwndsToInstances = weakref.WeakValueDictionary() @@ -147,9 +147,9 @@ def __init__(self, windowName=None): """Constructor. @raise WindowsError: If an error occurs. """ - if not isinstance(self.className, unicode): + if not isinstance(self.className, str): raise ValueError("className attribute must be a unicode string") - if windowName and not isinstance(windowName, unicode): + if windowName and not isinstance(windowName, str): raise ValueError("windowName must be a unicode string") self._wClass = WNDCLASSEXW( cbSize=ctypes.sizeof(WNDCLASSEXW), diff --git a/tests/unit/textProvider.py b/tests/unit/textProvider.py index 77e691c48cf..d0871722398 100644 --- a/tests/unit/textProvider.py +++ b/tests/unit/textProvider.py @@ -48,13 +48,13 @@ class BasicTextProvider(NVDAObject): def __init__(self, text=None, selection=(0, 0)): """ @param text: The text to provide via TextInfos. - @type text: basestring + @type text: str @param selection: The start and end offsets of the initial selection; same start and end is caret with no selection. @type selection: tuple of (int, int) """ super(BasicTextProvider, self).__init__() - self.basicText = unicode(text) + self.basicText = text self.selectionOffsets = selection def makeTextInfo(self, position): From a564157976595e2d6837bbef5fe07c959b1fbe29 Mon Sep 17 00:00:00 2001 From: Michael Curran Date: Fri, 14 Jun 2019 09:55:07 +1000 Subject: [PATCH 4/5] Revert changes to braille related files as these will be handled in a separate pr. --- source/bdDetect.py | 6 +++--- source/braille.py | 12 ++++++------ source/brailleDisplayDrivers/eurobraille.py | 2 +- source/brailleInput.py | 14 +++++++------- source/brailleTables.py | 4 ++-- source/hwIo.py | 4 ++-- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/source/bdDetect.py b/source/bdDetect.py index 3f5229a7439..1ac7db2a66b 100644 --- a/source/bdDetect.py +++ b/source/bdDetect.py @@ -40,9 +40,9 @@ class DeviceMatch( ): """Represents a detected device. @ivar id: The identifier of the device. - @type id: str + @type id: unicode @ivar port: The port that can be used by a driver to communicate with a device. - @type port: str + @type port: unicode @ivar deviceInfo: all known information about a device. @type deviceInfo: dict """ @@ -83,7 +83,7 @@ def addUsbDevices(driver, type, ids): @type ids: set of str @raise ValueError: When one of the provided IDs is malformed. """ - malformedIds = [id for id in ids if not isinstance(id, str) or not USB_ID_REGEX.match(id)] + malformedIds = [id for id in ids if not isinstance(id, basestring) or not USB_ID_REGEX.match(id)] if malformedIds: raise ValueError("Invalid IDs provided for driver %s, type %s: %s" % (driver, type, ", ".join(wrongIds))) diff --git a/source/braille.py b/source/braille.py index 2b36760e950..e5e154c0c53 100644 --- a/source/braille.py +++ b/source/braille.py @@ -330,7 +330,7 @@ def getDisplayList(excludeNegativeChecks=True): @param excludeNegativeChecks: excludes all drivers for which the check method returns C{False}. @type excludeNegativeChecks: bool @return: list of tuples with driver names and descriptions. - @rtype: [(str,str)] + @rtype: [(str,unicode)] """ displayList = [] # The display that should be placed at the end of the list. @@ -810,7 +810,7 @@ def _addTextWithFields(self, info, formatConfig, isSelection=False): # When true, we are inside a clickable field, and should therefore not report any more new clickable fields inClickable=False for command in info.getTextWithFields(formatConfig=formatConfig): - if isinstance(command, str): + if isinstance(command, basestring): # Text should break a run of clickables inClickable=False self._isFormatFieldAtStart = False @@ -2296,7 +2296,7 @@ def getManualPorts(cls): This is for ports which cannot be detected automatically such as serial ports. @return: The name and description for each port. - @rtype: iterable of str, str + @rtype: iterable of basestring, basestring """ raise NotImplementedError @@ -2305,13 +2305,13 @@ def _getTryPorts(cls, port): """Returns the ports for this driver to which a connection attempt should be made. This generator function is usually used in L{__init__} to connect to the desired display. @param port: the port to connect to. - @type port: one of str or L{bdDetect.DeviceMatch} + @type port: one of basestring or L{bdDetect.DeviceMatch} @return: The name and description for each port. - @rtype: iterable of str, str + @rtype: iterable of basestring, basestring """ if isinstance(port, bdDetect.DeviceMatch): yield port - elif isinstance(port, str): + elif isinstance(port, basestring): isUsb = port in (AUTOMATIC_PORT[0], USB_PORT[0]) isBluetooth = port in (AUTOMATIC_PORT[0], BLUETOOTH_PORT[0]) if not isUsb and not isBluetooth: diff --git a/source/brailleDisplayDrivers/eurobraille.py b/source/brailleDisplayDrivers/eurobraille.py index f4bf9a7a83f..393b6705de5 100644 --- a/source/brailleDisplayDrivers/eurobraille.py +++ b/source/brailleDisplayDrivers/eurobraille.py @@ -128,7 +128,7 @@ } def bytesToInt(bytes): - """Converts a bytes object to its integral equivalent.""" + """Converts a basestring to its integral equivalent.""" return int(bytes.encode('hex'), 16) class BrailleDisplayDriver(braille.BrailleDisplayDriver, ScriptableObject): diff --git a/source/brailleInput.py b/source/brailleInput.py index af5c559d101..c90afb1b6e2 100644 --- a/source/brailleInput.py +++ b/source/brailleInput.py @@ -36,7 +36,7 @@ #: @type: int UNICODE_BRAILLE_START = 0x2800 #: The Unicode braille character to use when masking cells in protected fields. -#: @type: str +#: @type: unicode UNICODE_BRAILLE_PROTECTED = u"⣿" # All dots down #: The singleton BrailleInputHandler instance. @@ -82,7 +82,7 @@ def __init__(self): #: or were translated but did not produce any text. #: This is used to show these cells to the user while they're entering braille. #: This is a string of Unicode braille. - #: @type: str + #: @type: unicode self.untranslatedBraille = "" #: The position in L{brailleBuffer} where untranslated braille begins. self.untranslatedStart = 0 @@ -126,7 +126,7 @@ def _translate(self, endWord): self.bufferText = u"" oldTextLen = len(self.bufferText) pos = self.untranslatedStart + self.untranslatedCursorPos - data = u"".join([chr(cell | LOUIS_DOTS_IO_START) for cell in self.bufferBraille[:pos]]) + data = u"".join([unichr(cell | LOUIS_DOTS_IO_START) for cell in self.bufferBraille[:pos]]) mode = louis.dotsIO | louis.noUndefinedDots if (not self.currentFocusIsTextObj or self.currentModifiers) and self._table.contracted: mode |= louis.partialTrans @@ -175,10 +175,10 @@ def _translate(self, endWord): def _translateForReportContractedCell(self, pos): """Translate text for current input as required by L{_reportContractedCell}. @return: The previous translated text. - @rtype: str + @rtype: unicode """ cells = self.bufferBraille[:pos + 1] - data = u"".join([chr(cell | LOUIS_DOTS_IO_START) for cell in cells]) + data = u"".join([unichr(cell | LOUIS_DOTS_IO_START) for cell in cells]) oldText = self.bufferText text = louis.backTranslate( [os.path.join(brailleTables.TABLES_DIR, self._table.fileName), @@ -293,7 +293,7 @@ def _updateUntranslated(self): if api.isTypingProtected(): self.untranslatedBraille = UNICODE_BRAILLE_PROTECTED * (len(self.bufferBraille) - self.untranslatedStart) else: - self.untranslatedBraille = "".join([chr(UNICODE_BRAILLE_START + dots) for dots in self.bufferBraille[self.untranslatedStart:]]) + self.untranslatedBraille = "".join([unichr(UNICODE_BRAILLE_START + dots) for dots in self.bufferBraille[self.untranslatedStart:]]) def updateDisplay(self): """Update the braille display to reflect untranslated input. @@ -385,7 +385,7 @@ def emulateKey(self, key, withModifiers=True): def sendChars(self, chars): """Sends the provided unicode characters to the system. @param chars: The characters to send to the system. - @type chars: str + @type chars: unicode """ inputs = [] for ch in chars: diff --git a/source/brailleTables.py b/source/brailleTables.py index a43cc8ea00f..51fbc79ecb5 100644 --- a/source/brailleTables.py +++ b/source/brailleTables.py @@ -28,9 +28,9 @@ def addTable(fileName, displayName, contracted=False, output=True, input=True): """Register a braille translation table. At least one of C{input} or C{output} must be C{True}. @param fileName: The file name of the table. - @type fileName: str + @type fileName: basestring @param displayname: The name of the table as displayed to the user. This should be translatable. - @type displayName: str + @type displayName: unicode @param contracted: C{True} if the table is contracted, C{False} if uncontracted. @type cContracted: bool @param output: C{True} if this table can be used for output, C{False} if not. diff --git a/source/hwIo.py b/source/hwIo.py index 4ffc739b7d9..4403518ec8b 100644 --- a/source/hwIo.py +++ b/source/hwIo.py @@ -248,7 +248,7 @@ def __init__(self, path, onReceive, exclusive=True): """Constructor. @param path: The device path. This can be retrieved using L{hwPortUtils.listHidDevices}. - @type path: str + @type path: unicode @param onReceive: A callable taking a received input report as its only argument. @type onReceive: callable(str) @param exclusive: Whether to block other application's access to this device. @@ -349,7 +349,7 @@ class Bulk(IoBase): def __init__(self, path, epIn, epOut, onReceive, onReceiveSize=1, writeSize=None): """Constructor. @param path: The device path. - @type path: str + @type path: unicode @param epIn: The endpoint to read data from. @type epIn: int @param epOut: The endpoint to write data to. From dac436488488abbbc1dfb100be07fb0ef0f82e5f Mon Sep 17 00:00:00 2001 From: Michael Curran Date: Fri, 14 Jun 2019 10:27:01 +1000 Subject: [PATCH 5/5] Address review comments. --- source/NVDAObjects/__init__.py | 2 +- source/browseMode.py | 7 ++++++- source/globalCommands.py | 10 +++++++--- source/louisHelper.py | 2 +- source/speechXml.py | 6 ++++-- source/synthDrivers/_espeak.py | 2 +- source/ui.py | 9 ++++++++- source/virtualBuffers/__init__.py | 6 +++++- 8 files changed, 33 insertions(+), 11 deletions(-) diff --git a/source/NVDAObjects/__init__.py b/source/NVDAObjects/__init__.py index f68b8ca0fec..4518d60b30a 100644 --- a/source/NVDAObjects/__init__.py +++ b/source/NVDAObjects/__init__.py @@ -1120,7 +1120,7 @@ def _formatLongDevInfoString(string, truncateLen=250): If the string is too long to be useful, it will be truncated. This string should be included as returned. There is no need to call repr. @param string: The string to format. - @type string: nstr + @type string: str @param truncateLen: The length at which to truncate the string. @type truncateLen: int @return: The formatted string. diff --git a/source/browseMode.py b/source/browseMode.py index 1f5d54f2002..255ce94d576 100644 --- a/source/browseMode.py +++ b/source/browseMode.py @@ -1648,7 +1648,12 @@ def _get_shouldRememberCaretPositionAcrossLoads(self): docConstId = self.documentConstantIdentifier # Return True if the URL indicates that this is probably a web browser document. # We do this check because we don't want to remember caret positions for email messages, etc. - return isinstance(docConstId, str) and docConstId.split("://", 1)[0] in ("http", "https", "ftp", "ftps", "file") + if isinstance(docConstId, str): + protocols=("http", "https", "ftp", "ftps", "file") + protocol=docConstId.split("://", 1)[0] + return protocol in protocols + return False + def _getInitialCaretPos(self): """Retrieve the initial position of the caret after the buffer has been loaded. diff --git a/source/globalCommands.py b/source/globalCommands.py index b07c0b08f92..c6777c6bb97 100755 --- a/source/globalCommands.py +++ b/source/globalCommands.py @@ -779,8 +779,9 @@ def script_navigatorObject_current(self,gesture): if scriptHandler.getLastScriptRepeatCount()>=1: if curObject.TextInfo!=NVDAObjectTextInfo: textList=[] - if curObject.name and isinstance(curObject.name, str) and not curObject.name.isspace(): - textList.append(curObject.name) + name = curObject.name + if isinstance(name, str) and not name.isspace(): + textList.append(name) try: info=curObject.makeTextInfo(textInfos.POSITION_SELECTION) if not info.isCollapsed: @@ -793,7 +794,10 @@ def script_navigatorObject_current(self,gesture): # No caret or selection on this object. pass else: - textList=[prop for prop in (curObject.name, curObject.value) if prop and isinstance(prop, str) and not prop.isspace()] + textList=[] + for prop in (curObject.name, curObject.value): + if isinstance(prop,str) and not prop.isspace(): + textList.append(prop) text=" ".join(textList) if len(text)>0 and not text.isspace(): if scriptHandler.getLastScriptRepeatCount()==1: diff --git a/source/louisHelper.py b/source/louisHelper.py index 6843c017336..c89064a03cc 100644 --- a/source/louisHelper.py +++ b/source/louisHelper.py @@ -52,7 +52,7 @@ def terminate(): def translate(tableList, inbuf, typeform=None, cursorPos=None, mode=0): """ Convenience wrapper for louis.translate that: - * returns a list of integers instead of an string with cells, and + * returns a list of integers instead of a string with cells, and * distinguishes between cursor position 0 (cursor at first character) and None (no cursor at all) """ text = inbuf.replace('\0','') diff --git a/source/speechXml.py b/source/speechXml.py index 34ad31c58f2..0abe0be00ac 100644 --- a/source/speechXml.py +++ b/source/speechXml.py @@ -73,7 +73,7 @@ def toXmlLang(nvdaLang): StandAloneTagCommand = namedtuple("StandAloneTagCommand", ("tag", "attrs", "content")) def _escapeXml(text): - text = str(text).translate(XML_ESCAPES) + text = text.translate(XML_ESCAPES) text = RE_INVALID_XML_CHARS.sub(REPLACEMENT_CHAR, text) return text @@ -112,7 +112,9 @@ def _openTag(self, tag, attrs, empty=False): self._out.append("<%s" % tag) for attr, val in attrs.items(): self._out.append(' %s="' % attr) - self._out.append(_escapeXml(val)) + # Attribute values could be ints, floats etc, not just strings. + # Therefore coerce the value to a string, as well as escaping xml characters. + self._out.append(_escapeXml(str(val))) self._out.append('"') self._out.append("/>" if empty else ">") diff --git a/source/synthDrivers/_espeak.py b/source/synthDrivers/_espeak.py index 71e012b4c60..3cefb3aaf4b 100755 --- a/source/synthDrivers/_espeak.py +++ b/source/synthDrivers/_espeak.py @@ -362,7 +362,7 @@ def getVariantDict(): variantDict={"none": pgettext("espeakVarient", "none")} for fileName in os.listdir(dir): if os.path.isfile("%s\\%s"%(dir,fileName)): - file=open("%s\\%s"%(dir,fileName)) + file=codecs.open("%s\\%s"%(dir,fileName)) for line in file: if line.startswith('name '): temp=line.split(" ") diff --git a/source/ui.py b/source/ui.py index 4a36f436ed7..ca19d3c9bf6 100644 --- a/source/ui.py +++ b/source/ui.py @@ -54,7 +54,14 @@ def browseableMessage(message,title=None,isHtml=False): dialogString = u"{isHtml};{title};{message}".format( isHtml = isHtmlArgument , title=title , message=message ) dialogArguements = automation.VARIANT( dialogString ) gui.mainFrame.prePopup() - windll.mshtml.ShowHTMLDialogEx( gui.mainFrame.Handle , moniker , HTMLDLG_MODELESS , addressof( dialogArguements ) , DIALOG_OPTIONS, None) + windll.mshtml.ShowHTMLDialogEx( + gui.mainFrame.Handle , + moniker , + HTMLDLG_MODELESS , + addressof( dialogArguements ) , + DIALOG_OPTIONS, + None + ) gui.mainFrame.postPopup() def message(text): diff --git a/source/virtualBuffers/__init__.py b/source/virtualBuffers/__init__.py index 1fe4af51b14..b6b13b5b77f 100644 --- a/source/virtualBuffers/__init__.py +++ b/source/virtualBuffers/__init__.py @@ -436,7 +436,11 @@ def _loadBuffer(self): try: if log.isEnabledFor(log.DEBUG): startTime = time.time() - self.VBufHandle=NVDAHelper.localLib.VBuf_createBuffer(self.rootNVDAObject.appModule.helperLocalBindingHandle,self.rootDocHandle,self.rootID,self.backendName) + self.VBufHandle=NVDAHelper.localLib.VBuf_createBuffer( + self.rootNVDAObject.appModule.helperLocalBindingHandle, + self.rootDocHandle,self.rootID, + self.backendName + ) if not self.VBufHandle: raise RuntimeError("Could not remotely create virtualBuffer") except: