From 07adc8ce4c514e09489c295a747576b7603bc8c6 Mon Sep 17 00:00:00 2001 From: Stefan Klug Date: Tue, 3 Nov 2015 20:55:21 +0100 Subject: [PATCH] python3 compatibility fixes --- appy/__init__.py | 2 +- appy/pod/__init__.py | 2 +- appy/pod/buffers.py | 9 +++------ appy/pod/elements.py | 2 +- appy/pod/pod_parser.py | 2 +- appy/pod/renderer.py | 10 +++++----- appy/pod/test/Tester.py | 14 ++++++-------- appy/pod/xhtml2odt.py | 4 ++-- appy/shared/css.py | 10 +++++----- appy/shared/csv_parser.py | 6 +++--- appy/shared/dav.py | 2 +- appy/shared/diff.py | 8 ++++---- appy/shared/ldap_connector.py | 4 ++-- appy/shared/test.py | 4 +--- appy/shared/utils.py | 4 ++-- appy/shared/xml_parser.py | 31 ++++++++++++++----------------- 16 files changed, 52 insertions(+), 62 deletions(-) diff --git a/appy/__init__.py b/appy/__init__.py index 010ddae..7e5a5d2 100644 --- a/appy/__init__.py +++ b/appy/__init__.py @@ -88,7 +88,7 @@ class Hack: '''Injects any method or attribute from p_patchClass into klass.''' patched = [] added = [] - for name, attr in patchClass.__dict__.iteritems(): + for name, attr in patchClass.__dict__.items(): if name.startswith('__'): continue # Ignore special methods # Unwrap functions from static methods if attr.__class__.__name__ == 'staticmethod': diff --git a/appy/pod/__init__.py b/appy/pod/__init__.py index 6759b0c..233c965 100644 --- a/appy/pod/__init__.py +++ b/appy/pod/__init__.py @@ -69,7 +69,7 @@ class PodError(Exception): '<%s:date>%s<%s:p>' % \ (officeNs, dcNs, dcNs, dcNs, time.strftime('%Y-%m-%dT%H:%M:%S'), dcNs, textNs)) - buffer.dumpContent(message) + buffer.dumpContent(str(message)) buffer.write('' % textNs) if dumpTb: # We don't dump the traceback if it is an expression error (it is diff --git a/appy/pod/buffers.py b/appy/pod/buffers.py index 96ceab7..857fcaf 100644 --- a/appy/pod/buffers.py +++ b/appy/pod/buffers.py @@ -222,7 +222,7 @@ class FileBuffer(Buffer): def __init__(self, env, result): Buffer.__init__(self, env, None) self.result = result - self.content = file(result, 'w') + self.content = open(result, 'w', encoding='utf-8') self.content.write(xmlPrologue) # getLength is used to manage insertions into sub-buffers. But in the case @@ -231,10 +231,7 @@ class FileBuffer(Buffer): def getLength(self): return 0 def write(self, something): - try: - self.content.write(something.encode('utf-8')) - except UnicodeDecodeError: - self.content.write(something) + self.content.write(something) def addExpression(self, expression, tiedHook=None): # At 2013-02-06, this method was not called within the whole test suite. @@ -674,7 +671,7 @@ class MemoryBuffer(Buffer): # Find the start position of the deepest element to remove deepestElem = self.action.elem.DEEPEST_TO_REMOVE pos = self.content.find('<%s' % deepestElem.elem) - for index in self.elements.keys(): + for index in list(self.elements.keys()): if index < pos: del self.elements[index] reTagContent = re.compile('<(?P

[\w-]+):(?P[\w-]+)(.*?)>.*', dynamicStyles) - f.close() - f = file(contentXml, 'w') + f.seek(0) + f.truncate(0) f.write(content) f.close() # Call the user-defined "finalize" function when present diff --git a/appy/pod/test/Tester.py b/appy/pod/test/Tester.py index 9e0748d..fbc7c4c 100644 --- a/appy/pod/test/Tester.py +++ b/appy/pod/test/Tester.py @@ -94,7 +94,7 @@ class Test(appy.shared.test.Test): raise TesterError(CONTEXT_NOT_FOUND % contextPy) contextPkg = 'appy.pod.test.contexts.%s' % contextName exec('import %s' % contextPkg) - exec('context = dir(%s)' % contextPkg) + context = eval('dir(%s)' % contextPkg) res = {} for elem in context: if not elem.startswith('__'): @@ -149,7 +149,7 @@ class Test(appy.shared.test.Test): zipFile = zipfile.ZipFile(odtFile) for zippedFile in zipFile.namelist(): if zippedFile in self.interestingOdtContent: - f = file(os.path.join(self.tempFolder, + f = open(os.path.join(self.tempFolder, '%s.%s' % (filePrefix, zippedFile)), 'wb') fileContent = zipFile.read(zippedFile) if zippedFile == 'content.xml': @@ -159,12 +159,10 @@ class Test(appy.shared.test.Test): # to the other. So we remove those paths. annotationsRemover = AnnotationsRemover( OdfEnvironment(), self) - annotationsRemover.parse(fileContent) - fileContent = annotationsRemover.getResult() - try: - f.write(fileContent.encode('utf-8')) - except UnicodeDecodeError: - f.write(fileContent) + annotationsRemover.parse(fileContent.decode('utf-8')) + fileContent = annotationsRemover.getResult().encode('utf-8') + + f.write(fileContent) f.close() zipFile.close() diff --git a/appy/pod/xhtml2odt.py b/appy/pod/xhtml2odt.py index 9519998..8aa6885 100644 --- a/appy/pod/xhtml2odt.py +++ b/appy/pod/xhtml2odt.py @@ -282,7 +282,7 @@ class HtmlTable: decl = '<%s:style %s:name="%s.%d" %s:family="table-column">' \ '<%s:table-column-properties %s:rel-column-width="%d*"' \ '/>' % (s, s, self.name, i, s, s, s, width, s) - renderer.dynamicStyles.append(decl.encode('utf-8')) + renderer.dynamicStyles.append(decl) # ------------------------------------------------------------------------------ class XhtmlEnvironment(XmlEnvironment): @@ -512,7 +512,7 @@ class XhtmlEnvironment(XmlEnvironment): sizes = table.columnContentSizes # Insert None values if the list is too small while (len(sizes)-1) < table.cellIndex: sizes.append(None) - highest = max(sizes[table.cellIndex], table.cellContentSize, 5) + highest = max(sizes[table.cellIndex] or 0, table.cellContentSize, 5) # Put a maximum highest = min(highest, 100) sizes[table.cellIndex] = highest diff --git a/appy/shared/css.py b/appy/shared/css.py index 57f92ab..3edf8e4 100644 --- a/appy/shared/css.py +++ b/appy/shared/css.py @@ -10,7 +10,7 @@ def parseStyleAttribute(value, asDict=False): else: res = [] for attr in value.split(';'): if not attr.strip(): continue - name, value = attr.split(':') + name, value = attr.split(':', 1) if asDict: res[name.strip()] = value.strip() else: res.append( (name.strip(), value.strip()) ) return res @@ -42,9 +42,9 @@ class CssStyles: '''Analyses styles as found in p_attrs and sets, for every found style, an attribute on self.''' # First, parse the "style" attr if present - if attrs.has_key('style'): + if 'style' in attrs.keys(): styles = parseStyleAttribute(attrs['style'], asDict=True) - for name, value in styles.iteritems(): + for name, value in styles.items(): if name in CssStyles.withUnit: value = CssValue(value) setattr(self, name.replace('-', ''), value) @@ -52,12 +52,12 @@ class CssStyles: # override corresponding attributes from the "styles" attributes if # found. for name in ('width', 'height'): - if not hasattr(self, name) and attrs.has_key(name): + if not hasattr(self, name) and name in attrs.keys(): setattr(self, name, CssValue(attrs[name])) def __repr__(self): res = '' # ------------------------------------------------------------------------------ diff --git a/appy/shared/csv_parser.py b/appy/shared/csv_parser.py index 1347cc7..1a10d5f 100644 --- a/appy/shared/csv_parser.py +++ b/appy/shared/csv_parser.py @@ -111,15 +111,15 @@ class CsvParser: Python type specified in p_basicType (int, float, ...).''' if (basicType != str) and (basicType != str): try: - exec('res = %s' % str(value)) + res = eval('%s' % str(value)) except SyntaxError as se: res = None else: try: - exec('res = """%s"""' % str(value)) + res = eval('"""%s"""' % str(value)) except SyntaxError as se: try: - exec("res = '''%s'''" % str(value)) + res = eval("res = '''%s'''" % str(value)) except SyntaxError as se: res = None return res diff --git a/appy/shared/dav.py b/appy/shared/dav.py index 295fc02..4d7949f 100644 --- a/appy/shared/dav.py +++ b/appy/shared/dav.py @@ -34,7 +34,7 @@ class FormDataEncoder: def encode(self): res = [] - for name, value in self.data.iteritems(): + for name, value in self.data.items(): res.append(self.marshalValue(name, value)) return '&'.join(res) diff --git a/appy/shared/diff.py b/appy/shared/diff.py index a836f7a..8167a8b 100644 --- a/appy/shared/diff.py +++ b/appy/shared/diff.py @@ -306,16 +306,16 @@ class HtmlDiff: else: tag = 'span' # What message will it show in its 'title' attribute? if not msg: - exec('msg = self.%sMsg' % type) + msg = eval('self.%sMsg' % type) # What CSS class (or, if none, tag-specific style) will be used ? - exec('cssClass = self.%sCss' % type) + cssClass = eval('self.%sCss' % type) if cssClass: style = 'class="%s"' % cssClass else: - exec('style = self.%sStyle' % type) + style = eval('self.%sStyle' % type) style = 'style="%s"' % style # The 'name' attribute of the tag indicates the type of the update. - exec('tagName = self.%sName' % type) + tagName = eval('self.%sName' % type) # The idea is: if there are several lines, every line must be surrounded # by a tag. This way, we know that a surrounding tag can't span several # lines, which is a prerequisite for managing cumulative diffs. diff --git a/appy/shared/ldap_connector.py b/appy/shared/ldap_connector.py index 772853f..e4f4f4f 100644 --- a/appy/shared/ldap_connector.py +++ b/appy/shared/ldap_connector.py @@ -83,7 +83,7 @@ class LdapConfig: dict of params usable for creating or updating the corresponding Appy user.''' res = {} - for name, appyName in self.ldapAttributes.iteritems(): + for name, appyName in self.ldapAttributes.items(): if not appyName: continue # Get the name of the attribute as known in the LDAP ldapName = getattr(self, name) @@ -111,7 +111,7 @@ class LdapConfig: user = tool.search1('User', noSecurity=True, login=login) if user: # Yes. Update it with info about him from the LDAP - for name, value in attrs.iteritems(): + for name, value in attrs.items(): currentValue = getattr(user, name) if value != currentValue: setattr(user, name, value) diff --git a/appy/shared/test.py b/appy/shared/test.py index d5c9863..b16f95c 100644 --- a/appy/shared/test.py +++ b/appy/shared/test.py @@ -69,11 +69,9 @@ class TestReport: TestReport.instance = self else: raise InternalError(TEST_REPORT_SINGLETON_ERROR) - def say(self, msg, force=False, encoding=None): + def say(self, msg, force=False): if self.verbose or force: print(msg) - if encoding: - self.report.write(msg.encode(encoding)) else: self.report.write(msg) self.report.write('\n') diff --git a/appy/shared/utils.py b/appy/shared/utils.py index 6a9cbf5..42e53fb 100644 --- a/appy/shared/utils.py +++ b/appy/shared/utils.py @@ -194,7 +194,7 @@ def flipDict(d): '''Flips dict p_d: keys become values, values become keys. p_d is left untouched: a new, flipped, dict is returned.''' res = {} - for k, v in d.iteritems(): res[v] = k + for k, v in d.items(): res[v] = k return res # ------------------------------------------------------------------------------ @@ -291,7 +291,7 @@ def normalizeString(s, usage='fileName'): for char in s: if char not in fileNameIgnore: res += char elif usage.startswith('alpha'): - exec('rex = %sRex' % usage) + rex = eval('%sRex' % usage) res = '' for char in s: if rex.match(char): res += char diff --git a/appy/shared/xml_parser.py b/appy/shared/xml_parser.py index d572668..2da2bc9 100644 --- a/appy/shared/xml_parser.py +++ b/appy/shared/xml_parser.py @@ -222,7 +222,7 @@ class XmlParser(ContentHandler, ErrorHandler): '''This method is called every time expat does not recognize an entity. We provide here support for HTML entities.''' if name in HTML_ENTITIES: - self.characters(HTML_ENTITIES[name].decode('utf-8')) + self.characters(HTML_ENTITIES[name]) else: # Put a question mark instead of raising an exception. self.characters('?') @@ -245,23 +245,20 @@ class XmlParser(ContentHandler, ErrorHandler): - a file instance opened for reading. Note that in this case, this method will close it. ''' - try: - from io import StringIO - except ImportError: - from io import StringIO + from io import BytesIO self._xml = xml self.parser.setContentHandler(self) self.parser.setErrorHandler(self) self.parser.setFeature(feature_external_ges, False) inputSource = InputSource() if source == 'string': - inputSource.setByteStream(StringIO(xml)) + inputSource.setByteStream(BytesIO(xml.encode('utf-8'))) else: - if not isinstance(xml, file): - xml = file(xml) + if isinstance(xml, str): + xml = open(xml,'rb') inputSource.setByteStream(xml) self.parser.parse(inputSource) - if isinstance(xml, file): xml.close() + if hasattr(xml, 'close'): xml.close() return self.res # ------------------------------------------------------------------------------ @@ -464,7 +461,7 @@ class XmlUnmarshaller(XmlParser): # If not, try a standard conversion elif e.currentBasicType in self.numericTypes: try: - exec('value = %s' % value) + value = eval('%s' % value) except SyntaxError: raise AppyError(CONVERSION_ERROR % ( e.currentBasicType, value)) @@ -945,10 +942,10 @@ class XmlComparator: # Perform the comparison differ = difflib.Differ() if self.areXml: - f = file(self.fileNameA) + f = open(self.fileNameA, 'rb') contentA = f.read() f.close() - f = file(self.fileNameB) + f = open(self.fileNameB, 'rb') contentB = f.read() f.close() xmlHandler = XmlHandler(self.xmlTagsToIgnore, self.xmlAttrsToIgnore) @@ -958,10 +955,10 @@ class XmlComparator: xml.sax.parseString(contentB, xmlHandler) contentB = xmlHandler.res.split('\n') else: - f = file(self.fileNameA) + f = open(self.fileNameA, 'r', encoding=encoding) contentA = f.readlines() f.close() - f = file(self.fileNameB) + f = open(self.fileNameB, 'r', encoding=encoding) contentB = f.readlines() f.close() diffResult = list(differ.compare(contentA, contentB)) @@ -975,17 +972,17 @@ class XmlComparator: if not atLeastOneDiff: msg = 'Difference(s) detected between files %s and %s:' % \ (self.fileNameA, self.fileNameB) - if report: report.say(msg, encoding='utf-8') + if report: report.say(msg) else: print(msg) atLeastOneDiff = True if not lastLinePrinted: if report: report.say('...') else: print('...') if self.areXml: - if report: report.say(line, encoding=encoding) + if report: report.say(line) else: print(line) else: - if report: report.say(line[:-1], encoding=encoding) + if report: report.say(line[:-1]) else: print((line[:-1])) lastLinePrinted = True else: