From 8fad7f9c88c322e782f9b9dd4b6c1a783d95e756 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 10 Mar 2012 15:37:13 +0000 Subject: [PATCH 001/319] Initial changes for Python 3 compatibility. --- .gitignore | 3 +- setup.py | 4 + xlrd/biffh.py | 8 +- xlrd/compdoc.py | 6 +- xlrd/examples/xlrdnameAPIdemo.py | 1 + xlrd/examples/xlrdnameAPIdemo_py3.py | 179 +++++++++++++++++++++++++++ xlrd/formatting.py | 4 +- xlrd/formula.py | 13 +- xlrd/sheet.py | 4 +- xlrd/timemachine.py | 22 ++++ 10 files changed, 231 insertions(+), 13 deletions(-) create mode 100644 xlrd/examples/xlrdnameAPIdemo_py3.py diff --git a/.gitignore b/.gitignore index db29331f..8edaf15a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /dist -*.egg-info \ No newline at end of file +*.egg-info +build/ diff --git a/setup.py b/setup.py index 29362c27..8c68fb55 100644 --- a/setup.py +++ b/setup.py @@ -74,4 +74,8 @@ def mkargs(**kwargs): ) args.update(args24) +if python_version >= (3,): + from distutils.command.build_py import build_py_2to3 + args['cmdclass'] = {'build_py': build_py_2to3} + setup(**args) diff --git a/xlrd/biffh.py b/xlrd/biffh.py index d5855be9..aa276364 100644 --- a/xlrd/biffh.py +++ b/xlrd/biffh.py @@ -249,7 +249,9 @@ def dump(self, f=None, header=None, footer=None, indent=0): _cell_opcode_dict = {} for _cell_opcode in _cell_opcode_list: _cell_opcode_dict[_cell_opcode] = 1 -is_cell_opcode = _cell_opcode_dict.has_key + +def is_cell_opcode(c): + return has_key(_cell_opcode_dict, c) # def fprintf(f, fmt, *vargs): f.write(fmt % vargs) @@ -290,7 +292,7 @@ def unpack_unicode(data, pos, lenlen=2): # Avoid crash if missing. return u"" pos += lenlen - options = ord(data[pos]) + options = get_int_1byte(data, pos) pos += 1 # phonetic = options & 0x04 # richtext = options & 0x08 @@ -332,7 +334,7 @@ def unpack_unicode_update_pos(data, pos, lenlen=2, known_len=None): if not nchars and not data[pos:]: # Zero-length string with no options byte return (u"", pos) - options = ord(data[pos]) + options = get_int_1byte(data, pos) pos += 1 phonetic = options & 0x04 richtext = options & 0x08 diff --git a/xlrd/compdoc.py b/xlrd/compdoc.py index 22d2ae84..738ecb7b 100644 --- a/xlrd/compdoc.py +++ b/xlrd/compdoc.py @@ -23,7 +23,7 @@ ## # Magic cookie that should appear in the first 8 bytes of the file. -SIGNATURE = "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" +SIGNATURE = b("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1") EOCSID = -2 FREESID = -1 @@ -84,7 +84,7 @@ def __init__(self, mem, logfile=sys.stdout, DEBUG=0): self.DEBUG = DEBUG if mem[0:8] != SIGNATURE: raise CompDocError('Not an OLE2 compound document') - if mem[28:30] != '\xFE\xFF': + if mem[28:30] != b('\xFE\xFF'): raise CompDocError('Expected "little-endian" marker, found %r' % mem[28:30]) revision, version = unpack('> self.logfile, "_get_stream(%s): seen" % name; dump_list(self.seen, 20, self.logfile) - return ''.join(sectors) + return b('').join(sectors) def _dir_search(self, path, storage_DID=0): # Return matching DirNode instance, or None diff --git a/xlrd/examples/xlrdnameAPIdemo.py b/xlrd/examples/xlrdnameAPIdemo.py index 6cd60df9..a0e15cd5 100644 --- a/xlrd/examples/xlrdnameAPIdemo.py +++ b/xlrd/examples/xlrdnameAPIdemo.py @@ -155,6 +155,7 @@ def usage(): sys.stdout.write(text) if len(sys.argv) != 5: + print(sys.argv) usage() sys.exit(0) arg_pattern = sys.argv[1] # glob pattern e.g. "foo*.xls" diff --git a/xlrd/examples/xlrdnameAPIdemo_py3.py b/xlrd/examples/xlrdnameAPIdemo_py3.py new file mode 100644 index 00000000..f415843f --- /dev/null +++ b/xlrd/examples/xlrdnameAPIdemo_py3.py @@ -0,0 +1,179 @@ +# -*- coding: cp1252 -*- + +## +# Module/script example of the xlrd API for extracting information +# about named references, named constants, etc. +# +#

Copyright © 2006 Stephen John Machin, Lingfo Pty Ltd

+#

This module is part of the xlrd package, which is released under a BSD-style licence.

+## + +import xlrd +import sys +import glob + +def scope_as_string(book, scope): + if 0 <= scope < book.nsheets: + return "sheet #%d (%r)" % (scope, book.sheet_names()[scope]) + if scope == -1: + return "Global" + if scope == -2: + return "Macro/VBA" + return "Unknown scope value (%r)" % scope + +def do_scope_query(book, scope_strg, show_contents=0, f=sys.stdout): + try: + qscope = int(scope_strg) + except ValueError: + if scope_strg == "*": + qscope = None # means "all' + else: + # so assume it's a sheet name ... + qscope = book.sheet_names().index(scope_strg) + print("%r => %d" % (scope_strg, qscope), file=f) + for nobj in book.name_obj_list: + if qscope is None or nobj.scope == qscope: + show_name_object(book, nobj, show_contents, f) + +def show_name_details(book, name, show_contents=0, f=sys.stdout): + """ + book -- Book object obtained from xlrd.open_workbook(). + name -- The name that's being investigated. + show_contents -- 0: Don't; 1: Non-empty cells only; 2: All cells + f -- Open output file handle. + """ + name_lcase = name.lower() # Excel names are case-insensitive. + nobj_list = book.name_map.get(name_lcase) + if not nobj_list: + print("%r: unknown name" % name, file=f) + return + for nobj in nobj_list: + show_name_object(book, nobj, show_contents, f) + +def show_name_details_in_scope( + book, name, scope_strg, show_contents=0, f=sys.stdout, + ): + try: + scope = int(scope_strg) + except ValueError: + # so assume it's a sheet name ... + scope = book.sheet_names().index(scope_strg) + print("%r => %d" % (scope_strg, scope), file=f) + name_lcase = name.lower() # Excel names are case-insensitive. + while 1: + nobj = book.name_and_scope_map.get((name_lcase, scope)) + if nobj: + break + print("Name %r not found in scope %d" % (name, scope), file=f) + if scope == -1: + return + scope = -1 # Try again with global scope + print("Name %r found in scope %d" % (name, scope), file=f) + show_name_object(book, nobj, show_contents, f) + +def showable_cell_value(celltype, cellvalue, datemode): + if celltype == xlrd.XL_CELL_DATE: + try: + showval = xlrd.xldate_as_tuple(cellvalue, datemode) + except xlrd.XLDateError: + e1, e2 = sys.exc_info()[:2] + showval = "%s:%s" % (e1.__name__, e2) + elif celltype == xlrd.XL_CELL_ERROR: + showval = xlrd.error_text_from_code.get( + cellvalue, '' % cellvalue) + else: + showval = cellvalue + return showval + +def show_name_object(book, nobj, show_contents=0, f=sys.stdout): + print("\nName: %r, scope: %r (%s)" \ + % (nobj.name, nobj.scope, scope_as_string(book, nobj.scope)), file=f) + res = nobj.result + print("Formula eval result: %r" % res, file=f) + if res is None: + return + # result should be an instance of the Operand class + kind = res.kind + value = res.value + if kind >= 0: + # A scalar, or unknown ... you've seen all there is to see. + pass + elif kind == xlrd.oREL: + # A list of Ref3D objects representing *relative* ranges + for i in range(len(value)): + ref3d = value[i] + print("Range %d: %r ==> %s"% (i, ref3d.coords, xlrd.rangename3drel(book, ref3d)), file=f) + elif kind == xlrd.oREF: + # A list of Ref3D objects + for i in range(len(value)): + ref3d = value[i] + print("Range %d: %r ==> %s"% (i, ref3d.coords, xlrd.rangename3d(book, ref3d)), file=f) + if not show_contents: + continue + datemode = book.datemode + for shx in range(ref3d.shtxlo, ref3d.shtxhi): + sh = book.sheet_by_index(shx) + print(" Sheet #%d (%s)" % (shx, sh.name), file=f) + rowlim = min(ref3d.rowxhi, sh.nrows) + collim = min(ref3d.colxhi, sh.ncols) + for rowx in range(ref3d.rowxlo, rowlim): + for colx in range(ref3d.colxlo, collim): + cty = sh.cell_type(rowx, colx) + if cty == xlrd.XL_CELL_EMPTY and show_contents == 1: + continue + cval = sh.cell_value(rowx, colx) + sval = showable_cell_value(cty, cval, datemode) + print(" (%3d,%3d) %-5s: %r" \ + % (rowx, colx, xlrd.cellname(rowx, colx), sval), file=f) + +if __name__ == "__main__": + def usage(): + text = """ +usage: xlrdnameAIPdemo.py glob_pattern name scope show_contents + +where: + "glob_pattern" designates a set of files + "name" is a name or '*' (all names) + "scope" is -1 (global) or a sheet number + or a sheet name or * (all scopes) + "show_contents" is one of 0 (no show), + 1 (only non-empty cells), or 2 (all cells) + +Examples (script name and glob_pattern arg omitted for brevity) + [Searching through book.name_obj_list] + * * 0 lists all names + * * 1 lists all names, showing referenced non-empty cells + * 1 0 lists all names local to the 2nd sheet + * Northern 0 lists all names local to the 'Northern' sheet + * -1 0 lists all names with global scope + [Initial direct access through book.name_map] + Sales * 0 lists all occurrences of "Sales" in any scope + [Direct access through book.name_and_scope_map] + Revenue -1 0 checks if "Revenue" exists in global scope + +""" + sys.stdout.write(text) + + if len(sys.argv) != 5: + print((sys.argv)) + usage() + sys.exit(0) + arg_pattern = sys.argv[1] # glob pattern e.g. "foo*.xls" + arg_name = sys.argv[2] # see below + arg_scope = sys.argv[3] # see below + arg_show_contents = int(sys.argv[4]) # 0: no show, 1: only non-empty cells, + # 2: all cells + for fname in glob.glob(arg_pattern): + book = xlrd.open_workbook(fname) + if arg_name == "*": + # Examine book.name_obj_list to find all names + # in a given scope ("*" => all scopes) + do_scope_query(book, arg_scope, arg_show_contents) + elif arg_scope == "*": + # Using book.name_map to find all usage of a name. + show_name_details(book, arg_name, arg_show_contents) + else: + # Using book.name_and_scope_map to find which if any instances + # of a name are visible in the given scope, which can be supplied + # as -1 (global) or a sheet number or a sheet name. + show_name_details_in_scope(book, arg_name, arg_scope, arg_show_contents) diff --git a/xlrd/formatting.py b/xlrd/formatting.py index f6a58b42..322aa490 100644 --- a/xlrd/formatting.py +++ b/xlrd/formatting.py @@ -458,7 +458,9 @@ def is_date_format_string(book, fmt): # TODO: u'[h]\\ \\h\\o\\u\\r\\s' ([h] means don't care about hours > 23) state = 0 s = '' - ignorable = skip_char_dict.has_key + def ignorable(c): + return has_key(skip_char_dict, c) + for c in fmt: if state == 0: if c == u'"': diff --git a/xlrd/formula.py b/xlrd/formula.py index 37477348..d0eb4db3 100644 --- a/xlrd/formula.py +++ b/xlrd/formula.py @@ -393,7 +393,9 @@ _error_opcodes = {} for _x in [0x07, 0x08, 0x0A, 0x0B, 0x1C, 0x1D, 0x2F]: _error_opcodes[_x] = 1 -is_error_opcode = _error_opcodes.has_key + +def is_error_opcode(c): + return has_key(_error_opcodes, c) tRangeFuncs = (min, max, min, max, min, max) tIsectFuncs = (max, min, max, min, max, min) @@ -687,6 +689,11 @@ def __repr__(self): import operator as opr +try: + from operator import floordiv +except: + from operator import div as floordiv + def nop(x): return x @@ -716,7 +723,7 @@ def num2strg(num): tAdd: (_arith_argdict, oNUM, opr.add, 30, '+'), tSub: (_arith_argdict, oNUM, opr.sub, 30, '-'), tMul: (_arith_argdict, oNUM, opr.mul, 40, '*'), - tDiv: (_arith_argdict, oNUM, opr.div, 40, '/'), + tDiv: (_arith_argdict, oNUM, floordiv, 40, '/'), tPower: (_arith_argdict, oNUM, _opr_pow, 50, '^',), tConcat:(_strg_argdict, oSTRG, opr.add, 20, '&'), tLT: (_cmp_argdict, oBOOL, _opr_lt, 10, '<'), @@ -819,7 +826,7 @@ def not_in_name_formula(op_arg, oname_arg): stack = [unk_opnd] while 0 <= pos < fmlalen: - op = ord(data[pos]) + op = get_int_1byte(data, pos) opcode = op & 0x1f optype = (op & 0x60) >> 5 if optype: diff --git a/xlrd/sheet.py b/xlrd/sheet.py index 80f6f2eb..d3ad334d 100644 --- a/xlrd/sheet.py +++ b/xlrd/sheet.py @@ -2142,7 +2142,7 @@ class Hyperlink(BaseObject): # === helpers === def unpack_RK(rk_str): - flags = ord(rk_str[0]) + flags = get_int_1byte(rk_str, 0) if flags & 2: # There's a SIGNED 30-bit integer in there! i, = unpack('= (3,): + # Python 3 + def b(s): + return s.encode('cp1252') + + def get_int_1byte(data, pos): + return data[pos] + +else: + # Python 2 + def b(s): return s + + def get_int_1byte(data, pos): + return ord(data[pos]) From 46da0acef7b66eb376c5522ecb835f62afb288af Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 10 Mar 2012 17:59:31 +0000 Subject: [PATCH 002/319] Remove extraneous print from demo code. --- .gitignore | 1 + xlrd/examples/xlrdnameAPIdemo.py | 1 - xlrd/examples/xlrdnameAPIdemo_py3.py | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 8edaf15a..325ce810 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /dist *.egg-info build/ +*.pyc diff --git a/xlrd/examples/xlrdnameAPIdemo.py b/xlrd/examples/xlrdnameAPIdemo.py index a0e15cd5..6cd60df9 100644 --- a/xlrd/examples/xlrdnameAPIdemo.py +++ b/xlrd/examples/xlrdnameAPIdemo.py @@ -155,7 +155,6 @@ def usage(): sys.stdout.write(text) if len(sys.argv) != 5: - print(sys.argv) usage() sys.exit(0) arg_pattern = sys.argv[1] # glob pattern e.g. "foo*.xls" diff --git a/xlrd/examples/xlrdnameAPIdemo_py3.py b/xlrd/examples/xlrdnameAPIdemo_py3.py index f415843f..d9fd16f9 100644 --- a/xlrd/examples/xlrdnameAPIdemo_py3.py +++ b/xlrd/examples/xlrdnameAPIdemo_py3.py @@ -155,7 +155,6 @@ def usage(): sys.stdout.write(text) if len(sys.argv) != 5: - print((sys.argv)) usage() sys.exit(0) arg_pattern = sys.argv[1] # glob pattern e.g. "foo*.xls" From e28a8e0c3aa9d526a19f3a06e4f8c410d1cbcc52 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 10 Mar 2012 18:09:34 +0000 Subject: [PATCH 003/319] Use truediv instead of floordiv in formula. --- xlrd/formula.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xlrd/formula.py b/xlrd/formula.py index d0eb4db3..4197b308 100644 --- a/xlrd/formula.py +++ b/xlrd/formula.py @@ -690,9 +690,9 @@ def __repr__(self): import operator as opr try: - from operator import floordiv + from operator import truediv except: - from operator import div as floordiv + from operator import div as truediv def nop(x): return x @@ -723,7 +723,7 @@ def num2strg(num): tAdd: (_arith_argdict, oNUM, opr.add, 30, '+'), tSub: (_arith_argdict, oNUM, opr.sub, 30, '-'), tMul: (_arith_argdict, oNUM, opr.mul, 40, '*'), - tDiv: (_arith_argdict, oNUM, floordiv, 40, '/'), + tDiv: (_arith_argdict, oNUM, truediv, 40, '/'), tPower: (_arith_argdict, oNUM, _opr_pow, 50, '^',), tConcat:(_strg_argdict, oSTRG, opr.add, 20, '&'), tLT: (_cmp_argdict, oBOOL, _opr_lt, 10, '<'), From b2c73ff1c4e0e742513f626bd3cf257a72112cc8 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 10 Mar 2012 18:29:33 +0000 Subject: [PATCH 004/319] Add tests from xlrd3 https://bitbucket.org/mozman/xlrd3 --- tests/Formate.xls | Bin 0 -> 10752 bytes tests/formula_test_sjmachin.xls | Bin 0 -> 16896 bytes tests/profiles.xls | Bin 0 -> 33792 bytes tests/test_cell.py | 48 ++++++++++ tests/test_formats.py | 82 ++++++++++++++++ tests/test_formulas_sjmachin.py | 51 ++++++++++ tests/test_sheet.py | 120 ++++++++++++++++++++++++ tests/test_workbook.py | 50 ++++++++++ tests/test_xfcell.py | 159 ++++++++++++++++++++++++++++++++ tests/test_xldate.py | 57 ++++++++++++ tests/xf_class.xls | Bin 0 -> 23040 bytes 11 files changed, 567 insertions(+) create mode 100644 tests/Formate.xls create mode 100644 tests/formula_test_sjmachin.xls create mode 100644 tests/profiles.xls create mode 100644 tests/test_cell.py create mode 100644 tests/test_formats.py create mode 100644 tests/test_formulas_sjmachin.py create mode 100644 tests/test_sheet.py create mode 100644 tests/test_workbook.py create mode 100644 tests/test_xfcell.py create mode 100644 tests/test_xldate.py create mode 100644 tests/xf_class.xls diff --git a/tests/Formate.xls b/tests/Formate.xls new file mode 100644 index 0000000000000000000000000000000000000000..808cafb4cd98bd375cc2ec4e4c9863999a51f480 GIT binary patch literal 10752 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 literal 0 HcmV?d00001 diff --git a/tests/formula_test_sjmachin.xls b/tests/formula_test_sjmachin.xls new file mode 100644 index 0000000000000000000000000000000000000000..82170088ee14089da502b8aece7bab9bd859f19d GIT binary patch literal 16896 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 literal 0 HcmV?d00001 diff --git a/tests/profiles.xls b/tests/profiles.xls new file mode 100644 index 0000000000000000000000000000000000000000..1254f02f30a2e0f545529bc610f55834d6b8115c GIT binary patch literal 33792 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 a{|EcY|C#Rj{}pdLTL1RnU;pnu|9=AR;#0x^ literal 0 HcmV?d00001 diff --git a/tests/test_cell.py b/tests/test_cell.py new file mode 100644 index 00000000..af2738d8 --- /dev/null +++ b/tests/test_cell.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# Author: mozman +# Purpose: test cell functions +# Created: 03.12.2010 +# Copyright (C) 2010, Manfred Moitzi +# License: GPLv3 + +import sys +import os +import unittest + +import xlrd + +def from_tests_dir(filename): + return os.path.join(os.path.dirname(os.path.abspath(__file__)), filename) + +book = xlrd.open_workbook(from_tests_dir('profiles.xls'), formatting_info=True) +sheet = book.sheet_by_name('PROFILEDEF') + +class TestCell(unittest.TestCase): + def test_string_cell(self): + cell = sheet.cell(0, 0) + self.assertEqual(cell.ctype, xlrd.XL_CELL_TEXT) + self.assertEqual(cell.value, 'PROFIL') + self.assertTrue(cell.xf_index > 0) + + def test_number_cell(self): + cell = sheet.cell(1, 1) + self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) + self.assertEqual(cell.value, 100) + self.assertTrue(cell.xf_index > 0) + + def test_calculated_cell(self): + sheet2 = book.sheet_by_name('PROFILELEVELS') + cell = sheet2.cell(1, 3) + self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) + self.assertAlmostEqual(cell.value, 265.131, places=3) + self.assertTrue(cell.xf_index > 0) + + def test_merged_cells(self): + book = xlrd.open_workbook(from_tests_dir('xf_class.xls'), formatting_info=True) + sheet3 = book.sheet_by_name('table2') + row_lo, row_hi, col_lo, col_hi = sheet3.merged_cells[0] + self.assertEqual(sheet3.cell(row_lo, col_lo).value, 'MERGED') + self.assertEqual((row_lo, row_hi, col_lo, col_hi), (3, 7, 2, 5)) + +if __name__=='__main__': + unittest.main() diff --git a/tests/test_formats.py b/tests/test_formats.py new file mode 100644 index 00000000..5b66b1c7 --- /dev/null +++ b/tests/test_formats.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Author: mozman +# Purpose: test cell formats +# Created: 03.12.2010 +# Copyright (C) 2010, Manfred Moitzi +# License: GPLv3 + +import sys +import os +import unittest + +import xlrd + +def from_tests_dir(filename): + return os.path.join(os.path.dirname(os.path.abspath(__file__)), filename) + +book = xlrd.open_workbook(from_tests_dir('Formate.xls'), formatting_info=True) + +class TestCellContent(unittest.TestCase): + def test_text_cells(self): + sheet = book.sheet_by_name('Blätt1') + for row, name in enumerate(['Huber', 'Äcker', 'Öcker']): + cell = sheet.cell(row, 0) + self.assertEqual(cell.ctype, xlrd.XL_CELL_TEXT) + self.assertEqual(cell.value, name) + self.assertTrue(cell.xf_index > 0) + + def test_date_cells(self): + sheet = book.sheet_by_name('Blätt1') + # see also 'Dates in Excel spreadsheets' in the documentation + # convert: xldate_as_tuple(float, book.datemode) -> (year, month, + # day, hour, minutes, seconds) + for row, date in [(0, 2741.), (1, 38406.), (2, 32266.)]: + cell = sheet.cell(row, 1) + self.assertEqual(cell.ctype, xlrd.XL_CELL_DATE) + self.assertEqual(cell.value, date) + self.assertTrue(cell.xf_index > 0) + + def test_time_cells(self): + sheet = book.sheet_by_name('Blätt1') + # see also 'Dates in Excel spreadsheets' in the documentation + # convert: xldate_as_tuple(float, book.datemode) -> (year, month, + # day, hour, minutes, seconds) + for row, time in [(3, .273611), (4, .538889), (5, .741123)]: + cell = sheet.cell(row, 1) + self.assertEqual(cell.ctype, xlrd.XL_CELL_DATE) + self.assertAlmostEqual(cell.value, time, places=6) + self.assertTrue(cell.xf_index > 0) + + def test_percent_cells(self): + sheet = book.sheet_by_name('Blätt1') + for row, time in [(6, .974), (7, .124)]: + cell = sheet.cell(row, 1) + self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) + self.assertAlmostEqual(cell.value, time, places=3) + self.assertTrue(cell.xf_index > 0) + + def test_currency_cells(self): + sheet = book.sheet_by_name('Blätt1') + for row, time in [(8, 1000.30), (9, 1.20)]: + cell = sheet.cell(row, 1) + self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) + self.assertAlmostEqual(cell.value, time, places=2) + self.assertTrue(cell.xf_index > 0) + + def test_get_from_merged_cell(self): + sheet = book.sheet_by_name('ÖÄÜ') + cell = sheet.cell(2, 2) + self.assertEqual(cell.ctype, xlrd.XL_CELL_TEXT) + self.assertEqual(cell.value, 'MERGED CELLS') + self.assertTrue(cell.xf_index > 0) + + def test_ignore_diagram(self): + sheet = book.sheet_by_name('Blätt3') + cell = sheet.cell(0, 0) + self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) + self.assertEqual(cell.value, 100) + self.assertTrue(cell.xf_index > 0) + +if __name__=='__main__': + unittest.main() diff --git a/tests/test_formulas_sjmachin.py b/tests/test_formulas_sjmachin.py new file mode 100644 index 00000000..75892ef4 --- /dev/null +++ b/tests/test_formulas_sjmachin.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +#coding:utf-8 +# Author: mozman -- +# Purpose: test formula (inspired by sjmachin) +# Created: 21.01.2011 +# Copyright (C) , Manfred Moitzi +# License: GPLv3 + +import os +import sys +import unittest + +import xlrd + +def from_tests_dir(filename): + return os.path.join(os.path.dirname(os.path.abspath(__file__)), filename) + +book = xlrd.open_workbook(from_tests_dir('formula_test_sjmachin.xls')) +sheet = book.sheet_by_index(0) + +class TestFormulas(unittest.TestCase): + + def get_value(self, col, row): + return ascii(sheet.col_values(col)[row]) + + def test_is_opened(self): + self.assertIsNotNone(book) + + def test_cell_B2(self): + self.assertEqual(self.get_value(1, 1), r"'\u041c\u041e\u0421\u041a\u0412\u0410 \u041c\u043e\u0441\u043a\u0432\u0430'") + + def test_cell_B3(self): + self.assertEqual(self.get_value(1, 2), '0.14285714285714285') + + def test_cell_B4(self): + self.assertEqual(self.get_value(1, 3), "'ABCDEF'") + + def test_cell_B5(self): + self.assertEqual(self.get_value(1, 4), "''") + + def test_cell_B6(self): + self.assertEqual(self.get_value(1, 5), '1') + + def test_cell_B7(self): + self.assertEqual(self.get_value(1, 6), '7') + + def test_cell_B8(self): + self.assertEqual(self.get_value(1, 7), r"'\u041c\u041e\u0421\u041a\u0412\u0410 \u041c\u043e\u0441\u043a\u0432\u0430'") + +if __name__=='__main__': + unittest.main() diff --git a/tests/test_sheet.py b/tests/test_sheet.py new file mode 100644 index 00000000..7d739731 --- /dev/null +++ b/tests/test_sheet.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python +# Author: mozman +# Purpose: test sheet functions +# Created: 03.12.2010 +# Copyright (C) 2010, Manfred Moitzi +# License: GPLv3 + +import sys +import os +import unittest + +import xlrd + +def from_tests_dir(filename): + return os.path.join(os.path.dirname(os.path.abspath(__file__)), filename) + +SHEETINDEX = 0 +NROWS = 15 +NCOLS = 13 + +ROW_ERR = NROWS + 10 +COL_ERR = NCOLS + 10 + +class TestSheet(unittest.TestCase): + book = xlrd.open_workbook(from_tests_dir('profiles.xls'), formatting_info=True) + sheetnames = ['PROFILEDEF', 'AXISDEF', 'TRAVERSALCHAINAGE', 'AXISDATUMLEVELS', 'PROFILELEVELS'] + + def check_sheet_function(self, function): + self.assertTrue(function(0, 0)) + self.assertTrue(function(NROWS-1, NCOLS-1)) + + def check_sheet_function_index_error(self, function): + self.assertRaises(IndexError, function, ROW_ERR, 0) + self.assertRaises(IndexError, function, 0, COL_ERR) + + def check_col_slice(self, col_function): + _slice = col_function(0, 2, NROWS-2) + self.assertEqual(len(_slice), NROWS-4) + + def check_row_slice(self, row_function): + _slice = row_function(0, 2, NCOLS-2) + self.assertEqual(len(_slice), NCOLS-4) + + def test_nrows(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.assertEqual(sheet.nrows, NROWS) + + def test_ncols(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.assertEqual(sheet.ncols, NCOLS) + + def test_cell(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.assertNotEqual(xlrd.empty_cell, sheet.cell(0, 0)) + self.assertNotEqual(xlrd.empty_cell, sheet.cell(NROWS-1, NCOLS-1)) + + def test_cell_error(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_sheet_function_index_error(sheet.cell) + + def test_cell_type(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_sheet_function(sheet.cell_type) + + def test_cell_type_error(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_sheet_function_index_error(sheet.cell_type) + + def test_cell_value(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_sheet_function(sheet.cell_value) + + def test_cell_value_error(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_sheet_function_index_error(sheet.cell_value) + + def test_cell_xf_index(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_sheet_function(sheet.cell_xf_index) + + def test_cell_xf_index_error(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_sheet_function_index_error(sheet.cell_xf_index) + + def test_col(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + col = sheet.col(0) + self.assertEqual(len(col), NROWS) + + def test_row(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + row = sheet.row(0) + self.assertEqual(len(row), NCOLS) + + def test_col_slice(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_col_slice(sheet.col_slice) + + def test_col_types(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_col_slice(sheet.col_types) + + def test_col_values(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_col_slice(sheet.col_values) + + def test_row_slice(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_row_slice(sheet.row_slice) + + def test_row_types(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_row_slice(sheet.col_types) + + def test_row_values(self): + sheet = self.book.sheet_by_index(SHEETINDEX) + self.check_col_slice(sheet.row_values) + +if __name__=='__main__': + unittest.main() diff --git a/tests/test_workbook.py b/tests/test_workbook.py new file mode 100644 index 00000000..2e21d206 --- /dev/null +++ b/tests/test_workbook.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# Author: mozman +# Purpose: test xlrd basic functions +# Created: 03.12.2010 +# Copyright (C) 2010, Manfred Moitzi +# License: GPLv3 + +import sys +import os +import unittest + +import xlrd + +def from_tests_dir(filename): + return os.path.join(os.path.dirname(os.path.abspath(__file__)), filename) + +class TestOpenWorkbook(unittest.TestCase): + def test_open_workbook(self): + book = xlrd.open_workbook(from_tests_dir('profiles.xls')) + +class TestReadWorkbook(unittest.TestCase): + book = xlrd.open_workbook(from_tests_dir('profiles.xls')) + sheetnames = ['PROFILEDEF', 'AXISDEF', 'TRAVERSALCHAINAGE', 'AXISDATUMLEVELS', 'PROFILELEVELS'] + + def test_nsheets(self): + self.assertEqual(self.book.nsheets, 5) + + def test_sheet_by_name(self): + for name in self.sheetnames: + sheet = self.book.sheet_by_name(name) + self.assertTrue(sheet) + + def test_sheet_by_index(self): + for index in range(5): + sheet = self.book.sheet_by_index(index) + self.assertEqual(sheet.name, self.sheetnames[index]) + + def test_sheets(self): + sheets = self.book.sheets() + for index, sheet in enumerate(sheets): + self.assertEqual(sheet.name, self.sheetnames[index]) + + def test_sheet_names(self): + names = self.book.sheet_names() + self.assertEqual(self.sheetnames, names) + + + +if __name__=='__main__': + unittest.main() diff --git a/tests/test_xfcell.py b/tests/test_xfcell.py new file mode 100644 index 00000000..f866ddd1 --- /dev/null +++ b/tests/test_xfcell.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Author: mozman +# Purpose: test cell functions +# Created: 03.12.2010 +# Copyright (C) 2010, Manfred Moitzi +# License: GPLv3 + +import sys +import os +import unittest +from datetime import datetime, date, time + +import xlrd +from xlrd import xfconst + +def from_tests_dir(filename): + return os.path.join(os.path.dirname(os.path.abspath(__file__)), filename) + +book = xlrd.open_workbook(from_tests_dir('profiles.xls'), + formatting_info=True) +sheet = book.sheet_by_name('PROFILEDEF') + +class TestCellValues(unittest.TestCase): + def test_string_cell(self): + cell = sheet.cell(0, 0) + self.assertEqual(cell.ctype, xlrd3.XL_CELL_TEXT) + self.assertEqual(cell.value, 'PROFIL') + self.assertTrue(cell.has_xf) + + def test_number_cell(self): + cell = sheet.cell(1, 1) + self.assertEqual(cell.ctype, xlrd3.XL_CELL_NUMBER) + self.assertEqual(cell.value, 100) + self.assertTrue(cell.has_xf) + + def test_calculated_cell(self): + sheet2 = book.sheet_by_name('PROFILELEVELS') + cell = sheet2.cell(1, 3) + self.assertEqual(cell.ctype, xlrd3.XL_CELL_NUMBER) + self.assertAlmostEqual(cell.value, 265.131, places=3) + self.assertTrue(cell.has_xf) + + def test_date(self): + book = xlrd.open_workbook(from_tests_dir('Formate.xls'), + formatting_info=True) + sheet = book.sheet_by_name('Blätt1') + for row, y, m, d in [(0, 1907, 7, 3), (1, 2005, 2, 23), (2, 1988, 5, 3)]: + cell = sheet.cell(row, 1) + self.assertEqual(cell.date(), date(y, m, d)) + + def test_time(self): + book = xlrd.open_workbook(from_tests_dir('Formate.xls'), + formatting_info=True) + sheet = book.sheet_by_name('Blätt1') + for row, h, m, s in [(3, 6, 34, 0), (4, 12, 56, 0), (5, 17, 47, 13)]: + cell = sheet.cell(row, 1) + self.assertEqual(cell.time(), time(h, m, s)) + +xf_book = xlrd.open_workbook(from_tests_dir('xf_class.xls'), + formatting_info=True) + +class TestXFCellProperties(unittest.TestCase): + sheet = xf_book.sheet_by_name('table1') + + def cell(self, row, col): + return self.sheet.cell(row, col) + + def test_red_background_color(self): + # bgcolor should be 'red' #ff0000, but is not! (also xlrd 0.7.1) + # but pattern_color is 'red' + self.assertEqual(self.cell(0, 0).background_color(), (153, 51, 0)) + self.assertEqual(self.cell(0, 0).pattern_color(), (255, 0, 0)) + self.assertEqual(self.cell(0, 0).fill_pattern(), 1) + + def test_green_background_color(self): + # bgcolor should be 'green' #008000, but is not! (also xlrd 0.7.1) + # but pattern_color is 'green' + self.assertEqual(self.cell(1, 0).background_color(), (0, 128, 128)) + self.assertEqual(self.cell(1, 0).pattern_color(), (0, 128, 0)) + self.assertEqual(self.cell(1, 0).fill_pattern(), 1) + + def test_blue_background_color(self): + # bgcolor should be 'green' #0000ff, but is not! (also xlrd 0.7.1) + # and pattern_color is 'blue' + self.assertEqual(self.cell(2, 0).background_color(), (0, 128, 128)) + self.assertEqual(self.cell(2, 0).pattern_color(), (0, 102, 204)) + self.assertEqual(self.cell(2, 0).fill_pattern(), 1) + + def test_font_color(self): + self.assertEqual(self.cell(0, 1).font_color(), (255, 0, 0)) + + def test_format_str(self): + self.assertEqual(self.cell(0, 0).format_str().upper(), "GENERAL") + + def test_horiz_alignment(self): + self.assertEqual(self.cell(3, 0).alignment.hor_align, xfconst.HOR_ALIGN_LEFT) + self.assertEqual(self.cell(3, 1).alignment.hor_align, xfconst.HOR_ALIGN_CENTRED) + self.assertEqual(self.cell(3, 2).alignment.hor_align, xfconst.HOR_ALIGN_RIGHT) + + def test_vert_alignment(self): + self.assertEqual(self.cell(4, 0).alignment.vert_align, xfconst.VERT_ALIGN_TOP) + self.assertEqual(self.cell(4, 1).alignment.vert_align, xfconst.VERT_ALIGN_CENTRED) + self.assertEqual(self.cell(4, 2).alignment.vert_align, xfconst.VERT_ALIGN_BOTTOM) + + def test_other_alignment(self): + self.assertEqual(self.cell(4, 0).alignment.rotation, 0) + self.assertEqual(self.cell(4, 0).alignment.text_wrapped, 0) + self.assertEqual(self.cell(4, 0).alignment.indent_level, 0) + self.assertEqual(self.cell(4, 0).alignment.shrink_to_fit, 0) + self.assertEqual(self.cell(4, 0).alignment.text_direction, 0) + + def test_borderstyles(self): + cell = self.cell(9, 0) + self.assertEqual(cell.value, 'borderstyle') + styles = cell.borderstyles() + self.assertEqual(styles['left'], xfconst.LS_THIN) + self.assertEqual(styles['right'], xfconst.LS_THIN) + self.assertEqual(styles['top'], xfconst.LS_MEDIUM) + self.assertEqual(styles['bottom'], xfconst.LS_MEDIUM) + self.assertEqual(styles['diag'], xfconst.LS_THIN) + + def test_bordercolors(self): + cell = self.cell(9, 0) + self.assertEqual(cell.value, 'borderstyle') + colors = cell.bordercolors() + self.assertEqual(colors['left'], (0, 128, 0)) + self.assertEqual(colors['right'], (0, 128, 0)) + self.assertEqual(colors['top'], (255, 0, 0)) + self.assertEqual(colors['bottom'], (255, 0, 0)) + self.assertEqual(colors['diag'], None) # None is default color ??? + + def test_diagline(self): + cell = self.cell(9, 0) + self.assertEqual(cell.value, 'borderstyle') + self.assertTrue(cell.has_up_diag) + self.assertTrue(cell.has_down_diag) + + def test_protection(self): + cell = self.cell(0, 0) + # 'cell_locked' and 'formula_hidden' but only if sheet is protected + self.assertTrue(cell.is_cell_locked) + self.assertTrue(cell.is_formula_hidden) + + def test_repr_with_formatting_info(self): + cell = self.cell(0, 0) + self.assertEqual(repr(cell), "text:'RED' (XF:62)") + self.assertNotEqual(cell.xf_index, None) + + def test_repr_without_formatting_info(self): + book = xlrd.open_workbook(from_tests_dir('xf_class.xls'), + formatting_info=False) + sheet = book.sheet_by_name('table1') + cell = sheet.cell(0, 0) + self.assertEqual(repr(cell), "text:'RED'") + self.assertEqual(cell.xf_index, None) + +if __name__=='__main__': + unittest.main() diff --git a/tests/test_xldate.py b/tests/test_xldate.py new file mode 100644 index 00000000..901f7328 --- /dev/null +++ b/tests/test_xldate.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# Author: mozman +# Purpose: test xldate.py +# Created: 04.12.2010 +# Copyright (C) 2010, Manfred Moitzi +# License: GPLv3 + +import sys +import unittest + +from xlrd import xldate + +DATEMODE = 0 # 1900-based + +class TestXLDate(unittest.TestCase): + def test_date_as_tuple(self): + date = xldate.xldate_as_tuple(2741., DATEMODE) + self.assertEqual(date, (1907, 7, 3, 0, 0, 0)) + date = xldate.xldate_as_tuple(38406., DATEMODE) + self.assertEqual(date, (2005, 2, 23, 0, 0, 0)) + date = xldate.xldate_as_tuple(32266., DATEMODE) + self.assertEqual(date, (1988, 5, 3, 0, 0, 0)) + + def test_time_as_tuple(self): + time = xldate.xldate_as_tuple(.273611, DATEMODE) + self.assertEqual(time, (0, 0, 0, 6, 34, 0)) + time = xldate.xldate_as_tuple(.538889, DATEMODE) + self.assertEqual(time, (0, 0, 0, 12, 56, 0)) + time = xldate.xldate_as_tuple(.741123, DATEMODE) + self.assertEqual(time, (0, 0, 0, 17, 47, 13)) + + def test_xldate_from_date_tuple(self): + date = xldate.xldate_from_date_tuple( (1907, 7, 3), DATEMODE ) + self.assertAlmostEqual(date, 2741.) + date = xldate.xldate_from_date_tuple( (2005, 2, 23), DATEMODE ) + self.assertAlmostEqual(date, 38406.) + date = xldate.xldate_from_date_tuple( (1988, 5, 3), DATEMODE ) + self.assertAlmostEqual(date, 32266.) + + def test_xldate_from_time_tuple(self): + time = xldate.xldate_from_time_tuple( (6, 34, 0) ) + self.assertAlmostEqual(time, .273611, places=6) + time = xldate.xldate_from_time_tuple( (12, 56, 0) ) + self.assertAlmostEqual(time, .538889, places=6) + time = xldate.xldate_from_time_tuple( (17, 47, 13) ) + self.assertAlmostEqual(time, .741123, places=6) + + def test_xldate_from_datetime_tuple(self): + date = xldate.xldate_from_datetime_tuple( (1907, 7, 3, 6, 34, 0), DATEMODE) + self.assertAlmostEqual(date, 2741.273611, places=6) + date = xldate.xldate_from_datetime_tuple( (2005, 2, 23, 12, 56, 0), DATEMODE) + self.assertAlmostEqual(date, 38406.538889, places=6) + date = xldate.xldate_from_datetime_tuple( (1988, 5, 3, 17, 47, 13), DATEMODE) + self.assertAlmostEqual(date, 32266.741123, places=6) + +if __name__=='__main__': + unittest.main() diff --git a/tests/xf_class.xls b/tests/xf_class.xls new file mode 100644 index 0000000000000000000000000000000000000000..41db86cc2476b8eb093ab4a0afaf077b2d366a0e GIT binary patch literal 23040 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 literal 0 HcmV?d00001 From 987a6c2592cb03d365bfabe3002a4dd130fe6afc Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 10 Mar 2012 18:43:57 +0000 Subject: [PATCH 005/319] Tweaks to tests. --- tests/test_formulas_sjmachin.py | 5 +++++ tests/test_xfcell.py | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/test_formulas_sjmachin.py b/tests/test_formulas_sjmachin.py index 75892ef4..bb9664da 100644 --- a/tests/test_formulas_sjmachin.py +++ b/tests/test_formulas_sjmachin.py @@ -15,6 +15,11 @@ def from_tests_dir(filename): return os.path.join(os.path.dirname(os.path.abspath(__file__)), filename) +try: + ascii +except NameError: + ascii = str + book = xlrd.open_workbook(from_tests_dir('formula_test_sjmachin.xls')) sheet = book.sheet_by_index(0) diff --git a/tests/test_xfcell.py b/tests/test_xfcell.py index f866ddd1..234aabe8 100644 --- a/tests/test_xfcell.py +++ b/tests/test_xfcell.py @@ -24,20 +24,20 @@ def from_tests_dir(filename): class TestCellValues(unittest.TestCase): def test_string_cell(self): cell = sheet.cell(0, 0) - self.assertEqual(cell.ctype, xlrd3.XL_CELL_TEXT) + self.assertEqual(cell.ctype, xlrd.XL_CELL_TEXT) self.assertEqual(cell.value, 'PROFIL') self.assertTrue(cell.has_xf) def test_number_cell(self): cell = sheet.cell(1, 1) - self.assertEqual(cell.ctype, xlrd3.XL_CELL_NUMBER) + self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) self.assertEqual(cell.value, 100) self.assertTrue(cell.has_xf) def test_calculated_cell(self): sheet2 = book.sheet_by_name('PROFILELEVELS') cell = sheet2.cell(1, 3) - self.assertEqual(cell.ctype, xlrd3.XL_CELL_NUMBER) + self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) self.assertAlmostEqual(cell.value, 265.131, places=3) self.assertTrue(cell.has_xf) From d342a4c92e7c4eee7ff6ebae915ea0c44ce918b7 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 10 Mar 2012 18:44:15 +0000 Subject: [PATCH 006/319] Add script to run tests. --- tests/run_tests.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100755 tests/run_tests.py diff --git a/tests/run_tests.py b/tests/run_tests.py new file mode 100755 index 00000000..0993b8db --- /dev/null +++ b/tests/run_tests.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +import unittest + +from test_cell import * +from test_formats import * +from test_formulas_sjmachin import * +from test_sheet import * +from test_workbook import * +#from test_xfcell import * # Not currently working +from test_xldate import * + +if __name__ == "__main__": + unittest.main() From 22dbf8a1ce124bcd253a3bd16f1f96e87d0705b8 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 10 Mar 2012 18:53:34 +0000 Subject: [PATCH 007/319] Include changes to formula parsing from xlrd3 https://bitbucket.org/mozman/xlrd3/changeset/84447954d33f --- xlrd/sheet.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/xlrd/sheet.py b/xlrd/sheet.py index d3ad334d..5b81079f 100644 --- a/xlrd/sheet.py +++ b/xlrd/sheet.py @@ -912,8 +912,9 @@ def read(self, bk): fmlalen = local_unpack("= 80: - flag = ord(data[offset]) & 1 + flag = get_int_1byte(data, offset) & 1 enc = ("latin_1", "utf_16_le")[flag] offset += 1 chunk = unicode(data[offset:], enc) From 50ec40479e9b7870a72645dea8bd633a6d4782e9 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 10 Mar 2012 18:57:31 +0000 Subject: [PATCH 008/319] Correction to tests for Python 2. --- tests/test_formulas_sjmachin.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_formulas_sjmachin.py b/tests/test_formulas_sjmachin.py index bb9664da..7052530e 100644 --- a/tests/test_formulas_sjmachin.py +++ b/tests/test_formulas_sjmachin.py @@ -18,7 +18,12 @@ def from_tests_dir(filename): try: ascii except NameError: - ascii = str + # For Python 2 + def ascii(s): + a = repr(s) + if a.startswith(('u"', "u'")): + a = a[1:] + return a book = xlrd.open_workbook(from_tests_dir('formula_test_sjmachin.xls')) sheet = book.sheet_by_index(0) From 0e8d13e995b8d14f355a21ebc9500ed44effe693 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 10 Mar 2012 19:01:52 +0000 Subject: [PATCH 009/319] Use unicode in tests with Python 2. --- tests/test_formats.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/tests/test_formats.py b/tests/test_formats.py index 5b66b1c7..39d6690d 100644 --- a/tests/test_formats.py +++ b/tests/test_formats.py @@ -12,6 +12,12 @@ import xlrd +if sys.version_info[0] >= 3: + def u(s): return s +else: + def u(s): + return s.decode('utf-8') + def from_tests_dir(filename): return os.path.join(os.path.dirname(os.path.abspath(__file__)), filename) @@ -19,15 +25,15 @@ def from_tests_dir(filename): class TestCellContent(unittest.TestCase): def test_text_cells(self): - sheet = book.sheet_by_name('Blätt1') - for row, name in enumerate(['Huber', 'Äcker', 'Öcker']): + sheet = book.sheet_by_name(u('Blätt1')) + for row, name in enumerate([u('Huber'), u('Äcker'), u('Öcker')]): cell = sheet.cell(row, 0) self.assertEqual(cell.ctype, xlrd.XL_CELL_TEXT) self.assertEqual(cell.value, name) self.assertTrue(cell.xf_index > 0) def test_date_cells(self): - sheet = book.sheet_by_name('Blätt1') + sheet = book.sheet_by_name(u('Blätt1')) # see also 'Dates in Excel spreadsheets' in the documentation # convert: xldate_as_tuple(float, book.datemode) -> (year, month, # day, hour, minutes, seconds) @@ -38,7 +44,7 @@ def test_date_cells(self): self.assertTrue(cell.xf_index > 0) def test_time_cells(self): - sheet = book.sheet_by_name('Blätt1') + sheet = book.sheet_by_name(u('Blätt1')) # see also 'Dates in Excel spreadsheets' in the documentation # convert: xldate_as_tuple(float, book.datemode) -> (year, month, # day, hour, minutes, seconds) @@ -49,7 +55,7 @@ def test_time_cells(self): self.assertTrue(cell.xf_index > 0) def test_percent_cells(self): - sheet = book.sheet_by_name('Blätt1') + sheet = book.sheet_by_name(u('Blätt1')) for row, time in [(6, .974), (7, .124)]: cell = sheet.cell(row, 1) self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) @@ -57,7 +63,7 @@ def test_percent_cells(self): self.assertTrue(cell.xf_index > 0) def test_currency_cells(self): - sheet = book.sheet_by_name('Blätt1') + sheet = book.sheet_by_name(u('Blätt1')) for row, time in [(8, 1000.30), (9, 1.20)]: cell = sheet.cell(row, 1) self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) @@ -65,14 +71,14 @@ def test_currency_cells(self): self.assertTrue(cell.xf_index > 0) def test_get_from_merged_cell(self): - sheet = book.sheet_by_name('ÖÄÜ') + sheet = book.sheet_by_name(u('ÖÄÜ')) cell = sheet.cell(2, 2) self.assertEqual(cell.ctype, xlrd.XL_CELL_TEXT) self.assertEqual(cell.value, 'MERGED CELLS') self.assertTrue(cell.xf_index > 0) def test_ignore_diagram(self): - sheet = book.sheet_by_name('Blätt3') + sheet = book.sheet_by_name(u('Blätt3')) cell = sheet.cell(0, 0) self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) self.assertEqual(cell.value, 100) From 8a76a1c0b38d828679783d985bd4fe3090959d07 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 10 Mar 2012 19:03:23 +0000 Subject: [PATCH 010/319] Add trove classifiers for Python 2 and 3 compatibility. --- setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.py b/setup.py index 8c68fb55..76d7ee5b 100644 --- a/setup.py +++ b/setup.py @@ -53,6 +53,8 @@ def mkargs(**kwargs): 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3', 'Operating System :: OS Independent', 'Topic :: Database', 'Topic :: Office/Business', From bd9c2e3643623d669da157f07850a85b8c7fb2d3 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Tue, 27 Mar 2012 13:56:58 +0100 Subject: [PATCH 011/319] Some more fixes for bytes literals --- xlrd/sheet.py | 16 ++++++++-------- xlrd/timemachine.py | 5 ++++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/xlrd/sheet.py b/xlrd/sheet.py index 5b81079f..e8521fd6 100644 --- a/xlrd/sheet.py +++ b/xlrd/sheet.py @@ -1024,7 +1024,7 @@ def read(self, bk): elif rc == XL_GCW: if not fmt_info: continue # useless w/o COLINFO assert data_len == 34 - assert data[0:2] == "\x20\x00" + assert data[0:2] == b("\x20\x00") iguff = unpack("<8i", data[2:34]) gcw = [] for bits in iguff: @@ -1459,7 +1459,7 @@ def read(self, bk): attr_names = ("show_formulas", "show_grid_lines", "show_sheet_headers", "panes_are_frozen", "show_zero_values") for attr, char in zip(attr_names, data[0:5]): - setattr(self, attr, int(char != "\x00")) + setattr(self, attr, int(char != byte_0)) (self.first_visible_rowx, self.first_visible_colx, self.automatic_grid_line_colour, ) = unpack("> self.logfile, "options: %08X" % options offset = 32 @@ -1731,7 +1731,7 @@ def get_nul_terminated_unicode(buf, ofs): clsid, = unpack('<16s', data[offset:offset + 16]) if DEBUG: print >> self.logfile, "clsid=%r" %clsid offset += 16 - if clsid == "\xE0\xC9\xEA\x79\xF9\xBA\xCE\x11\x8C\x82\x00\xAA\x00\x4B\xA9\x0B": + if clsid == b("\xE0\xC9\xEA\x79\xF9\xBA\xCE\x11\x8C\x82\x00\xAA\x00\x4B\xA9\x0B"): # E0H C9H EAH 79H F9H BAH CEH 11H 8CH 82H 00H AAH 00H 4BH A9H 0BH # URL Moniker h.type = u'url' @@ -1751,7 +1751,7 @@ def get_nul_terminated_unicode(buf, ofs): if DEBUG: print >> self.logfile, "extra=%r" % extra_data if DEBUG: print >> self.logfile, "nbytes=%d true_nbytes=%d extra_nbytes=%d" % (nbytes, true_nbytes, extra_nbytes) assert extra_nbytes in (24, 0) - elif clsid == "\x03\x03\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46": + elif clsid == b("\x03\x03\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46"): # file moniker h.type = u'local file' uplevels, nbytes = unpack("= (3,): # Python 3 def b(s): - return s.encode('cp1252') + return s.encode('latin1') def get_int_1byte(data, pos): return data[pos] @@ -111,3 +111,6 @@ def b(s): return s def get_int_1byte(data, pos): return ord(data[pos]) + +byte_0 = b('\x00') +byte_empty = b('') From cbd17a2d686744a503c6df51ab87cef8efbec766 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Tue, 27 Mar 2012 14:29:12 +0100 Subject: [PATCH 012/319] More use of byte_0 and bytes_empty. --- xlrd/biffh.py | 4 ++-- xlrd/compdoc.py | 4 ++-- xlrd/formatting.py | 2 +- xlrd/sheet.py | 2 +- xlrd/timemachine.py | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/xlrd/biffh.py b/xlrd/biffh.py index aa276364..c05ec1dd 100644 --- a/xlrd/biffh.py +++ b/xlrd/biffh.py @@ -582,7 +582,7 @@ def biff_dump(mem, stream_offset, stream_len, base=0, fout=sys.stdout, unnumbere while stream_end - pos >= 4: rc, length = unpack('= 4: rc, length = unpack('> self.logfile, "_get_stream(%s): seen" % name; dump_list(self.seen, 20, self.logfile) - return b('').join(sectors) + return bytes_empty.join(sectors) def _dir_search(self, path, storage_DID=0): # Return matching DirNode instance, or None @@ -446,7 +446,7 @@ def _locate_stream(self, mem, base, sat, sec_size, start_sid, expected_stream_si return (mem, start_pos, expected_stream_size) slices.append((start_pos, end_pos)) # print >> self.logfile, "+++>>> %d fragments" % len(slices) - return (''.join([mem[start_pos:end_pos] for start_pos, end_pos in slices]), 0, expected_stream_size) + return (bytes_empty.join([mem[start_pos:end_pos] for start_pos, end_pos in slices]), 0, expected_stream_size) # ========================================================================================== def x_dump_line(alist, stride, f, dpos, equal=0): diff --git a/xlrd/formatting.py b/xlrd/formatting.py index 322aa490..eea21e9b 100644 --- a/xlrd/formatting.py +++ b/xlrd/formatting.py @@ -629,7 +629,7 @@ def handle_style(book, data): bv = book.biff_version flag_and_xfx, built_in_id, level = unpack(' Date: Tue, 27 Mar 2012 14:32:54 +0100 Subject: [PATCH 013/319] bytes fixes in hex_char_dump() --- xlrd/biffh.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/xlrd/biffh.py b/xlrd/biffh.py index c05ec1dd..c5c759e2 100644 --- a/xlrd/biffh.py +++ b/xlrd/biffh.py @@ -559,9 +559,15 @@ def hex_char_dump(strg, ofs, dlen, base=0, fout=sys.stdout, unnumbered=False): '??? hex_char_dump: ofs=%d dlen=%d base=%d -> endpos=%d pos=%d endsub=%d substrg=%r\n', ofs, dlen, base, endpos, pos, endsub, substrg) break - hexd = ''.join(["%02x " % ord(c) for c in substrg]) + if PY3: + hexd = ''.join(["%02x " % c for c in substrg]) + else: + hexd = ''.join(["%02x " % ord(c) for c in substrg]) + chard = '' for c in substrg: + if PY3: + c = chr(c) if c == '\0': c = '~' elif not (' ' <= c <= '~'): @@ -569,6 +575,7 @@ def hex_char_dump(strg, ofs, dlen, base=0, fout=sys.stdout, unnumbered=False): chard += c if numbered: num_prefix = "%5d: " % (base+pos-ofs) + fprintf(fout, "%s %-48s %s\n", num_prefix, hexd, chard) pos = endsub From 65f61fe9eccf13805498b10a51f89ce18e8362fa Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Tue, 3 Apr 2012 00:01:50 +0100 Subject: [PATCH 014/319] Use get_int_1byte in more places. --- xlrd/formula.py | 6 +++--- xlrd/sheet.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/xlrd/formula.py b/xlrd/formula.py index 4197b308..17e72695 100644 --- a/xlrd/formula.py +++ b/xlrd/formula.py @@ -1423,7 +1423,7 @@ def unexpected_opcode(op_arg, oname_arg): stack = [unk_opnd] while 0 <= pos < fmlalen: - op = ord(data[pos]) + op = get_int_1byte(data, pos) opcode = op & 0x1f optype = (op & 0x60) >> 5 if optype: @@ -1903,7 +1903,7 @@ def dump_formula(bk, data, fmlalen, bv, reldelta, blah=0, isname=0): any_err = 0 spush = stack.append while 0 <= pos < fmlalen: - op = ord(data[pos]) + op = get_int_1byte(data, pos) opcode = op & 0x1f optype = (op & 0x60) >> 5 if optype: @@ -1958,7 +1958,7 @@ def dump_formula(bk, data, fmlalen, bv, reldelta, blah=0, isname=0): if blah: print >> bk.logfile, " subop=%02xh subname=t%s sz=%d nc=%02xh" % (subop, subname, sz, nc) elif opcode == 0x17: # tStr if bv <= 70: - nc = ord(data[pos+1]) + nc = get_int_1byte(data, pos+1) strg = data[pos+2:pos+2+nc] # left in 8-bit encoding sz = nc + 2 else: diff --git a/xlrd/sheet.py b/xlrd/sheet.py index 794108cc..338db795 100644 --- a/xlrd/sheet.py +++ b/xlrd/sheet.py @@ -806,7 +806,7 @@ def read(self, bk): rowx, colx, xf_index = local_unpack(' Date: Tue, 3 Apr 2012 00:09:46 +0100 Subject: [PATCH 015/319] b() -> BYTES_LITERAL() --- xlrd/compdoc.py | 4 ++-- xlrd/formatting.py | 2 +- xlrd/sheet.py | 18 +++++++++--------- xlrd/timemachine.py | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/xlrd/compdoc.py b/xlrd/compdoc.py index 4c58ef85..e96cef94 100644 --- a/xlrd/compdoc.py +++ b/xlrd/compdoc.py @@ -23,7 +23,7 @@ ## # Magic cookie that should appear in the first 8 bytes of the file. -SIGNATURE = b("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1") +SIGNATURE = BYTES_LITERAL("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1") EOCSID = -2 FREESID = -1 @@ -84,7 +84,7 @@ def __init__(self, mem, logfile=sys.stdout, DEBUG=0): self.DEBUG = DEBUG if mem[0:8] != SIGNATURE: raise CompDocError('Not an OLE2 compound document') - if mem[28:30] != b('\xFE\xFF'): + if mem[28:30] != BYTES_LITERAL('\xFE\xFF'): raise CompDocError('Expected "little-endian" marker, found %r' % mem[28:30]) revision, version = unpack('> self.logfile, "options: %08X" % options offset = 32 @@ -1731,7 +1731,7 @@ def get_nul_terminated_unicode(buf, ofs): clsid, = unpack('<16s', data[offset:offset + 16]) if DEBUG: print >> self.logfile, "clsid=%r" %clsid offset += 16 - if clsid == b("\xE0\xC9\xEA\x79\xF9\xBA\xCE\x11\x8C\x82\x00\xAA\x00\x4B\xA9\x0B"): + if clsid == BYTES_LITERAL("\xE0\xC9\xEA\x79\xF9\xBA\xCE\x11\x8C\x82\x00\xAA\x00\x4B\xA9\x0B"): # E0H C9H EAH 79H F9H BAH CEH 11H 8CH 82H 00H AAH 00H 4BH A9H 0BH # URL Moniker h.type = u'url' @@ -1751,7 +1751,7 @@ def get_nul_terminated_unicode(buf, ofs): if DEBUG: print >> self.logfile, "extra=%r" % extra_data if DEBUG: print >> self.logfile, "nbytes=%d true_nbytes=%d extra_nbytes=%d" % (nbytes, true_nbytes, extra_nbytes) assert extra_nbytes in (24, 0) - elif clsid == b("\x03\x03\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46"): + elif clsid == BYTES_LITERAL("\x03\x03\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46"): # file moniker h.type = u'local file' uplevels, nbytes = unpack("= (3,): # Python 3 - def b(s): + def BYTES_LITERAL(s): return s.encode('latin1') def get_int_1byte(data, pos): @@ -107,10 +107,10 @@ def get_int_1byte(data, pos): else: # Python 2 - def b(s): return s + def BYTES_LITERAL(s): return s def get_int_1byte(data, pos): return ord(data[pos]) -byte_0 = b('\x00') -bytes_empty = b('') +byte_0 = BYTES_LITERAL('\x00') +bytes_empty = BYTES_LITERAL('') From 8c84fda3033086aa0119488646f7e20a90fb8e39 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Wed, 4 Apr 2012 11:32:03 +0100 Subject: [PATCH 016/319] Remove non-corresponding xfcell tests. --- tests/run_tests.py | 1 - tests/test_xfcell.py | 159 ------------------------------------------- 2 files changed, 160 deletions(-) delete mode 100644 tests/test_xfcell.py diff --git a/tests/run_tests.py b/tests/run_tests.py index 0993b8db..0ac1cc68 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -7,7 +7,6 @@ from test_formulas_sjmachin import * from test_sheet import * from test_workbook import * -#from test_xfcell import * # Not currently working from test_xldate import * if __name__ == "__main__": diff --git a/tests/test_xfcell.py b/tests/test_xfcell.py deleted file mode 100644 index 234aabe8..00000000 --- a/tests/test_xfcell.py +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Author: mozman -# Purpose: test cell functions -# Created: 03.12.2010 -# Copyright (C) 2010, Manfred Moitzi -# License: GPLv3 - -import sys -import os -import unittest -from datetime import datetime, date, time - -import xlrd -from xlrd import xfconst - -def from_tests_dir(filename): - return os.path.join(os.path.dirname(os.path.abspath(__file__)), filename) - -book = xlrd.open_workbook(from_tests_dir('profiles.xls'), - formatting_info=True) -sheet = book.sheet_by_name('PROFILEDEF') - -class TestCellValues(unittest.TestCase): - def test_string_cell(self): - cell = sheet.cell(0, 0) - self.assertEqual(cell.ctype, xlrd.XL_CELL_TEXT) - self.assertEqual(cell.value, 'PROFIL') - self.assertTrue(cell.has_xf) - - def test_number_cell(self): - cell = sheet.cell(1, 1) - self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) - self.assertEqual(cell.value, 100) - self.assertTrue(cell.has_xf) - - def test_calculated_cell(self): - sheet2 = book.sheet_by_name('PROFILELEVELS') - cell = sheet2.cell(1, 3) - self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) - self.assertAlmostEqual(cell.value, 265.131, places=3) - self.assertTrue(cell.has_xf) - - def test_date(self): - book = xlrd.open_workbook(from_tests_dir('Formate.xls'), - formatting_info=True) - sheet = book.sheet_by_name('Blätt1') - for row, y, m, d in [(0, 1907, 7, 3), (1, 2005, 2, 23), (2, 1988, 5, 3)]: - cell = sheet.cell(row, 1) - self.assertEqual(cell.date(), date(y, m, d)) - - def test_time(self): - book = xlrd.open_workbook(from_tests_dir('Formate.xls'), - formatting_info=True) - sheet = book.sheet_by_name('Blätt1') - for row, h, m, s in [(3, 6, 34, 0), (4, 12, 56, 0), (5, 17, 47, 13)]: - cell = sheet.cell(row, 1) - self.assertEqual(cell.time(), time(h, m, s)) - -xf_book = xlrd.open_workbook(from_tests_dir('xf_class.xls'), - formatting_info=True) - -class TestXFCellProperties(unittest.TestCase): - sheet = xf_book.sheet_by_name('table1') - - def cell(self, row, col): - return self.sheet.cell(row, col) - - def test_red_background_color(self): - # bgcolor should be 'red' #ff0000, but is not! (also xlrd 0.7.1) - # but pattern_color is 'red' - self.assertEqual(self.cell(0, 0).background_color(), (153, 51, 0)) - self.assertEqual(self.cell(0, 0).pattern_color(), (255, 0, 0)) - self.assertEqual(self.cell(0, 0).fill_pattern(), 1) - - def test_green_background_color(self): - # bgcolor should be 'green' #008000, but is not! (also xlrd 0.7.1) - # but pattern_color is 'green' - self.assertEqual(self.cell(1, 0).background_color(), (0, 128, 128)) - self.assertEqual(self.cell(1, 0).pattern_color(), (0, 128, 0)) - self.assertEqual(self.cell(1, 0).fill_pattern(), 1) - - def test_blue_background_color(self): - # bgcolor should be 'green' #0000ff, but is not! (also xlrd 0.7.1) - # and pattern_color is 'blue' - self.assertEqual(self.cell(2, 0).background_color(), (0, 128, 128)) - self.assertEqual(self.cell(2, 0).pattern_color(), (0, 102, 204)) - self.assertEqual(self.cell(2, 0).fill_pattern(), 1) - - def test_font_color(self): - self.assertEqual(self.cell(0, 1).font_color(), (255, 0, 0)) - - def test_format_str(self): - self.assertEqual(self.cell(0, 0).format_str().upper(), "GENERAL") - - def test_horiz_alignment(self): - self.assertEqual(self.cell(3, 0).alignment.hor_align, xfconst.HOR_ALIGN_LEFT) - self.assertEqual(self.cell(3, 1).alignment.hor_align, xfconst.HOR_ALIGN_CENTRED) - self.assertEqual(self.cell(3, 2).alignment.hor_align, xfconst.HOR_ALIGN_RIGHT) - - def test_vert_alignment(self): - self.assertEqual(self.cell(4, 0).alignment.vert_align, xfconst.VERT_ALIGN_TOP) - self.assertEqual(self.cell(4, 1).alignment.vert_align, xfconst.VERT_ALIGN_CENTRED) - self.assertEqual(self.cell(4, 2).alignment.vert_align, xfconst.VERT_ALIGN_BOTTOM) - - def test_other_alignment(self): - self.assertEqual(self.cell(4, 0).alignment.rotation, 0) - self.assertEqual(self.cell(4, 0).alignment.text_wrapped, 0) - self.assertEqual(self.cell(4, 0).alignment.indent_level, 0) - self.assertEqual(self.cell(4, 0).alignment.shrink_to_fit, 0) - self.assertEqual(self.cell(4, 0).alignment.text_direction, 0) - - def test_borderstyles(self): - cell = self.cell(9, 0) - self.assertEqual(cell.value, 'borderstyle') - styles = cell.borderstyles() - self.assertEqual(styles['left'], xfconst.LS_THIN) - self.assertEqual(styles['right'], xfconst.LS_THIN) - self.assertEqual(styles['top'], xfconst.LS_MEDIUM) - self.assertEqual(styles['bottom'], xfconst.LS_MEDIUM) - self.assertEqual(styles['diag'], xfconst.LS_THIN) - - def test_bordercolors(self): - cell = self.cell(9, 0) - self.assertEqual(cell.value, 'borderstyle') - colors = cell.bordercolors() - self.assertEqual(colors['left'], (0, 128, 0)) - self.assertEqual(colors['right'], (0, 128, 0)) - self.assertEqual(colors['top'], (255, 0, 0)) - self.assertEqual(colors['bottom'], (255, 0, 0)) - self.assertEqual(colors['diag'], None) # None is default color ??? - - def test_diagline(self): - cell = self.cell(9, 0) - self.assertEqual(cell.value, 'borderstyle') - self.assertTrue(cell.has_up_diag) - self.assertTrue(cell.has_down_diag) - - def test_protection(self): - cell = self.cell(0, 0) - # 'cell_locked' and 'formula_hidden' but only if sheet is protected - self.assertTrue(cell.is_cell_locked) - self.assertTrue(cell.is_formula_hidden) - - def test_repr_with_formatting_info(self): - cell = self.cell(0, 0) - self.assertEqual(repr(cell), "text:'RED' (XF:62)") - self.assertNotEqual(cell.xf_index, None) - - def test_repr_without_formatting_info(self): - book = xlrd.open_workbook(from_tests_dir('xf_class.xls'), - formatting_info=False) - sheet = book.sheet_by_name('table1') - cell = sheet.cell(0, 0) - self.assertEqual(repr(cell), "text:'RED'") - self.assertEqual(cell.xf_index, None) - -if __name__=='__main__': - unittest.main() From 7120b920291b64f15ea91acf47524180d112db4f Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 13 Apr 2012 21:34:27 +0100 Subject: [PATCH 017/319] Update tests to new package structure. --- tests/test_cell.py | 6 +++--- tests/test_formats.py | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/test_cell.py b/tests/test_cell.py index af2738d8..9f5c06ba 100644 --- a/tests/test_cell.py +++ b/tests/test_cell.py @@ -20,20 +20,20 @@ def from_tests_dir(filename): class TestCell(unittest.TestCase): def test_string_cell(self): cell = sheet.cell(0, 0) - self.assertEqual(cell.ctype, xlrd.XL_CELL_TEXT) + self.assertEqual(cell.ctype, xlrd.book.XL_CELL_TEXT) self.assertEqual(cell.value, 'PROFIL') self.assertTrue(cell.xf_index > 0) def test_number_cell(self): cell = sheet.cell(1, 1) - self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) + self.assertEqual(cell.ctype, xlrd.book.XL_CELL_NUMBER) self.assertEqual(cell.value, 100) self.assertTrue(cell.xf_index > 0) def test_calculated_cell(self): sheet2 = book.sheet_by_name('PROFILELEVELS') cell = sheet2.cell(1, 3) - self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) + self.assertEqual(cell.ctype, xlrd.book.XL_CELL_NUMBER) self.assertAlmostEqual(cell.value, 265.131, places=3) self.assertTrue(cell.xf_index > 0) diff --git a/tests/test_formats.py b/tests/test_formats.py index 39d6690d..185e7bbd 100644 --- a/tests/test_formats.py +++ b/tests/test_formats.py @@ -28,7 +28,7 @@ def test_text_cells(self): sheet = book.sheet_by_name(u('Blätt1')) for row, name in enumerate([u('Huber'), u('Äcker'), u('Öcker')]): cell = sheet.cell(row, 0) - self.assertEqual(cell.ctype, xlrd.XL_CELL_TEXT) + self.assertEqual(cell.ctype, xlrd.book.XL_CELL_TEXT) self.assertEqual(cell.value, name) self.assertTrue(cell.xf_index > 0) @@ -39,7 +39,7 @@ def test_date_cells(self): # day, hour, minutes, seconds) for row, date in [(0, 2741.), (1, 38406.), (2, 32266.)]: cell = sheet.cell(row, 1) - self.assertEqual(cell.ctype, xlrd.XL_CELL_DATE) + self.assertEqual(cell.ctype, xlrd.book.XL_CELL_DATE) self.assertEqual(cell.value, date) self.assertTrue(cell.xf_index > 0) @@ -50,7 +50,7 @@ def test_time_cells(self): # day, hour, minutes, seconds) for row, time in [(3, .273611), (4, .538889), (5, .741123)]: cell = sheet.cell(row, 1) - self.assertEqual(cell.ctype, xlrd.XL_CELL_DATE) + self.assertEqual(cell.ctype, xlrd.book.XL_CELL_DATE) self.assertAlmostEqual(cell.value, time, places=6) self.assertTrue(cell.xf_index > 0) @@ -58,7 +58,7 @@ def test_percent_cells(self): sheet = book.sheet_by_name(u('Blätt1')) for row, time in [(6, .974), (7, .124)]: cell = sheet.cell(row, 1) - self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) + self.assertEqual(cell.ctype, xlrd.book.XL_CELL_NUMBER) self.assertAlmostEqual(cell.value, time, places=3) self.assertTrue(cell.xf_index > 0) @@ -66,21 +66,21 @@ def test_currency_cells(self): sheet = book.sheet_by_name(u('Blätt1')) for row, time in [(8, 1000.30), (9, 1.20)]: cell = sheet.cell(row, 1) - self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) + self.assertEqual(cell.ctype, xlrd.book.XL_CELL_NUMBER) self.assertAlmostEqual(cell.value, time, places=2) self.assertTrue(cell.xf_index > 0) def test_get_from_merged_cell(self): sheet = book.sheet_by_name(u('ÖÄÜ')) cell = sheet.cell(2, 2) - self.assertEqual(cell.ctype, xlrd.XL_CELL_TEXT) + self.assertEqual(cell.ctype, xlrd.book.XL_CELL_TEXT) self.assertEqual(cell.value, 'MERGED CELLS') self.assertTrue(cell.xf_index > 0) def test_ignore_diagram(self): sheet = book.sheet_by_name(u('Blätt3')) cell = sheet.cell(0, 0) - self.assertEqual(cell.ctype, xlrd.XL_CELL_NUMBER) + self.assertEqual(cell.ctype, xlrd.book.XL_CELL_NUMBER) self.assertEqual(cell.value, 100) self.assertTrue(cell.xf_index > 0) From b43619ef43754cf95fdaf83854f4b3700ed1a2f0 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 13 Apr 2012 21:46:43 +0100 Subject: [PATCH 018/319] Use sjmachin's Python 3 compatibility functions. --- xlrd/biffh.py | 8 ++++---- xlrd/compdoc.py | 4 ++-- xlrd/formula.py | 8 ++++---- xlrd/sheet.py | 22 +++++++++++----------- xlrd/timemachine.py | 18 ------------------ 5 files changed, 21 insertions(+), 39 deletions(-) diff --git a/xlrd/biffh.py b/xlrd/biffh.py index c5c759e2..b68febae 100644 --- a/xlrd/biffh.py +++ b/xlrd/biffh.py @@ -292,7 +292,7 @@ def unpack_unicode(data, pos, lenlen=2): # Avoid crash if missing. return u"" pos += lenlen - options = get_int_1byte(data, pos) + options = BYTES_ORD(data[pos]) pos += 1 # phonetic = options & 0x04 # richtext = options & 0x08 @@ -334,7 +334,7 @@ def unpack_unicode_update_pos(data, pos, lenlen=2, known_len=None): if not nchars and not data[pos:]: # Zero-length string with no options byte return (u"", pos) - options = get_int_1byte(data, pos) + options = BYTES_ORD(data[pos]) pos += 1 phonetic = options & 0x04 richtext = options & 0x08 @@ -589,7 +589,7 @@ def biff_dump(mem, stream_offset, stream_len, base=0, fout=sys.stdout, unnumbere while stream_end - pos >= 4: rc, length = unpack('= 4: rc, length = unpack('> self.logfile, "_get_stream(%s): seen" % name; dump_list(self.seen, 20, self.logfile) - return bytes_empty.join(sectors) + return BYTES_NULL.join(sectors) def _dir_search(self, path, storage_DID=0): # Return matching DirNode instance, or None @@ -446,7 +446,7 @@ def _locate_stream(self, mem, base, sat, sec_size, start_sid, expected_stream_si return (mem, start_pos, expected_stream_size) slices.append((start_pos, end_pos)) # print >> self.logfile, "+++>>> %d fragments" % len(slices) - return (bytes_empty.join([mem[start_pos:end_pos] for start_pos, end_pos in slices]), 0, expected_stream_size) + return (BYTES_NULL.join([mem[start_pos:end_pos] for start_pos, end_pos in slices]), 0, expected_stream_size) # ========================================================================================== def x_dump_line(alist, stride, f, dpos, equal=0): diff --git a/xlrd/formula.py b/xlrd/formula.py index 17e72695..b9a0961c 100644 --- a/xlrd/formula.py +++ b/xlrd/formula.py @@ -826,7 +826,7 @@ def not_in_name_formula(op_arg, oname_arg): stack = [unk_opnd] while 0 <= pos < fmlalen: - op = get_int_1byte(data, pos) + op = BYTES_ORD(data[pos]) opcode = op & 0x1f optype = (op & 0x60) >> 5 if optype: @@ -1423,7 +1423,7 @@ def unexpected_opcode(op_arg, oname_arg): stack = [unk_opnd] while 0 <= pos < fmlalen: - op = get_int_1byte(data, pos) + op = BYTES_ORD(data[pos]) opcode = op & 0x1f optype = (op & 0x60) >> 5 if optype: @@ -1903,7 +1903,7 @@ def dump_formula(bk, data, fmlalen, bv, reldelta, blah=0, isname=0): any_err = 0 spush = stack.append while 0 <= pos < fmlalen: - op = get_int_1byte(data, pos) + op = BYTES_ORD(data[pos]) opcode = op & 0x1f optype = (op & 0x60) >> 5 if optype: @@ -1958,7 +1958,7 @@ def dump_formula(bk, data, fmlalen, bv, reldelta, blah=0, isname=0): if blah: print >> bk.logfile, " subop=%02xh subname=t%s sz=%d nc=%02xh" % (subop, subname, sz, nc) elif opcode == 0x17: # tStr if bv <= 70: - nc = get_int_1byte(data, pos+1) + nc = BYTES_ORD(data[pos+1]) strg = data[pos+2:pos+2+nc] # left in 8-bit encoding sz = nc + 2 else: diff --git a/xlrd/sheet.py b/xlrd/sheet.py index 4c99374c..99aa449b 100644 --- a/xlrd/sheet.py +++ b/xlrd/sheet.py @@ -806,7 +806,7 @@ def read(self, bk): rowx, colx, xf_index = local_unpack('= 80: - flag = get_int_1byte(data, offset) & 1 + flag = BYTES_ORD(data[offset]) & 1 enc = ("latin_1", "utf_16_le")[flag] offset += 1 chunk = unicode(data[offset:], enc) @@ -1560,7 +1560,7 @@ def fixed_BIFF2_xfindex(self, cell_attr, rowx, colx, true_xfx=None): if true_xfx is not None: xfx = true_xfx else: - xfx = get_int_1byte(cell_attr, 0) & 0x3F + xfx = BYTES_ORD(cell_attr[0]) & 0x3F if xfx == 0x3F: if self._ixfe is None: raise XLRDError("BIFF2 cell record has XF index 63 but no preceding IXFE record.") @@ -1573,7 +1573,7 @@ def fixed_BIFF2_xfindex(self, cell_attr, rowx, colx, true_xfx=None): # Have either Excel 2.0, or broken 2.1 w/o XF records -- same effect. self.biff_version = self.book.biff_version = 20 #### check that XF slot in cell_attr is zero - xfx_slot = get_int_1byte(cell_attr, 0) & 0x3F + xfx_slot = BYTES_ORD(cell_attr[0]) & 0x3F assert xfx_slot == 0 xfx = self._cell_attr_to_xfx.get(cell_attr) if xfx is not None: @@ -1923,7 +1923,7 @@ def handle_note(self, data, txos): expected_bytes -= nb assert expected_bytes == 0 enc = self.book.encoding or self.book.derive_encoding() - o.text = unicode(bytes_empty.join(pieces), enc) + o.text = unicode(BYTES_NULL.join(pieces), enc) o.rich_text_runlist = [(0, 0)] o.show = 0 o.row_hidden = 0 @@ -1975,7 +1975,7 @@ def handle_txo(self, data): assert rc2 == XL_CONTINUE if OBJ_MSO_DEBUG: hex_char_dump(data2, 0, data2_len, base=0, fout=self.logfile) - nb = get_int_1byte(data2, 0) # 0 means latin1, 1 means utf_16_le + nb = BYTES_ORD(data2[0]) # 0 means latin1, 1 means utf_16_le nchars = data2_len - 1 if nb: assert nchars % 2 == 0 @@ -2143,7 +2143,7 @@ class Hyperlink(BaseObject): # === helpers === def unpack_RK(rk_str): - flags = get_int_1byte(rk_str, 0) + flags = BYTES_ORD(rk_str[0]) if flags & 2: # There's a SIGNED 30-bit integer in there! i, = unpack('= (3,): - # Python 3 - def BYTES_LITERAL(s): - return s.encode('latin1') - - def get_int_1byte(data, pos): - return data[pos] - -else: - # Python 2 - def BYTES_LITERAL(s): return s - - def get_int_1byte(data, pos): - return ord(data[pos]) - -byte_0 = BYTES_LITERAL('\x00') -bytes_empty = BYTES_LITERAL('') From aa58c594ebd353077300d1cd56f3705cbb81e265 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 26 Oct 2012 13:54:54 +0100 Subject: [PATCH 019/319] Fix relative imports --- xlrd/__init__.py | 16 ++++++++-------- xlrd/biffh.py | 2 +- xlrd/book.py | 10 +++++----- xlrd/compdoc.py | 2 +- xlrd/formatting.py | 6 +++--- xlrd/formula.py | 4 ++-- xlrd/sheet.py | 8 ++++---- xlrd/xldate.py | 2 +- xlrd/xlsx.py | 10 +++++----- 9 files changed, 30 insertions(+), 30 deletions(-) diff --git a/xlrd/__init__.py b/xlrd/__init__.py index 32d70958..d9ea0284 100644 --- a/xlrd/__init__.py +++ b/xlrd/__init__.py @@ -1,12 +1,12 @@ from os import path -from info import __VERSION__ +from .info import __VERSION__ #

Copyright (c) 2005-2012 Stephen John Machin, Lingfo Pty Ltd

#

This module is part of the xlrd package, which is released under a # BSD-style licence.

-import licences +from . import licences ## #

A Python module for extracting data from MS Excel (TM) spreadsheet files. @@ -304,8 +304,8 @@ ## import sys, zipfile, pprint -import timemachine -from biffh import ( +from . import timemachine +from .biffh import ( XLRDError, biff_text_from_num, error_text_from_code, @@ -317,10 +317,10 @@ XL_CELL_DATE, XL_CELL_NUMBER ) -from formula import * # is constrained by __all__ -from book import Book, colname #### TODO #### formula also has `colname` (restricted to 256 cols) -from sheet import empty_cell -from xldate import XLDateError, xldate_as_tuple +from .formula import * # is constrained by __all__ +from .book import Book, colname #### TODO #### formula also has `colname` (restricted to 256 cols) +from .sheet import empty_cell +from .xldate import XLDateError, xldate_as_tuple if sys.version.startswith("IronPython"): # print >> sys.stderr, "...importing encodings" diff --git a/xlrd/biffh.py b/xlrd/biffh.py index b68febae..bd458cb0 100644 --- a/xlrd/biffh.py +++ b/xlrd/biffh.py @@ -20,7 +20,7 @@ from struct import unpack import sys -from timemachine import * +from .timemachine import * class XLRDError(Exception): pass diff --git a/xlrd/book.py b/xlrd/book.py index 214159ec..c79117ab 100644 --- a/xlrd/book.py +++ b/xlrd/book.py @@ -4,16 +4,16 @@ #

This module is part of the xlrd package, which is released under a # BSD-style licence.

-from timemachine import * -from biffh import * +from .timemachine import * +from .biffh import * import struct; unpack = struct.unpack import sys import time import sheet import compdoc -from xldate import xldate_as_tuple, XLDateError -from formula import * -import formatting +from .xldate import xldate_as_tuple, XLDateError +from .formula import * +from . import formatting if sys.version.startswith("IronPython"): # print >> sys.stderr, "...importing encodings" import encodings diff --git a/xlrd/compdoc.py b/xlrd/compdoc.py index 5f3a8fcc..76405fb7 100644 --- a/xlrd/compdoc.py +++ b/xlrd/compdoc.py @@ -18,7 +18,7 @@ from __future__ import nested_scopes import sys from struct import unpack -from timemachine import * +from .timemachine import * import array ## diff --git a/xlrd/formatting.py b/xlrd/formatting.py index 91427eb7..e91b54b2 100644 --- a/xlrd/formatting.py +++ b/xlrd/formatting.py @@ -24,13 +24,13 @@ DEBUG = 0 import copy, re -from timemachine import * -from biffh import BaseObject, unpack_unicode, unpack_string, \ +from struct import unpack +from .timemachine import * +from .biffh import BaseObject, unpack_unicode, unpack_string, \ upkbits, upkbitsL, fprintf, \ FUN, FDT, FNU, FGE, FTX, XL_CELL_NUMBER, XL_CELL_DATE, \ XL_FORMAT, XL_FORMAT2, \ XLRDError -from struct import unpack excel_default_palette_b5 = ( ( 0, 0, 0), (255, 255, 255), (255, 0, 0), ( 0, 255, 0), diff --git a/xlrd/formula.py b/xlrd/formula.py index b9a0961c..122729d9 100644 --- a/xlrd/formula.py +++ b/xlrd/formula.py @@ -13,8 +13,8 @@ from __future__ import nested_scopes import copy from struct import unpack -from timemachine import * -from biffh import unpack_unicode_update_pos, unpack_string_update_pos, \ +from .timemachine import * +from .biffh import unpack_unicode_update_pos, unpack_string_update_pos, \ XLRDError, hex_char_dump, error_text_from_code, BaseObject __all__ = [ diff --git a/xlrd/sheet.py b/xlrd/sheet.py index 99aa449b..47c5560f 100644 --- a/xlrd/sheet.py +++ b/xlrd/sheet.py @@ -27,12 +27,12 @@ # 2007-07-11 SJM Allow for BIFF2/3-style FORMAT record in BIFF4/8 file # 2007-04-22 SJM Remove experimental "trimming" facility. -from biffh import * -from timemachine import * from struct import unpack, calcsize -from formula import dump_formula, decompile_formula, rangename2d, FMLA_TYPE_CELL, FMLA_TYPE_SHARED -from formatting import nearest_colour_index, Format import time +from .biffh import * +from .timemachine import * +from .formula import dump_formula, decompile_formula, rangename2d, FMLA_TYPE_CELL, FMLA_TYPE_SHARED +from .formatting import nearest_colour_index, Format DEBUG = 0 OBJ_MSO_DEBUG = 0 diff --git a/xlrd/xldate.py b/xlrd/xldate.py index e5f75916..2c316be8 100644 --- a/xlrd/xldate.py +++ b/xlrd/xldate.py @@ -18,7 +18,7 @@ # Noon on Gregorian 1900-03-01 (day 61 in the 1900-based system) is JDN 2415080.0 # Noon on Gregorian 1904-01-02 (day 1 in the 1904-based system) is JDN 2416482.0 -from timemachine import int_floor_div as ifd +from .timemachine import int_floor_div as ifd _JDN_delta = (2415080 - 61, 2416482 - 1) assert _JDN_delta[1] - _JDN_delta[0] == 1462 diff --git a/xlrd/xlsx.py b/xlrd/xlsx.py index 25fe1f50..5a3f488f 100644 --- a/xlrd/xlsx.py +++ b/xlrd/xlsx.py @@ -9,11 +9,11 @@ import sys, zipfile, pprint import re -from timemachine import * -from book import Book, Name -from biffh import error_text_from_code, XLRDError, XL_CELL_BLANK, XL_CELL_TEXT, XL_CELL_BOOLEAN, XL_CELL_ERROR -from formatting import is_date_format_string, Format, XF -from sheet import Sheet +from .timemachine import * +from .book import Book, Name +from .biffh import error_text_from_code, XLRDError, XL_CELL_BLANK, XL_CELL_TEXT, XL_CELL_BOOLEAN, XL_CELL_ERROR +from .formatting import is_date_format_string, Format, XF +from .sheet import Sheet DLF = sys.stdout # Default Log File From 00e53268f068b5bcadb29bfcaf71a9b6c2cc5fab Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 26 Oct 2012 14:15:19 +0100 Subject: [PATCH 020/319] Syntax fixes for Python 3 --- xlrd/biffh.py | 4 ++-- xlrd/book.py | 48 +++++++++++++++++++++++---------------------- xlrd/formula.py | 8 ++++++-- xlrd/sheet.py | 28 ++++++++++++++------------ xlrd/timemachine.py | 2 ++ 5 files changed, 50 insertions(+), 40 deletions(-) diff --git a/xlrd/biffh.py b/xlrd/biffh.py index bd458cb0..0ccd5ea3 100644 --- a/xlrd/biffh.py +++ b/xlrd/biffh.py @@ -290,7 +290,7 @@ def unpack_unicode(data, pos, lenlen=2): if not nchars: # Ambiguous whether 0-length string should have an "options" byte. # Avoid crash if missing. - return u"" + return UNICODE_LITERAL("") pos += lenlen options = BYTES_ORD(data[pos]) pos += 1 @@ -333,7 +333,7 @@ def unpack_unicode_update_pos(data, pos, lenlen=2, known_len=None): pos += lenlen if not nchars and not data[pos:]: # Zero-length string with no options byte - return (u"", pos) + return (UNICODE_LITERAL(""), pos) options = BYTES_ORD(data[pos]) pos += 1 phonetic = options & 0x04 diff --git a/xlrd/book.py b/xlrd/book.py index c79117ab..1e451cd6 100644 --- a/xlrd/book.py +++ b/xlrd/book.py @@ -4,13 +4,15 @@ #

This module is part of the xlrd package, which is released under a # BSD-style licence.

+from __future__ import unicode_literals + from .timemachine import * from .biffh import * import struct; unpack = struct.unpack import sys import time -import sheet -import compdoc +from . import sheet +from . import compdoc from .xldate import xldate_as_tuple, XLDateError from .formula import * from . import formatting @@ -42,20 +44,20 @@ SUPPORTED_VERSIONS = (80, 70, 50, 45, 40, 30, 21, 20) code_from_builtin_name = { - u"Consolidate_Area": u"\x00", - u"Auto_Open": u"\x01", - u"Auto_Close": u"\x02", - u"Extract": u"\x03", - u"Database": u"\x04", - u"Criteria": u"\x05", - u"Print_Area": u"\x06", - u"Print_Titles": u"\x07", - u"Recorder": u"\x08", - u"Data_Form": u"\x09", - u"Auto_Activate": u"\x0A", - u"Auto_Deactivate": u"\x0B", - u"Sheet_Title": u"\x0C", - u"_FilterDatabase": u"\x0D", + "Consolidate_Area": "\x00", + "Auto_Open": "\x01", + "Auto_Close": "\x02", + "Extract": "\x03", + "Database": "\x04", + "Criteria": "\x05", + "Print_Area": "\x06", + "Print_Titles": "\x07", + "Recorder": "\x08", + "Data_Form": "\x09", + "Auto_Activate": "\x0A", + "Auto_Deactivate": "\x0B", + "Sheet_Title": "\x0C", + "_FilterDatabase": "\x0D", } builtin_name_from_code = {} for _bin, _bic in code_from_builtin_name.items(): @@ -207,7 +209,7 @@ class Name(BaseObject): ## # A Unicode string. If builtin, decoded as per OOo docs. - name = u"" + name = "" ## # An 8-bit string. @@ -341,7 +343,7 @@ class Book(BaseObject): ## # What (if anything) is recorded as the name of the last user to save the file. - user_name = u'' + user_name = '' ## # A list of Font class instances, each corresponding to a FONT record. @@ -612,13 +614,13 @@ def biff2_8_load(self, filename=None, file_contents=None, else: cd = compdoc.CompDoc(self.filestr, logfile=self.logfile) if USE_FANCY_CD: - for qname in [u'Workbook', u'Book']: + for qname in ['Workbook', 'Book']: self.mem, self.base, self.stream_len = cd.locate_named_stream(qname) if self.mem: break else: raise XLRDError("Can't find workbook in OLE2 compound document") else: - for qname in [u'Workbook', u'Book']: + for qname in ['Workbook', 'Book']: self.mem = cd.get_named_stream(qname) if self.mem: break else: @@ -703,7 +705,7 @@ def get_sheets(self): def fake_globals_get_sheet(self): # for BIFF 4.0 and earlier formatting.initialise_book(self) - fake_sheet_name = u'Sheet 1' + fake_sheet_name = 'Sheet 1' self._sheet_names = [fake_sheet_name] self._sh_abs_posn = [0] self._sheet_visibility = [0] # one sheet, visible @@ -1338,7 +1340,7 @@ def expand_cell_address(inrow, incol): def colname(colx, _A2Z="ABCDEFGHIJKLMNOPQRSTUVWXYZ"): assert colx >= 0 - name = u'' + name = '' while 1: quot, rem = divmod(colx, 26) name = _A2Z[rem] + name @@ -1384,7 +1386,7 @@ def unpack_SST_table(datatab, nstrings): if options & 0x04: # phonetic phosz = local_unpack('= 80: flag = BYTES_ORD(data[offset]) & 1 @@ -1601,7 +1603,7 @@ def insert_new_BIFF20_xf(self, cell_attr, style=0): msg = "ERROR *** XF[%d] unknown format key (%d, 0x%04x)\n" fprintf(self.logfile, msg, xf.xf_index, xf.format_key, xf.format_key) - fmt = Format(xf.format_key, FUN, u"General") + fmt = Format(xf.format_key, FUN, "General") book.format_map[xf.format_key] = fmt book.format_list.append(fmt) cellty_from_fmtty = { @@ -1734,12 +1736,12 @@ def get_nul_terminated_unicode(buf, ofs): if clsid == BYTES_LITERAL("\xE0\xC9\xEA\x79\xF9\xBA\xCE\x11\x8C\x82\x00\xAA\x00\x4B\xA9\x0B"): # E0H C9H EAH 79H F9H BAH CEH 11H 8CH 82H 00H AAH 00H 4BH A9H 0BH # URL Moniker - h.type = u'url' + h.type = 'url' nbytes = unpack('> self.logfile, "initial url=%r len=%d" % (h.url_or_path, len(h.url_or_path)) - endpos = h.url_or_path.find(u'\x00') + endpos = h.url_or_path.find('\x00') if DEBUG: print >> self.logfile, "endpos=%d" % endpos h.url_or_path = h.url_or_path[:endpos] true_nbytes = 2 * (endpos + 1) @@ -1753,7 +1755,7 @@ def get_nul_terminated_unicode(buf, ofs): assert extra_nbytes in (24, 0) elif clsid == BYTES_LITERAL("\x03\x03\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46"): # file moniker - h.type = u'local file' + h.type = 'local file' uplevels, nbytes = unpack("> self.logfile, "*** unknown clsid %r" % clsid elif options & 0x163 == 0x103: # UNC - h.type = u'unc' + h.type = 'unc' h.url_or_path, offset = get_nul_terminated_unicode(data, offset) elif options & 0x16B == 8: - h.type = u'workbook' + h.type = 'workbook' else: - h.type = u'unknown' + h.type = 'unknown' if options & 0x8: # has textmark h.textmark, offset = get_nul_terminated_unicode(data, offset) @@ -1928,7 +1930,7 @@ def handle_note(self, data, txos): o.show = 0 o.row_hidden = 0 o.col_hidden = 0 - o.author = u'' + o.author = '' o._object_id = None self.cell_note_map[o.rowx, o.colx] = o return @@ -1969,7 +1971,7 @@ def handle_txo(self, data): (15, 0x8000, 'secret_edit'), )) totchars = 0 - o.text = u'' + o.text = '' while totchars < cchText: rc2, data2_len, data2 = self.book.get_record_parts() assert rc2 == XL_CONTINUE @@ -2068,7 +2070,7 @@ class MSTxo(BaseObject): class Note(BaseObject): ## # Author of note - author = u'' + author = '' ## # True if the containing column is hidden col_hidden = 0 @@ -2090,7 +2092,7 @@ class Note(BaseObject): show = 0 ## # Text of the note - text = u'' + text = '' ## #

Contains the attributes of a hyperlink. diff --git a/xlrd/timemachine.py b/xlrd/timemachine.py index 60b03182..ce7dc493 100644 --- a/xlrd/timemachine.py +++ b/xlrd/timemachine.py @@ -19,6 +19,7 @@ if python_version >= (3, 0): # Might work on 3.0 but absolutely no support! BYTES_LITERAL = lambda x: x.encode('latin1') + UNICODE_LITERAL = lambda x: x BYTES_ORD = lambda byte: byte BYTES_NULL = bytes(0) # b'' BYTES_X00 = bytes(1) # b'\x00' @@ -31,6 +32,7 @@ def fprintf(f, fmt, *vargs): REPR = ascii else: BYTES_LITERAL = lambda x: x + UNICODE_LITERAL = lambda x: x.decode('latin1') BYTES_ORD = ord BYTES_NULL = '' BYTES_X00 = '\x00' From 8ee6ae38e72fecbb7b3b5cc9b20cdc4e25b6aecb Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 26 Oct 2012 14:28:57 +0100 Subject: [PATCH 021/319] Apply 2to3 print fixer, and __future__ statements --- xlrd/biffh.py | 16 +-- xlrd/book.py | 95 ++++++++-------- xlrd/compdoc.py | 96 ++++++++-------- xlrd/formatting.py | 39 +++---- xlrd/formula.py | 278 ++++++++++++++++++++++----------------------- xlrd/sheet.py | 100 ++++++++-------- xlrd/xlsx.py | 10 +- 7 files changed, 310 insertions(+), 324 deletions(-) diff --git a/xlrd/biffh.py b/xlrd/biffh.py index 0ccd5ea3..2522f683 100644 --- a/xlrd/biffh.py +++ b/xlrd/biffh.py @@ -16,6 +16,8 @@ # 2007-09-08 SJM Avoid crash when zero-length Unicode string missing options byte. # 2007-04-22 SJM Remove experimental "trimming" facility. +from __future__ import print_function + DEBUG = 0 from struct import unpack @@ -50,7 +52,7 @@ def dump(self, f=None, header=None, footer=None, indent=0): alist = self.__dict__.items() alist.sort() pad = " " * indent - if header is not None: print >> f, header + if header is not None: print(header, file=f) list_type = type([]) dict_type = type({}) for attr, value in alist: @@ -61,10 +63,10 @@ def dump(self, f=None, header=None, footer=None, indent=0): elif attr not in self._repr_these and ( isinstance(value, list_type) or isinstance(value, dict_type) ): - print >> f, "%s%s: %s, len = %d" % (pad, attr, type(value), len(value)) + print("%s%s: %s, len = %d" % (pad, attr, type(value), len(value)), file=f) else: - print >> f, "%s%s: %r" % (pad, attr, value) - if footer is not None: print >> f, footer + print("%s%s: %r" % (pad, attr, value), file=f) + if footer is not None: print(footer, file=f) FUN, FDT, FNU, FGE, FTX = range(5) # unknown, date, number, general, text DATEFORMAT = FDT @@ -257,9 +259,9 @@ def is_cell_opcode(c): def fprintf(f, fmt, *vargs): if fmt.endswith('\n'): - print >> f, fmt[:-1] % vargs + print(fmt[:-1] % vargs, file=f) else: - print >> f, fmt % vargs, + print(fmt % vargs, end=' ', file=f) def upkbits(tgt_obj, src, manifest, local_setattr=setattr): for n, mask, attr in manifest: @@ -647,7 +649,7 @@ def biff_count_records(mem, stream_offset, stream_len, fout=sys.stdout): slist = tally.items() slist.sort() for recname, count in slist: - print >> fout, "%8d %s" % (count, recname) + print("%8d %s" % (count, recname), file=fout) encoding_from_codepage = { 1200 : 'utf_16_le', diff --git a/xlrd/book.py b/xlrd/book.py index 1e451cd6..5c4b1f1d 100644 --- a/xlrd/book.py +++ b/xlrd/book.py @@ -4,7 +4,7 @@ #

This module is part of the xlrd package, which is released under a # BSD-style licence.

-from __future__ import unicode_literals +from __future__ import unicode_literals, print_function from .timemachine import * from .biffh import * @@ -633,7 +633,7 @@ def biff2_8_load(self, filename=None, file_contents=None, self.filestr = BYTES_NULL self._position = self.base if DEBUG: - print >> self.logfile, "mem: %s, base: %d, len: %d" % (type(self.mem), self.base, self.stream_len) + print("mem: %s, base: %d, len: %d" % (type(self.mem), self.base, self.stream_len), file=self.logfile) def initialise_format_info(self): # needs to be done once per sheet for BIFF 4W :-( @@ -698,9 +698,9 @@ def get_sheet(self, sh_number, update_pos=True): def get_sheets(self): # DEBUG = 0 - if DEBUG: print >> self.logfile, "GET_SHEETS:", self._sheet_names, self._sh_abs_posn + if DEBUG: print("GET_SHEETS:", self._sheet_names, self._sh_abs_posn, file=self.logfile) for sheetno in xrange(len(self._sheet_names)): - if DEBUG: print >> self.logfile, "GET_SHEETS: sheetno =", sheetno, self._sheet_names, self._sh_abs_posn + if DEBUG: print("GET_SHEETS: sheetno =", sheetno, self._sheet_names, self._sh_abs_posn, file=self.logfile) self.get_sheet(sheetno) def fake_globals_get_sheet(self): # for BIFF 4.0 and earlier @@ -821,7 +821,7 @@ def handle_codepage(self, data): def handle_country(self, data): countries = unpack('> self.logfile, "Countries:", countries + if self.verbosity: print("Countries:", countries, file=self.logfile) # Note: in BIFF7 and earlier, country record was put (redundantly?) in each worksheet. assert self.countries == (0, 0) or self.countries == countries self.countries = countries @@ -881,7 +881,7 @@ def handle_externsheet(self, data): else: nc, ty = unpack("> self.logfile, "EXTERNSHEET(b7-):" + print("EXTERNSHEET(b7-):", file=self.logfile) hex_char_dump(data, 0, len(data), fout=self.logfile) msg = { 1: "Encoded URL", @@ -889,11 +889,11 @@ def handle_externsheet(self, data): 3: "Specific sheet in own doc't", 4: "Nonspecific sheet in own doc't!!", }.get(ty, "Not encoded") - print >> self.logfile, " %3d chars, type is %d (%s)" % (nc, ty, msg) + print(" %3d chars, type is %d (%s)" % (nc, ty, msg), file=self.logfile) if ty == 3: sheet_name = unicode(data[2:nc+2], self.encoding) self._extnsht_name_from_num[self._extnsht_count] = sheet_name - if blah2: print >> self.logfile, self._extnsht_name_from_num + if blah2: print(self._extnsht_name_from_num, file=self.logfile) if not (1 <= ty <= 4): ty = 0 self._externsheet_type_b57.append(ty) @@ -960,13 +960,13 @@ def handle_name(self, data): nobj.excel_sheet_index = sheet_index nobj.scope = None # patched up in the names_epilogue() method if blah: - print >> self.logfile, "NAME[%d]:%s oflags=%d, name_len=%d, fmla_len=%d, extsht_index=%d, sheet_index=%d, name=%r" \ + print("NAME[%d]:%s oflags=%d, name_len=%d, fmla_len=%d, extsht_index=%d, sheet_index=%d, name=%r" \ % (name_index, macro_flag, option_flags, name_len, - fmla_len, extsht_index, sheet_index, internal_name) + fmla_len, extsht_index, sheet_index, internal_name), file=self.logfile) name = internal_name if nobj.builtin: name = builtin_name_from_code.get(name, "??Unknown??") - if blah: print >> self.logfile, " builtin: %s" % name + if blah: print(" builtin: %s" % name, file=self.logfile) nobj.name = name nobj.raw_formula = data[pos:] nobj.basic_formula_len = fmla_len @@ -982,10 +982,10 @@ def names_epilogue(self): blah = self.verbosity >= 2 f = self.logfile if blah: - print >> f, "+++++ names_epilogue +++++" - print >> f, "_all_sheets_map", self._all_sheets_map - print >> f, "_extnsht_name_from_num", self._extnsht_name_from_num - print >> f, "_sheet_num_from_name", self._sheet_num_from_name + print("+++++ names_epilogue +++++", file=f) + print("_all_sheets_map", self._all_sheets_map, file=f) + print("_extnsht_name_from_num", self._extnsht_name_from_num, file=f) + print("_sheet_num_from_name", self._sheet_num_from_name, file=f) num_names = len(self.name_obj_list) for namex in range(num_names): nobj = self.name_obj_list[namex] @@ -1021,11 +1021,11 @@ def names_epilogue(self): evaluate_name_formula(self, nobj, namex, blah=blah) if self.verbosity >= 2: - print >> f, "---------- name object dump ----------" + print("---------- name object dump ----------", file=f) for namex in range(num_names): nobj = self.name_obj_list[namex] nobj.dump(f, header="--- name[%d] ---" % namex) - print >> f, "--------------------------------------" + print("--------------------------------------", file=f) # # Build some dicts for access to the name objects # @@ -1041,7 +1041,7 @@ def names_epilogue(self): raise XLRDError(msg) else: if self.verbosity: - print >> f, msg + print(msg, file=f) name_and_scope_map[key] = nobj if name_map.has_key(name_lcase): name_map[name_lcase].append((nobj.scope, nobj)) @@ -1066,31 +1066,31 @@ def handle_supbook(self, data): self._supbook_types.append(None) blah = DEBUG or self.verbosity >= 2 if blah: - print >> self.logfile, "SUPBOOK:" + print("SUPBOOK:", file=self.logfile) hex_char_dump(data, 0, len(data), fout=self.logfile) num_sheets = unpack("> self.logfile, "num_sheets = %d" % num_sheets + if blah: print("num_sheets = %d" % num_sheets, file=self.logfile) sbn = self._supbook_count self._supbook_count += 1 if data[2:4] == BYTES_LITERAL("\x01\x04"): self._supbook_types[-1] = SUPBOOK_INTERNAL self._supbook_locals_inx = self._supbook_count - 1 if blah: - print >> self.logfile, "SUPBOOK[%d]: internal 3D refs; %d sheets" % (sbn, num_sheets) - print >> self.logfile, " _all_sheets_map", self._all_sheets_map + print("SUPBOOK[%d]: internal 3D refs; %d sheets" % (sbn, num_sheets), file=self.logfile) + print(" _all_sheets_map", self._all_sheets_map, file=self.logfile) return if data[0:4] == BYTES_LITERAL("\x01\x00\x01\x3A"): self._supbook_types[-1] = SUPBOOK_ADDIN self._supbook_addins_inx = self._supbook_count - 1 - if blah: print >> self.logfile, "SUPBOOK[%d]: add-in functions" % sbn + if blah: print("SUPBOOK[%d]: add-in functions" % sbn, file=self.logfile) return url, pos = unpack_unicode_update_pos(data, 2, lenlen=2) if num_sheets == 0: self._supbook_types[-1] = SUPBOOK_DDEOLE - if blah: print >> self.logfile, "SUPBOOK[%d]: DDE/OLE document = %r" % (sbn, url) + if blah: print("SUPBOOK[%d]: DDE/OLE document = %r" % (sbn, url), file=self.logfile) return self._supbook_types[-1] = SUPBOOK_EXTERNAL - if blah: print >> self.logfile, "SUPBOOK[%d]: url = %r" % (sbn, url) + if blah: print("SUPBOOK[%d]: url = %r" % (sbn, url), file=self.logfile) sheet_names = [] for x in range(num_sheets): try: @@ -1099,13 +1099,13 @@ def handle_supbook(self, data): # #### FIX ME #### # Should implement handling of CONTINUE record(s) ... if self.verbosity: - print >> self.logfile, ( + print(( "*** WARNING: unpack failure in sheet %d of %d in SUPBOOK record for file %r" % (x, num_sheets, url) - ) + ), file=self.logfile) break sheet_names.append(shname) - if blah: print >> self.logfile, " sheetx=%d namelen=%d name=%r (next pos=%d)" % (x, len(shname), shname, pos) + if blah: print(" sheetx=%d namelen=%d name=%r (next pos=%d)" % (x, len(shname), shname, pos), file=self.logfile) def handle_sheethdr(self, data): # This a BIFF 4W special. @@ -1120,24 +1120,24 @@ def handle_sheethdr(self, data): self._sheethdr_count += 1 BOF_posn = self._position posn = BOF_posn - 4 - len(data) - if DEBUG: print >> self.logfile, 'SHEETHDR %d at posn %d: len=%d name=%r' % (sheetno, posn, sheet_len, sheet_name) + if DEBUG: print('SHEETHDR %d at posn %d: len=%d name=%r' % (sheetno, posn, sheet_len, sheet_name), file=self.logfile) self.initialise_format_info() - if DEBUG: print >> self.logfile, 'SHEETHDR: xf epilogue flag is %d' % self._xf_epilogue_done + if DEBUG: print('SHEETHDR: xf epilogue flag is %d' % self._xf_epilogue_done, file=self.logfile) self._sheet_list.append(None) # get_sheet updates _sheet_list but needs a None beforehand self.get_sheet(sheetno, update_pos=False) - if DEBUG: print >> self.logfile, 'SHEETHDR: posn after get_sheet() =', self._position + if DEBUG: print('SHEETHDR: posn after get_sheet() =', self._position, file=self.logfile) self._position = BOF_posn + sheet_len def handle_sheetsoffset(self, data): # DEBUG = 0 posn = unpack('> self.logfile, 'SHEETSOFFSET:', posn + if DEBUG: print('SHEETSOFFSET:', posn, file=self.logfile) self._sheetsoffset = posn def handle_sst(self, data): # DEBUG = 1 if DEBUG: - print >> self.logfile, "SST Processing" + print("SST Processing", file=self.logfile) t0 = time.time() nbt = len(data) strlist = [data] @@ -1157,7 +1157,7 @@ def handle_sst(self, data): self._rich_text_runlist_map = rt_runlist if DEBUG: t1 = time.time() - print >> self.logfile, "SST processing took %.2f seconds" % (t1 - t0, ) + print("SST processing took %.2f seconds" % (t1 - t0, ), file=self.logfile) def handle_writeaccess(self, data): # DEBUG = 0 @@ -1169,7 +1169,7 @@ def handle_writeaccess(self, data): strg = unpack_string(data, 0, self.encoding, lenlen=1) else: strg = unpack_unicode(data, 0, lenlen=2) - if DEBUG: print >> self.logfile, "WRITEACCESS: %d bytes; raw=%d %r" % (len(data), self.raw_user_name, strg) + if DEBUG: print("WRITEACCESS: %d bytes; raw=%d %r" % (len(data), self.raw_user_name, strg), file=self.logfile) strg = strg.rstrip() self.user_name = strg @@ -1179,7 +1179,7 @@ def parse_globals(self): formatting.initialise_book(self) while 1: rc, length, data = self.get_record_parts() - if DEBUG: print >> self.logfile, "parse_globals: record code is 0x%04x" % rc + if DEBUG: print("parse_globals: record code is 0x%04x" % rc, file=self.logfile) if rc == XL_SST: self.handle_sst(data) elif rc == XL_FONT or rc == XL_FONT_B3B4: @@ -1217,8 +1217,8 @@ def parse_globals(self): elif rc == XL_STYLE: self.handle_style(data) elif rc & 0xff == 9 and self.verbosity: - print >> self.logfile, "*** Unexpected BOF at posn %d: 0x%04x len=%d data=%r" \ - % (self._position - length - 4, rc, length, data) + print("*** Unexpected BOF at posn %d: 0x%04x len=%d data=%r" \ + % (self._position - length - 4, rc, length, data), file=self.logfile) elif rc == XL_EOF: self.xf_epilogue() self.names_epilogue() @@ -1227,7 +1227,7 @@ def parse_globals(self): self.derive_encoding() if self.biff_version == 45: # DEBUG = 0 - if DEBUG: print >> self.logfile, "global EOF: position", self._position + if DEBUG: print("global EOF: position", self._position, file=self.logfile) # if DEBUG: # pos = self._position - 4 # print repr(self.mem[pos:pos+40]) @@ -1245,7 +1245,7 @@ def read(self, pos, length): def getbof(self, rqd_stream): # DEBUG = 1 # if DEBUG: print >> self.logfile, "getbof(): position", self._position - if DEBUG: print >> self.logfile, "reqd: 0x%04x" % rqd_stream + if DEBUG: print("reqd: 0x%04x" % rqd_stream, file=self.logfile) def bof_error(msg): raise XLRDError('Unsupported format, or corrupt file: ' + msg) savpos = self._position @@ -1263,19 +1263,19 @@ def bof_error(msg): % (length, opcode)) padding = BYTES_X00 * max(0, boflen[opcode] - length) data = self.read(self._position, length); - if DEBUG: print >> self.logfile, "\ngetbof(): data=%r" % data + if DEBUG: print("\ngetbof(): data=%r" % data, file=self.logfile) if len(data) < length: bof_error('Incomplete BOF record[2]; met end of file') data += padding version1 = opcode >> 8 version2, streamtype = unpack('> self.logfile, "getbof(): op=0x%04x version2=0x%04x streamtype=0x%04x" \ - % (opcode, version2, streamtype) + print("getbof(): op=0x%04x version2=0x%04x streamtype=0x%04x" \ + % (opcode, version2, streamtype), file=self.logfile) bof_offset = self._position - 4 - length if DEBUG: - print >> self.logfile, "getbof(): BOF found at offset %d; savpos=%d" \ - % (bof_offset, savpos) + print("getbof(): BOF found at offset %d; savpos=%d" \ + % (bof_offset, savpos), file=self.logfile) version = build = year = 0 if version1 == 0x08: build, year = unpack('= 2: - print >> self.logfile, \ - "BOF: op=0x%04x vers=0x%04x stream=0x%04x buildid=%d buildyr=%d -> BIFF%d" \ - % (opcode, version2, streamtype, build, year, version) + print("BOF: op=0x%04x vers=0x%04x stream=0x%04x buildid=%d buildyr=%d -> BIFF%d" \ + % (opcode, version2, streamtype, build, year, version), file=self.logfile) got_globals = streamtype == XL_WORKBOOK_GLOBALS or ( version == 45 and streamtype == XL_WORKBOOK_GLOBALS_4W) if (rqd_stream == XL_WORKBOOK_GLOBALS and got_globals) or streamtype == rqd_stream: diff --git a/xlrd/compdoc.py b/xlrd/compdoc.py index 76405fb7..8d16bbf5 100644 --- a/xlrd/compdoc.py +++ b/xlrd/compdoc.py @@ -15,7 +15,7 @@ # 2007-05-07 SJM Meaningful exception instead of IndexError if a SAT (sector allocation table) is corrupted. # 2007-04-22 SJM Missing "<" in a struct.unpack call => can't open files on bigendian platforms. -from __future__ import nested_scopes +from __future__ import nested_scopes, print_function import sys from struct import unpack from .timemachine import * @@ -56,12 +56,12 @@ def __init__(self, DID, dent, DEBUG=0, logfile=sys.stdout): self.dump(DEBUG) def dump(self, DEBUG=1): - print >> self.logfile, "DID=%d name=%r etype=%d DIDs(left=%d right=%d root=%d parent=%d kids=%r) first_SID=%d tot_size=%d" \ + print("DID=%d name=%r etype=%d DIDs(left=%d right=%d root=%d parent=%d kids=%r) first_SID=%d tot_size=%d" \ % (self.DID, self.name, self.etype, self.left_DID, - self.right_DID, self.root_DID, self.parent, self.children, self.first_SID, self.tot_size) + self.right_DID, self.root_DID, self.parent, self.children, self.first_SID, self.tot_size), file=self.logfile) if DEBUG == 2: # cre_lo, cre_hi, mod_lo, mod_hi = tsinfo - print >> self.logfile, "timestamp info", self.tsinfo + print("timestamp info", self.tsinfo, file=self.logfile) def _build_family_tree(dirlist, parent_DID, child_DID): if child_DID < 0: return @@ -88,23 +88,21 @@ def __init__(self, mem, logfile=sys.stdout, DEBUG=0): raise CompDocError('Expected "little-endian" marker, found %r' % mem[28:30]) revision, version = unpack('> logfile, "\nCompDoc format: version=0x%04x revision=0x%04x" % (version, revision) + print("\nCompDoc format: version=0x%04x revision=0x%04x" % (version, revision), file=logfile) self.mem = mem ssz, sssz = unpack(' 20: # allows for 2**20 bytes i.e. 1MB - print >> logfile, \ - "WARNING: sector size (2**%d) is preposterous; assuming 512 and continuing ..." \ - % ssz + print("WARNING: sector size (2**%d) is preposterous; assuming 512 and continuing ..." \ + % ssz, file=logfile) ssz = 9 if sssz > ssz: - print >> logfile, \ - "WARNING: short stream sector size (2**%d) is preposterous; assuming 64 and continuing ..." \ - % sssz + print("WARNING: short stream sector size (2**%d) is preposterous; assuming 64 and continuing ..." \ + % sssz, file=logfile) sssz = 6 self.sec_size = sec_size = 1 << ssz self.short_sec_size = 1 << sssz if self.sec_size != 512 or self.short_sec_size != 64: - print >> logfile, "@@@@ sec_size=%d short_sec_size=%d" % (self.sec_size, self.short_sec_size) + print("@@@@ sec_size=%d short_sec_size=%d" % (self.sec_size, self.short_sec_size), file=logfile) ( SAT_tot_secs, self.dir_first_sec_sid, _unused, self.min_size_std_stream, SSAT_first_sec_sid, SSAT_tot_secs, @@ -116,20 +114,19 @@ def __init__(self, mem, logfile=sys.stdout, DEBUG=0): if left_over: #### raise CompDocError("Not a whole number of sectors") mem_data_secs += 1 - print >> logfile, \ - "WARNING *** file size (%d) not 512 + multiple of sector size (%d)" \ - % (len(mem), sec_size) + print("WARNING *** file size (%d) not 512 + multiple of sector size (%d)" \ + % (len(mem), sec_size), file=logfile) self.mem_data_secs = mem_data_secs # use for checking later self.mem_data_len = mem_data_len seen = self.seen = array.array('B', [0]) * mem_data_secs if DEBUG: - print >> logfile, 'sec sizes', ssz, sssz, sec_size, self.short_sec_size - print >> logfile, "mem data: %d bytes == %d sectors" % (mem_data_len, mem_data_secs) - print >> logfile, "SAT_tot_secs=%d, dir_first_sec_sid=%d, min_size_std_stream=%d" \ - % (SAT_tot_secs, self.dir_first_sec_sid, self.min_size_std_stream,) - print >> logfile, "SSAT_first_sec_sid=%d, SSAT_tot_secs=%d" % (SSAT_first_sec_sid, SSAT_tot_secs,) - print >> logfile, "MSATX_first_sec_sid=%d, MSATX_tot_secs=%d" % (MSATX_first_sec_sid, MSATX_tot_secs,) + print('sec sizes', ssz, sssz, sec_size, self.short_sec_size, file=logfile) + print("mem data: %d bytes == %d sectors" % (mem_data_len, mem_data_secs), file=logfile) + print("SAT_tot_secs=%d, dir_first_sec_sid=%d, min_size_std_stream=%d" \ + % (SAT_tot_secs, self.dir_first_sec_sid, self.min_size_std_stream,), file=logfile) + print("SSAT_first_sec_sid=%d, SSAT_tot_secs=%d" % (SSAT_first_sec_sid, SSAT_tot_secs,), file=logfile) + print("MSATX_first_sec_sid=%d, MSATX_tot_secs=%d" % (MSATX_first_sec_sid, MSATX_tot_secs,), file=logfile) nent = int_floor_div(sec_size, 4) # number of SID entries in a sector fmt = "<%di" % nent trunc_warned = 0 @@ -151,11 +148,11 @@ def __init__(self, mem, logfile=sys.stdout, DEBUG=0): # but Excel doesn't complain about FREESID. Zero is a valid # sector number, not a sentinel. if DEBUG > 1: - print >> logfile, 'MSATX: sid=%d (0x%08X)' % (sid, sid) + print('MSATX: sid=%d (0x%08X)' % (sid, sid), file=logfile) if sid >= mem_data_secs: msg = "MSAT extension: accessing sector %d but only %d in file" % (sid, mem_data_secs) if DEBUG > 1: - print >> logfile, msg + print(msg, file=logfile) break raise CompDocError(msg) elif sid < 0: @@ -165,15 +162,15 @@ def __init__(self, mem, logfile=sys.stdout, DEBUG=0): seen[sid] = 1 actual_MSATX_sectors += 1 if DEBUG and actual_MSATX_sectors > expected_MSATX_sectors: - print >> logfile, "[1]===>>>", mem_data_secs, nent, SAT_sectors_reqd, expected_MSATX_sectors, actual_MSATX_sectors + print("[1]===>>>", mem_data_secs, nent, SAT_sectors_reqd, expected_MSATX_sectors, actual_MSATX_sectors, file=logfile) offset = 512 + sec_size * sid MSAT.extend(unpack(fmt, mem[offset:offset+sec_size])) sid = MSAT.pop() # last sector id is sid of next sector in the chain if DEBUG and actual_MSATX_sectors != expected_MSATX_sectors: - print >> logfile, "[2]===>>>", mem_data_secs, nent, SAT_sectors_reqd, expected_MSATX_sectors, actual_MSATX_sectors + print("[2]===>>>", mem_data_secs, nent, SAT_sectors_reqd, expected_MSATX_sectors, actual_MSATX_sectors, file=logfile) if DEBUG: - print >> logfile, "MSAT: len =", len(MSAT) + print("MSAT: len =", len(MSAT), file=logfile) dump_list(MSAT, 10, logfile) # # === build the SAT === @@ -189,10 +186,9 @@ def __init__(self, mem, logfile=sys.stdout, DEBUG=0): continue if msid >= mem_data_secs: if not trunc_warned: - print >> logfile, "WARNING *** File is truncated, or OLE2 MSAT is corrupt!!" - print >> logfile, \ - "INFO: Trying to access sector %d but only %d available" \ - % (msid, mem_data_secs) + print("WARNING *** File is truncated, or OLE2 MSAT is corrupt!!", file=logfile) + print("INFO: Trying to access sector %d but only %d available" \ + % (msid, mem_data_secs), file=logfile) trunc_warned = 1 MSAT[msidx] = EVILSID dump_again = 1 @@ -204,24 +200,24 @@ def __init__(self, mem, logfile=sys.stdout, DEBUG=0): seen[msid] = 2 actual_SAT_sectors += 1 if DEBUG and actual_SAT_sectors > SAT_sectors_reqd: - print >> logfile, "[3]===>>>", mem_data_secs, nent, SAT_sectors_reqd, expected_MSATX_sectors, actual_MSATX_sectors, actual_SAT_sectors, msid + print("[3]===>>>", mem_data_secs, nent, SAT_sectors_reqd, expected_MSATX_sectors, actual_MSATX_sectors, actual_SAT_sectors, msid, file=logfile) offset = 512 + sec_size * msid self.SAT.extend(unpack(fmt, mem[offset:offset+sec_size])) if DEBUG: - print >> logfile, "SAT: len =", len(self.SAT) + print("SAT: len =", len(self.SAT), file=logfile) dump_list(self.SAT, 10, logfile) # print >> logfile, "SAT ", # for i, s in enumerate(self.SAT): # print >> logfile, "entry: %4d offset: %6d, next entry: %4d" % (i, 512 + sec_size * i, s) # print >> logfile, "%d:%d " % (i, s), - print >> logfile + print(file=logfile) if DEBUG and dump_again: - print >> logfile, "MSAT: len =", len(MSAT) + print("MSAT: len =", len(MSAT), file=logfile) dump_list(MSAT, 10, logfile) for satx in xrange(mem_data_secs, len(self.SAT)): self.SAT[satx] = EVILSID - print >> logfile, "SAT: len =", len(self.SAT) + print("SAT: len =", len(self.SAT), file=logfile) dump_list(self.SAT, 10, logfile) # # === build the directory === @@ -262,8 +258,7 @@ def __init__(self, mem, logfile=sys.stdout, DEBUG=0): # self.SSAT = [] if SSAT_tot_secs > 0 and sscs_dir.tot_size == 0: - print >> logfile, \ - "WARNING *** OLE2 inconsistency: SSCS size is 0 but SSAT size is non-zero" + print("WARNING *** OLE2 inconsistency: SSCS size is 0 but SSAT size is non-zero", file=logfile) if sscs_dir.tot_size > 0: sid = SSAT_first_sec_sid nsecs = SSAT_tot_secs @@ -276,13 +271,13 @@ def __init__(self, mem, logfile=sys.stdout, DEBUG=0): news = list(unpack(fmt, mem[start_pos:start_pos+sec_size])) self.SSAT.extend(news) sid = self.SAT[sid] - if DEBUG: print >> logfile, "SSAT last sid %d; remaining sectors %d" % (sid, nsecs) + if DEBUG: print("SSAT last sid %d; remaining sectors %d" % (sid, nsecs), file=logfile) assert nsecs == 0 and sid == EOCSID if DEBUG: - print >> logfile, "SSAT" + print("SSAT", file=logfile) dump_list(self.SSAT, 10, logfile) if DEBUG: - print >> logfile, "seen" + print("seen", file=logfile) dump_list(seen, 20, logfile) def _get_stream(self, mem, base, sat, sec_size, start_sid, size=None, name='', seen_id=None): @@ -328,9 +323,8 @@ def _get_stream(self, mem, base, sat, sec_size, start_sid, size=None, name='', s ) assert s == EOCSID if todo != 0: - print >> self.logfile, \ - "WARNING *** OLE2 stream %r: expected size %d, actual size %d" \ - % (name, size, size - todo) + print("WARNING *** OLE2 stream %r: expected size %d, actual size %d" \ + % (name, size, size - todo), file=self.logfile) # print >> self.logfile, "_get_stream(%s): seen" % name; dump_list(self.seen, 20, self.logfile) return BYTES_NULL.join(sectors) @@ -392,7 +386,7 @@ def locate_named_stream(self, qname): self.mem, 512, self.SAT, self.sec_size, d.first_SID, d.tot_size, qname, d.DID+6) if self.DEBUG: - print >> self.logfile, "\nseen" + print("\nseen", file=self.logfile) dump_list(self.seen, 20, self.logfile) return result else: @@ -417,7 +411,7 @@ def _locate_stream(self, mem, base, sat, sec_size, start_sid, expected_stream_si found_limit = int_floor_div(expected_stream_size + sec_size - 1, sec_size) while s >= 0: if self.seen[s]: - print >> self.logfile, "_locate_stream(%s): seen" % qname; dump_list(self.seen, 20, self.logfile) + print("_locate_stream(%s): seen" % qname, file=self.logfile); dump_list(self.seen, 20, self.logfile) raise CompDocError("%s corruption: seen[%d] == %d" % (qname, s, self.seen[s])) self.seen[s] = seen_id tot_found += 1 @@ -450,17 +444,17 @@ def _locate_stream(self, mem, base, sat, sec_size, start_sid, expected_stream_si # ========================================================================================== def x_dump_line(alist, stride, f, dpos, equal=0): - print >> f, "%5d%s" % (dpos, " ="[equal]), + print("%5d%s" % (dpos, " ="[equal]), end=' ', file=f) for value in alist[dpos:dpos + stride]: - print >> f, str(value), - print >> f + print(str(value), end=' ', file=f) + print(file=f) def dump_list(alist, stride, f=sys.stdout): def _dump_line(dpos, equal=0): - print >> f, "%5d%s" % (dpos, " ="[equal]), + print("%5d%s" % (dpos, " ="[equal]), end=' ', file=f) for value in alist[dpos:dpos + stride]: - print >> f, str(value), - print >> f + print(str(value), end=' ', file=f) + print(file=f) pos = None oldpos = None for pos in xrange(0, len(alist), stride): diff --git a/xlrd/formatting.py b/xlrd/formatting.py index e91b54b2..8a0b5cf0 100644 --- a/xlrd/formatting.py +++ b/xlrd/formatting.py @@ -22,6 +22,8 @@ # 2007-09-08 SJM Work around corrupt STYLE record # 2007-07-11 SJM Allow for BIFF2/3-style FORMAT record in BIFF4/8 file +from __future__ import print_function + DEBUG = 0 import copy, re from struct import unpack @@ -149,8 +151,8 @@ def nearest_colour_index(colour_map, rgb, debug=0): if metric == 0: break if 0 and debug: - print "nearest_colour_index for %r is %r -> %r; best_metric is %d" \ - % (rgb, best_colourx, colour_map[best_colourx], best_metric) + print("nearest_colour_index for %r is %r -> %r; best_metric is %d" \ + % (rgb, best_colourx, colour_map[best_colourx], best_metric)) return best_colourx ## @@ -479,7 +481,7 @@ def ignorable(c): state = 0 assert 0 <= state <= 2 if book.verbosity >= 4: - print >> book.logfile, "is_date_format_string: reduced format is %r" % s + print("is_date_format_string: reduced format is %r" % s, file=book.logfile) s = fmt_bracketed_sub('', s) if non_date_formats.has_key(s): return False @@ -598,7 +600,7 @@ def handle_palette(book, data): book.colour_map[8+i] = new_rgb if blah: if new_rgb != old_rgb: - print >> book.logfile, "%2d: %r -> %r" % (i, old_rgb, new_rgb) + print("%2d: %r -> %r" % (i, old_rgb, new_rgb), file=book.logfile) def palette_epilogue(book): # Check colour indexes in fonts etc. @@ -613,14 +615,13 @@ def palette_epilogue(book): if book.colour_map.has_key(cx): book.colour_indexes_used[cx] = 1 elif book.verbosity: - print >> book.logfile, "Size of colour table:", len(book.colour_map) - print >> book.logfile, \ - "*** Font #%d (%r): colour index 0x%04x is unknown" \ - % (font.font_index, font.name, cx) + print("Size of colour table:", len(book.colour_map), file=book.logfile) + print("*** Font #%d (%r): colour index 0x%04x is unknown" \ + % (font.font_index, font.name, cx), file=book.logfile) if book.verbosity >= 1: used = book.colour_indexes_used.keys() used.sort() - print >> book.logfile, "\nColour indexes used:\n%r\n" % used + print("\nColour indexes used:\n%r\n" % used, file=book.logfile) def handle_style(book, data): if not book.formatting_info: @@ -653,21 +654,18 @@ def handle_style(book, data): try: name = unpack_unicode(data, 2, lenlen=2) except UnicodeDecodeError: - print >> book.logfile, \ - "STYLE: built_in=%d xf_index=%d built_in_id=%d level=%d" \ - % (built_in, xf_index, built_in_id, level) - print >> book.logfile, "raw bytes:", repr(data[2:]) + print("STYLE: built_in=%d xf_index=%d built_in_id=%d level=%d" \ + % (built_in, xf_index, built_in_id, level), file=book.logfile) + print("raw bytes:", repr(data[2:]), file=book.logfile) raise else: name = unpack_string(data, 2, book.encoding, lenlen=1) if blah and not name: - print >> book.logfile, \ - "WARNING *** A user-defined style has a zero-length name" + print("WARNING *** A user-defined style has a zero-length name", file=book.logfile) book.style_name_map[name] = (built_in, xf_index) if blah: - print >> book.logfile, \ - "STYLE: built_in=%d xf_index=%d built_in_id=%d level=%d name=%r" \ - % (built_in, xf_index, built_in_id, level, name) + print("STYLE: built_in=%d xf_index=%d built_in_id=%d level=%d name=%r" \ + % (built_in, xf_index, built_in_id, level, name), file=book.logfile) def check_colour_indexes_in_obj(book, obj, orig_index): alist = obj.__dict__.items() @@ -680,9 +678,8 @@ def check_colour_indexes_in_obj(book, obj, orig_index): book.colour_indexes_used[nobj] = 1 continue oname = obj.__class__.__name__ - print >> book.logfile, \ - "*** xf #%d : %s.%s = 0x%04x (unknown)" \ - % (orig_index, oname, attr, nobj) + print("*** xf #%d : %s.%s = 0x%04x (unknown)" \ + % (orig_index, oname, attr, nobj), file=book.logfile) def fill_in_standard_formats(book): for x in std_format_code_types.keys(): diff --git a/xlrd/formula.py b/xlrd/formula.py index 40888d95..6aa00b28 100644 --- a/xlrd/formula.py +++ b/xlrd/formula.py @@ -10,7 +10,7 @@ # No part of the content of this file was derived from the works of David Giffin. -from __future__ import nested_scopes +from __future__ import print_function import copy from struct import unpack from .timemachine import * @@ -474,32 +474,32 @@ def get_externsheet_local_range(bk, refx, blah=0): try: info = bk._externsheet_info[refx] except IndexError: - print >> bk.logfile, "!!! get_externsheet_local_range: refx=%d, not in range(%d)" \ - % (refx, len(bk._externsheet_info)) + print("!!! get_externsheet_local_range: refx=%d, not in range(%d)" \ + % (refx, len(bk._externsheet_info)), file=bk.logfile) return (-101, -101) ref_recordx, ref_first_sheetx, ref_last_sheetx = info if ref_recordx == bk._supbook_addins_inx: if blah: - print >> bk.logfile, "/// get_externsheet_local_range(refx=%d) -> addins %r" % (refx, info) + print("/// get_externsheet_local_range(refx=%d) -> addins %r" % (refx, info), file=bk.logfile) assert ref_first_sheetx == 0xFFFE == ref_last_sheetx return (-5, -5) if ref_recordx != bk._supbook_locals_inx: if blah: - print >> bk.logfile, "/// get_externsheet_local_range(refx=%d) -> external %r" % (refx, info) + print("/// get_externsheet_local_range(refx=%d) -> external %r" % (refx, info), file=bk.logfile) return (-4, -4) # external reference if ref_first_sheetx == 0xFFFE == ref_last_sheetx: if blah: - print >> bk.logfile, "/// get_externsheet_local_range(refx=%d) -> unspecified sheet %r" % (refx, info) + print("/// get_externsheet_local_range(refx=%d) -> unspecified sheet %r" % (refx, info), file=bk.logfile) return (-1, -1) # internal reference, any sheet if ref_first_sheetx == 0xFFFF == ref_last_sheetx: if blah: - print >> bk.logfile, "/// get_externsheet_local_range(refx=%d) -> deleted sheet(s)" % (refx, ) + print("/// get_externsheet_local_range(refx=%d) -> deleted sheet(s)" % (refx, ), file=bk.logfile) return (-2, -2) # internal reference, deleted sheet(s) nsheets = len(bk._all_sheets_map) if not(0 <= ref_first_sheetx <= ref_last_sheetx < nsheets): if blah: - print >> bk.logfile, "/// get_externsheet_local_range(refx=%d) -> %r" % (refx, info) - print >> bk.logfile, "--- first/last sheet not in range(%d)" % nsheets + print("/// get_externsheet_local_range(refx=%d) -> %r" % (refx, info), file=bk.logfile) + print("--- first/last sheet not in range(%d)" % nsheets, file=bk.logfile) return (-102, -102) # stuffed up somewhere :-( xlrd_sheetx1 = bk._all_sheets_map[ref_first_sheetx] xlrd_sheetx2 = bk._all_sheets_map[ref_last_sheetx] @@ -511,16 +511,16 @@ def get_externsheet_local_range_b57( bk, raw_extshtx, ref_first_sheetx, ref_last_sheetx, blah=0): if raw_extshtx > 0: if blah: - print >> bk.logfile, "/// get_externsheet_local_range_b57(raw_extshtx=%d) -> external" % raw_extshtx + print("/// get_externsheet_local_range_b57(raw_extshtx=%d) -> external" % raw_extshtx, file=bk.logfile) return (-4, -4) # external reference if ref_first_sheetx == -1 and ref_last_sheetx == -1: return (-2, -2) # internal reference, deleted sheet(s) nsheets = len(bk._all_sheets_map) if not(0 <= ref_first_sheetx <= ref_last_sheetx < nsheets): if blah: - print >> bk.logfile, "/// get_externsheet_local_range_b57(%d, %d, %d) -> ???" \ - % (raw_extshtx, ref_first_sheetx, ref_last_sheetx) - print >> bk.logfile, "--- first/last sheet not in range(%d)" % nsheets + print("/// get_externsheet_local_range_b57(%d, %d, %d) -> ???" \ + % (raw_extshtx, ref_first_sheetx, ref_last_sheetx), file=bk.logfile) + print("--- first/last sheet not in range(%d)" % nsheets, file=bk.logfile) return (-103, -103) # stuffed up somewhere :-( xlrd_sheetx1 = bk._all_sheets_map[ref_first_sheetx] xlrd_sheetx2 = bk._all_sheets_map[ref_last_sheetx] @@ -754,8 +754,8 @@ def evaluate_name_formula(bk, nobj, namex, blah=0, level=0): bv = bk.biff_version reldelta = 1 # All defined name formulas use "Method B" [OOo docs] if blah: - print >> bk.logfile, "::: evaluate_name_formula %r %r %d %d %r level=%d" \ - % (namex, nobj.name, fmlalen, bv, data, level) + print("::: evaluate_name_formula %r %r %d %d %r level=%d" \ + % (namex, nobj.name, fmlalen, bv, data, level), file=bk.logfile) hex_char_dump(data, 0, fmlalen, fout=bk.logfile) if level > STACK_PANIC_LEVEL: raise XLRDError("Excessive indirect references in NAME formula") @@ -836,9 +836,9 @@ def not_in_name_formula(op_arg, oname_arg): oname = onames[opx] # + [" RVA"][optype] sz = sztab[opx] if blah: - print >> bk.logfile, "Pos:%d Op:0x%02x Name:t%s Sz:%d opcode:%02xh optype:%02xh" \ - % (pos, op, oname, sz, opcode, optype) - print >> bk.logfile, "Stack =", stack + print("Pos:%d Op:0x%02x Name:t%s Sz:%d opcode:%02xh optype:%02xh" \ + % (pos, op, oname, sz, opcode, optype), file=bk.logfile) + print("Stack =", stack, file=bk.logfile) if sz == -2: msg = 'ERROR *** Unexpected token 0x%02x ("%s"); biff_version=%d' \ % (op, oname, bv) @@ -852,7 +852,7 @@ def not_in_name_formula(op_arg, oname_arg): # tLT, ..., tNE do_binop(opcode, stack) elif opcode == 0x0F: # tIsect - if blah: print >> bk.logfile, "tIsect pre", stack + if blah: print("tIsect pre", stack, file=bk.logfile) assert len(stack) >= 2 bop = stack.pop() aop = stack.pop() @@ -900,9 +900,9 @@ def not_in_name_formula(op_arg, oname_arg): else: pass spush(res) - if blah: print >> bk.logfile, "tIsect post", stack + if blah: print("tIsect post", stack, file=bk.logfile) elif opcode == 0x10: # tList - if blah: print >> bk.logfile, "tList pre", stack + if blah: print("tList pre", stack, file=bk.logfile) assert len(stack) >= 2 bop = stack.pop() aop = stack.pop() @@ -931,9 +931,9 @@ def not_in_name_formula(op_arg, oname_arg): else: pass spush(res) - if blah: print >> bk.logfile, "tList post", stack + if blah: print("tList post", stack, file=bk.logfile) elif opcode == 0x11: # tRange - if blah: print >> bk.logfile, "tRange pre", stack + if blah: print("tRange pre", stack, file=bk.logfile) assert len(stack) >= 2 bop = stack.pop() aop = stack.pop() @@ -972,7 +972,7 @@ def not_in_name_formula(op_arg, oname_arg): else: pass spush(res) - if blah: print >> bk.logfile, "tRange post", stack + if blah: print("tRange post", stack, file=bk.logfile) elif 0x12 <= opcode <= 0x14: # tUplus, tUminus, tPercent do_unaryop(opcode, oNUM, stack) elif opcode == 0x15: # tParen @@ -988,7 +988,7 @@ def not_in_name_formula(op_arg, oname_arg): strg, newpos = unpack_unicode_update_pos( data, pos+1, lenlen=1) sz = newpos - pos - if blah: print >> bk.logfile, " sz=%d strg=%r" % (sz, strg) + if blah: print(" sz=%d strg=%r" % (sz, strg), file=bk.logfile) text = '"' + strg.replace('"', '""') + '"' spush(Operand(oSTRG, strg, LEAF_RANK, text)) elif opcode == 0x18: # tExtended @@ -1003,7 +1003,7 @@ def not_in_name_formula(op_arg, oname_arg): sz = nc * 2 + 6 elif subop == 0x10: # Sum (single arg) sz = 4 - if blah: print >> bk.logfile, "tAttrSum", stack + if blah: print("tAttrSum", stack, file=bk.logfile) assert len(stack) >= 1 aop = stack[-1] otext = 'SUM(%s)' % aop.text @@ -1011,8 +1011,8 @@ def not_in_name_formula(op_arg, oname_arg): else: sz = 4 if blah: - print >> bk.logfile, " subop=%02xh subname=t%s sz=%d nc=%02xh" \ - % (subop, subname, sz, nc) + print(" subop=%02xh subname=t%s sz=%d nc=%02xh" \ + % (subop, subname, sz, nc), file=bk.logfile) elif 0x1A <= opcode <= 0x1B: # tSheet, tEndSheet assert bv < 50 raise FormulaError("tSheet & tEndsheet tokens not implemented") @@ -1044,14 +1044,14 @@ def not_in_name_formula(op_arg, oname_arg): funcx = unpack("<" + " BH"[nb], data[pos+1:pos+1+nb])[0] func_attrs = func_defs.get(funcx, None) if not func_attrs: - print >> bk.logfile, "*** formula/tFunc unknown FuncID:%d" \ - % funcx + print("*** formula/tFunc unknown FuncID:%d" \ + % funcx, file=bk.logfile) spush(unk_opnd) else: func_name, nargs = func_attrs[:2] if blah: - print >> bk.logfile, " FuncID=%d name=%s nargs=%d" \ - % (funcx, func_name, nargs) + print(" FuncID=%d name=%s nargs=%d" \ + % (funcx, func_name, nargs), file=bk.logfile) assert len(stack) >= nargs if nargs: argtext = listsep.join([arg.text for arg in stack[-nargs:]]) @@ -1067,18 +1067,18 @@ def not_in_name_formula(op_arg, oname_arg): prompt, nargs = divmod(nargs, 128) macro, funcx = divmod(funcx, 32768) if blah: - print >> bk.logfile, " FuncID=%d nargs=%d macro=%d prompt=%d" \ - % (funcx, nargs, macro, prompt) + print(" FuncID=%d nargs=%d macro=%d prompt=%d" \ + % (funcx, nargs, macro, prompt), file=bk.logfile) func_attrs = func_defs.get(funcx, None) if not func_attrs: - print >> bk.logfile, "*** formula/tFuncVar unknown FuncID:%d" \ - % funcx + print("*** formula/tFuncVar unknown FuncID:%d" \ + % funcx, file=bk.logfile) spush(unk_opnd) else: func_name, minargs, maxargs = func_attrs[:3] if blah: - print >> bk.logfile, " name: %r, min~max args: %d~%d" \ - % (func_name, minargs, maxargs) + print(" name: %r, min~max args: %d~%d" \ + % (func_name, minargs, maxargs), file=bk.logfile) assert minargs <= nargs <= maxargs assert len(stack) >= nargs assert len(stack) >= nargs @@ -1089,10 +1089,10 @@ def not_in_name_formula(op_arg, oname_arg): testarg = stack[-nargs] if testarg.kind not in (oNUM, oBOOL): if blah and testarg.kind != oUNK: - print >> bk.logfile, "IF testarg kind?" + print("IF testarg kind?", file=bk.logfile) elif testarg.value not in (0, 1): if blah and testarg.value is not None: - print >> bk.logfile, "IF testarg value?" + print("IF testarg value?", file=bk.logfile) else: if nargs == 2 and not testarg.value: # IF(FALSE, tv) => FALSE @@ -1105,7 +1105,7 @@ def not_in_name_formula(op_arg, oname_arg): else: res.kind, res.value = chosen.kind, chosen.value if blah: - print >> bk.logfile, "$$$$$$ IF => constant" + print("$$$$$$ IF => constant", file=bk.logfile) elif funcx == 100: # CHOOSE testarg = stack[-nargs] if testarg.kind == oNUM: @@ -1120,7 +1120,7 @@ def not_in_name_formula(op_arg, oname_arg): elif opcode == 0x03: #tName tgtnamex = unpack("> bk.logfile, " tgtnamex=%d" % tgtnamex + if blah: print(" tgtnamex=%d" % tgtnamex, file=bk.logfile) tgtobj = bk.name_obj_list[tgtnamex] if not tgtobj.evaluated: ### recursive ### @@ -1146,17 +1146,17 @@ def not_in_name_formula(op_arg, oname_arg): res.text = "%s!%s" \ % (bk._sheet_names[tgtobj.scope], tgtobj.name) if blah: - print >> bk.logfile, " tName: setting text to", repr(res.text) + print(" tName: setting text to", repr(res.text), file=bk.logfile) spush(res) elif opcode == 0x04: # tRef # not_in_name_formula(op, oname) res = get_cell_addr(data, pos+1, bv, reldelta) - if blah: print >> bk.logfile, " ", res + if blah: print(" ", res, file=bk.logfile) rowx, colx, row_rel, col_rel = res shx1 = shx2 = 0 ####### N.B. relative to the CURRENT SHEET any_rel = 1 coords = (shx1, shx2+1, rowx, rowx+1, colx, colx+1) - if blah: print >> bk.logfile, " ", coords + if blah: print(" ", coords, file=bk.logfile) res = Operand(oUNK, None) if optype == 1: relflags = (1, 1, row_rel, row_rel, col_rel, col_rel) @@ -1165,13 +1165,13 @@ def not_in_name_formula(op_arg, oname_arg): elif opcode == 0x05: # tArea # not_in_name_formula(op, oname) res1, res2 = get_cell_range_addr(data, pos+1, bv, reldelta) - if blah: print >> bk.logfile, " ", res1, res2 + if blah: print(" ", res1, res2, file=bk.logfile) rowx1, colx1, row_rel1, col_rel1 = res1 rowx2, colx2, row_rel2, col_rel2 = res2 shx1 = shx2 = 0 ####### N.B. relative to the CURRENT SHEET any_rel = 1 coords = (shx1, shx2+1, rowx1, rowx2+1, colx1, colx2+1) - if blah: print >> bk.logfile, " ", coords + if blah: print(" ", coords, file=bk.logfile) res = Operand(oUNK, None) if optype == 1: relflags = (1, 1, row_rel1, row_rel2, col_rel1, col_rel2) @@ -1181,7 +1181,7 @@ def not_in_name_formula(op_arg, oname_arg): not_in_name_formula(op, oname) elif opcode == 0x09: # tMemFunc nb = unpack("> bk.logfile, " %d bytes of cell ref formula" % nb + if blah: print(" %d bytes of cell ref formula" % nb, file=bk.logfile) # no effect on stack elif opcode == 0x0C: #tRefN not_in_name_formula(op, oname) @@ -1206,7 +1206,7 @@ def not_in_name_formula(op_arg, oname_arg): raw_extshtx, raw_shx1, raw_shx2 = \ unpack("> bk.logfile, "tRef3d", raw_extshtx, raw_shx1, raw_shx2 + print("tRef3d", raw_extshtx, raw_shx1, raw_shx2, file=bk.logfile) shx1, shx2 = get_externsheet_local_range_b57( bk, raw_extshtx, raw_shx1, raw_shx2, blah) rowx, colx, row_rel, col_rel = res @@ -1214,7 +1214,7 @@ def not_in_name_formula(op_arg, oname_arg): any_rel = any_rel or is_rel coords = (shx1, shx2+1, rowx, rowx+1, colx, colx+1) any_err |= shx1 < -1 - if blah: print >> bk.logfile, " ", coords + if blah: print(" ", coords, file=bk.logfile) res = Operand(oUNK, None) if is_rel: relflags = (0, 0, row_rel, row_rel, col_rel, col_rel) @@ -1239,7 +1239,7 @@ def not_in_name_formula(op_arg, oname_arg): raw_extshtx, raw_shx1, raw_shx2 = \ unpack("> bk.logfile, "tArea3d", raw_extshtx, raw_shx1, raw_shx2 + print("tArea3d", raw_extshtx, raw_shx1, raw_shx2, file=bk.logfile) shx1, shx2 = get_externsheet_local_range_b57( bk, raw_extshtx, raw_shx1, raw_shx2, blah) any_err |= shx1 < -1 @@ -1248,7 +1248,7 @@ def not_in_name_formula(op_arg, oname_arg): is_rel = row_rel1 or col_rel1 or row_rel2 or col_rel2 any_rel = any_rel or is_rel coords = (shx1, shx2+1, rowx1, rowx2+1, colx1, colx2+1) - if blah: print >> bk.logfile, " ", coords + if blah: print(" ", coords, file=bk.logfile) res = Operand(oUNK, None) if is_rel: relflags = (0, 0, row_rel1, row_rel2, col_rel1, col_rel2) @@ -1282,11 +1282,10 @@ def not_in_name_formula(op_arg, oname_arg): else: dodgy = 1 if blah: - print >> bk.logfile, \ - " origrefx=%d refx=%d tgtnamex=%d dodgy=%d" \ - % (origrefx, refx, tgtnamex, dodgy) + print(" origrefx=%d refx=%d tgtnamex=%d dodgy=%d" \ + % (origrefx, refx, tgtnamex, dodgy), file=bk.logfile) if tgtnamex == namex: - if blah: print >> bk.logfile, "!!!! Self-referential !!!!" + if blah: print("!!!! Self-referential !!!!", file=bk.logfile) dodgy = any_err = 1 if not dodgy: if bv >= 80: @@ -1329,25 +1328,25 @@ def not_in_name_formula(op_arg, oname_arg): res.text = "%s!%s" \ % (bk._sheet_names[tgtobj.scope], tgtobj.name) if blah: - print >> bk.logfile, " tNameX: setting text to", repr(res.text) + print(" tNameX: setting text to", repr(res.text), file=bk.logfile) spush(res) elif is_error_opcode(opcode): any_err = 1 spush(error_opnd) else: if blah: - print >> bk.logfile, "FORMULA: /// Not handled yet: t" + oname + print("FORMULA: /// Not handled yet: t" + oname, file=bk.logfile) any_err = 1 if sz <= 0: raise FormulaError("Fatal: token size is not positive") pos += sz any_rel = not not any_rel if blah: - print >> bk.logfile, "End of formula. level=%d any_rel=%d any_err=%d stack=%r" % \ - (level, not not any_rel, any_err, stack) + print("End of formula. level=%d any_rel=%d any_err=%d stack=%r" % \ + (level, not not any_rel, any_err, stack), file=bk.logfile) if len(stack) >= 2: - print >> bk.logfile, "*** Stack has unprocessed args" - print >> bk.logfile + print("*** Stack has unprocessed args", file=bk.logfile) + print(file=bk.logfile) nobj.stack = stack if len(stack) != 1: nobj.result = None @@ -1368,8 +1367,8 @@ def decompile_formula(bk, fmla, fmlalen, data = fmla bv = bk.biff_version if blah: - print >> bk.logfile, "::: decompile_formula len=%d fmlatype=%r browx=%r bcolx=%r reldelta=%d %r level=%d" \ - % (fmlalen, fmlatype, browx, bcolx, reldelta, data, level) + print("::: decompile_formula len=%d fmlatype=%r browx=%r bcolx=%r reldelta=%d %r level=%d" \ + % (fmlalen, fmlatype, browx, bcolx, reldelta, data, level), file=bk.logfile) hex_char_dump(data, 0, fmlalen, fout=bk.logfile) if level > STACK_PANIC_LEVEL: raise XLRDError("Excessive indirect references in formula") @@ -1416,7 +1415,7 @@ def do_unaryop(opcode, result_kind, stk): def unexpected_opcode(op_arg, oname_arg): msg = "ERROR *** Unexpected token 0x%02x (%s) found in formula type %s" \ % (op_arg, oname_arg, FMLA_TYPEDESCR_MAP[fmlatype]) - print >> bk.logfile, msg + print(msg, file=bk.logfile) # raise FormulaError(msg) if fmlalen == 0: @@ -1433,9 +1432,9 @@ def unexpected_opcode(op_arg, oname_arg): oname = onames[opx] # + [" RVA"][optype] sz = sztab[opx] if blah: - print >> bk.logfile, "Pos:%d Op:0x%02x opname:t%s Sz:%d opcode:%02xh optype:%02xh" \ - % (pos, op, oname, sz, opcode, optype) - print >> bk.logfile, "Stack =", stack + print("Pos:%d Op:0x%02x opname:t%s Sz:%d opcode:%02xh optype:%02xh" \ + % (pos, op, oname, sz, opcode, optype), file=bk.logfile) + print("Stack =", stack, file=bk.logfile) if sz == -2: msg = 'ERROR *** Unexpected token 0x%02x ("%s"); biff_version=%d' \ % (op, oname, bv) @@ -1460,7 +1459,7 @@ def unexpected_opcode(op_arg, oname_arg): # tLT, ..., tNE do_binop(opcode, stack) elif opcode == 0x0F: # tIsect - if blah: print >> bk.logfile, "tIsect pre", stack + if blah: print("tIsect pre", stack, file=bk.logfile) assert len(stack) >= 2 bop = stack.pop() aop = stack.pop() @@ -1494,9 +1493,9 @@ def unexpected_opcode(op_arg, oname_arg): else: pass spush(res) - if blah: print >> bk.logfile, "tIsect post", stack + if blah: print("tIsect post", stack, file=bk.logfile) elif opcode == 0x10: # tList - if blah: print >> bk.logfile, "tList pre", stack + if blah: print("tList pre", stack, file=bk.logfile) assert len(stack) >= 2 bop = stack.pop() aop = stack.pop() @@ -1521,9 +1520,9 @@ def unexpected_opcode(op_arg, oname_arg): else: pass spush(res) - if blah: print >> bk.logfile, "tList post", stack + if blah: print("tList post", stack, file=bk.logfile) elif opcode == 0x11: # tRange - if blah: print >> bk.logfile, "tRange pre", stack + if blah: print("tRange pre", stack, file=bk.logfile) assert len(stack) >= 2 bop = stack.pop() aop = stack.pop() @@ -1546,7 +1545,7 @@ def unexpected_opcode(op_arg, oname_arg): else: pass spush(res) - if blah: print >> bk.logfile, "tRange post", stack + if blah: print("tRange post", stack, file=bk.logfile) elif 0x12 <= opcode <= 0x14: # tUplus, tUminus, tPercent do_unaryop(opcode, oNUM, stack) elif opcode == 0x15: # tParen @@ -1562,7 +1561,7 @@ def unexpected_opcode(op_arg, oname_arg): strg, newpos = unpack_unicode_update_pos( data, pos+1, lenlen=1) sz = newpos - pos - if blah: print >> bk.logfile, " sz=%d strg=%r" % (sz, strg) + if blah: print(" sz=%d strg=%r" % (sz, strg), file=bk.logfile) text = '"' + strg.replace('"', '""') + '"' spush(Operand(oSTRG, None, LEAF_RANK, text)) elif opcode == 0x18: # tExtended @@ -1577,7 +1576,7 @@ def unexpected_opcode(op_arg, oname_arg): sz = nc * 2 + 6 elif subop == 0x10: # Sum (single arg) sz = 4 - if blah: print >> bk.logfile, "tAttrSum", stack + if blah: print("tAttrSum", stack, file=bk.logfile) assert len(stack) >= 1 aop = stack[-1] otext = 'SUM(%s)' % aop.text @@ -1585,8 +1584,8 @@ def unexpected_opcode(op_arg, oname_arg): else: sz = 4 if blah: - print >> bk.logfile, " subop=%02xh subname=t%s sz=%d nc=%02xh" \ - % (subop, subname, sz, nc) + print(" subop=%02xh subname=t%s sz=%d nc=%02xh" \ + % (subop, subname, sz, nc), file=bk.logfile) elif 0x1A <= opcode <= 0x1B: # tSheet, tEndSheet assert bv < 50 raise FormulaError("tSheet & tEndsheet tokens not implemented") @@ -1618,13 +1617,13 @@ def unexpected_opcode(op_arg, oname_arg): funcx = unpack("<" + " BH"[nb], data[pos+1:pos+1+nb])[0] func_attrs = func_defs.get(funcx, None) if not func_attrs: - print >> bk.logfile, "*** formula/tFunc unknown FuncID:%d" % funcx + print("*** formula/tFunc unknown FuncID:%d" % funcx, file=bk.logfile) spush(unk_opnd) else: func_name, nargs = func_attrs[:2] if blah: - print >> bk.logfile, " FuncID=%d name=%s nargs=%d" \ - % (funcx, func_name, nargs) + print(" FuncID=%d name=%s nargs=%d" \ + % (funcx, func_name, nargs), file=bk.logfile) assert len(stack) >= nargs if nargs: argtext = listsep.join([arg.text for arg in stack[-nargs:]]) @@ -1640,22 +1639,22 @@ def unexpected_opcode(op_arg, oname_arg): prompt, nargs = divmod(nargs, 128) macro, funcx = divmod(funcx, 32768) if blah: - print >> bk.logfile, " FuncID=%d nargs=%d macro=%d prompt=%d" \ - % (funcx, nargs, macro, prompt) + print(" FuncID=%d nargs=%d macro=%d prompt=%d" \ + % (funcx, nargs, macro, prompt), file=bk.logfile) #### TODO #### if funcx == 255: # call add-in function if funcx == 255: func_attrs = ("CALL_ADDIN", 1, 30) else: func_attrs = func_defs.get(funcx, None) if not func_attrs: - print >> bk.logfile, "*** formula/tFuncVar unknown FuncID:%d" \ - % funcx + print("*** formula/tFuncVar unknown FuncID:%d" \ + % funcx, file=bk.logfile) spush(unk_opnd) else: func_name, minargs, maxargs = func_attrs[:3] if blah: - print >> bk.logfile, " name: %r, min~max args: %d~%d" \ - % (func_name, minargs, maxargs) + print(" name: %r, min~max args: %d~%d" \ + % (func_name, minargs, maxargs), file=bk.logfile) assert minargs <= nargs <= maxargs assert len(stack) >= nargs assert len(stack) >= nargs @@ -1667,19 +1666,19 @@ def unexpected_opcode(op_arg, oname_arg): elif opcode == 0x03: #tName tgtnamex = unpack("> bk.logfile, " tgtnamex=%d" % tgtnamex + if blah: print(" tgtnamex=%d" % tgtnamex, file=bk.logfile) tgtobj = bk.name_obj_list[tgtnamex] if tgtobj.scope == -1: otext = tgtobj.name else: otext = "%s!%s" % (bk._sheet_names[tgtobj.scope], tgtobj.name) if blah: - print >> bk.logfile, " tName: setting text to", repr(otext) + print(" tName: setting text to", repr(otext), file=bk.logfile) res = Operand(oUNK, None, LEAF_RANK, otext) spush(res) elif opcode == 0x04: # tRef res = get_cell_addr(data, pos+1, bv, reldelta, browx, bcolx) - if blah: print >> bk.logfile, " ", res + if blah: print(" ", res, file=bk.logfile) rowx, colx, row_rel, col_rel = res is_rel = row_rel or col_rel if is_rel: @@ -1692,7 +1691,7 @@ def unexpected_opcode(op_arg, oname_arg): elif opcode == 0x05: # tArea res1, res2 = get_cell_range_addr( data, pos+1, bv, reldelta, browx, bcolx) - if blah: print >> bk.logfile, " ", res1, res2 + if blah: print(" ", res1, res2, file=bk.logfile) rowx1, colx1, row_rel1, col_rel1 = res1 rowx2, colx2, row_rel2, col_rel2 = res2 coords = (rowx1, rowx2+1, colx1, colx2+1) @@ -1702,7 +1701,7 @@ def unexpected_opcode(op_arg, oname_arg): okind = oREL else: okind = oREF - if blah: print >> bk.logfile, " ", coords, relflags + if blah: print(" ", coords, relflags, file=bk.logfile) otext = rangename2drel(coords, relflags, browx, bcolx, r1c1) res = Operand(okind, None, LEAF_RANK, otext) spush(res) @@ -1710,13 +1709,13 @@ def unexpected_opcode(op_arg, oname_arg): not_in_name_formula(op, oname) elif opcode == 0x09: # tMemFunc nb = unpack("> bk.logfile, " %d bytes of cell ref formula" % nb + if blah: print(" %d bytes of cell ref formula" % nb, file=bk.logfile) # no effect on stack elif opcode == 0x0C: #tRefN res = get_cell_addr(data, pos+1, bv, reldelta, browx, bcolx) # note *ALL* tRefN usage has signed offset for relative addresses any_rel = 1 - if blah: print >> bk.logfile, " ", res + if blah: print(" ", res, file=bk.logfile) rowx, colx, row_rel, col_rel = res is_rel = row_rel or col_rel if is_rel: @@ -1733,7 +1732,7 @@ def unexpected_opcode(op_arg, oname_arg): # if blah: print >> bk.logfile, " ", res res1, res2 = get_cell_range_addr( data, pos+1, bv, reldelta, browx, bcolx) - if blah: print >> bk.logfile, " ", res1, res2 + if blah: print(" ", res1, res2, file=bk.logfile) rowx1, colx1, row_rel1, col_rel1 = res1 rowx2, colx2, row_rel2, col_rel2 = res2 coords = (rowx1, rowx2+1, colx1, colx2+1) @@ -1743,7 +1742,7 @@ def unexpected_opcode(op_arg, oname_arg): okind = oREL else: okind = oREF - if blah: print >> bk.logfile, " ", coords, relflags + if blah: print(" ", coords, relflags, file=bk.logfile) otext = rangename2drel(coords, relflags, browx, bcolx, r1c1) res = Operand(okind, None, LEAF_RANK, otext) spush(res) @@ -1757,7 +1756,7 @@ def unexpected_opcode(op_arg, oname_arg): raw_extshtx, raw_shx1, raw_shx2 = \ unpack("> bk.logfile, "tRef3d", raw_extshtx, raw_shx1, raw_shx2 + print("tRef3d", raw_extshtx, raw_shx1, raw_shx2, file=bk.logfile) shx1, shx2 = get_externsheet_local_range_b57( bk, raw_extshtx, raw_shx1, raw_shx2, blah) rowx, colx, row_rel, col_rel = res @@ -1765,7 +1764,7 @@ def unexpected_opcode(op_arg, oname_arg): any_rel = any_rel or is_rel coords = (shx1, shx2+1, rowx, rowx+1, colx, colx+1) any_err |= shx1 < -1 - if blah: print >> bk.logfile, " ", coords + if blah: print(" ", coords, file=bk.logfile) res = Operand(oUNK, None) if is_rel: relflags = (0, 0, row_rel, row_rel, col_rel, col_rel) @@ -1789,7 +1788,7 @@ def unexpected_opcode(op_arg, oname_arg): raw_extshtx, raw_shx1, raw_shx2 = \ unpack("> bk.logfile, "tArea3d", raw_extshtx, raw_shx1, raw_shx2 + print("tArea3d", raw_extshtx, raw_shx1, raw_shx2, file=bk.logfile) shx1, shx2 = get_externsheet_local_range_b57( bk, raw_extshtx, raw_shx1, raw_shx2, blah) any_err |= shx1 < -1 @@ -1798,7 +1797,7 @@ def unexpected_opcode(op_arg, oname_arg): is_rel = row_rel1 or col_rel1 or row_rel2 or col_rel2 any_rel = any_rel or is_rel coords = (shx1, shx2+1, rowx1, rowx2+1, colx1, colx2+1) - if blah: print >> bk.logfile, " ", coords + if blah: print(" ", coords, file=bk.logfile) res = Operand(oUNK, None) if is_rel: relflags = (0, 0, row_rel1, row_rel2, col_rel1, col_rel2) @@ -1829,9 +1828,8 @@ def unexpected_opcode(op_arg, oname_arg): else: dodgy = 1 if blah: - print >> bk.logfile, \ - " origrefx=%d refx=%d tgtnamex=%d dodgy=%d" \ - % (origrefx, refx, tgtnamex, dodgy) + print(" origrefx=%d refx=%d tgtnamex=%d dodgy=%d" \ + % (origrefx, refx, tgtnamex, dodgy), file=bk.logfile) # if tgtnamex == namex: # if blah: print >> bk.logfile, "!!!! Self-referential !!!!" # dodgy = any_err = 1 @@ -1863,7 +1861,7 @@ def unexpected_opcode(op_arg, oname_arg): otext = "%s!%s" \ % (bk._sheet_names[tgtobj.scope], tgtobj.name) if blah: - print >> bk.logfile, " tNameX: setting text to", repr(res.text) + print(" tNameX: setting text to", repr(res.text), file=bk.logfile) res = Operand(okind, ovalue, LEAF_RANK, otext) spush(res) elif is_error_opcode(opcode): @@ -1871,18 +1869,18 @@ def unexpected_opcode(op_arg, oname_arg): spush(error_opnd) else: if blah: - print >> bk.logfile, "FORMULA: /// Not handled yet: t" + oname + print("FORMULA: /// Not handled yet: t" + oname, file=bk.logfile) any_err = 1 if sz <= 0: raise FormulaError("Fatal: token size is not positive") pos += sz any_rel = not not any_rel if blah: - print >> bk.logfile, "End of formula. level=%d any_rel=%d any_err=%d stack=%r" % \ - (level, not not any_rel, any_err, stack) + print("End of formula. level=%d any_rel=%d any_err=%d stack=%r" % \ + (level, not not any_rel, any_err, stack), file=bk.logfile) if len(stack) >= 2: - print >> bk.logfile, "*** Stack has unprocessed args" - print >> bk.logfile + print("*** Stack has unprocessed args", file=bk.logfile) + print(file=bk.logfile) if len(stack) != 1: result = None @@ -1893,7 +1891,7 @@ def unexpected_opcode(op_arg, oname_arg): #### under deconstruction ### def dump_formula(bk, data, fmlalen, bv, reldelta, blah=0, isname=0): if blah: - print >> bk.logfile, "dump_formula", fmlalen, bv, len(data) + print("dump_formula", fmlalen, bv, len(data), file=bk.logfile) hex_char_dump(data, 0, fmlalen, fout=bk.logfile) assert bv >= 80 #### this function needs updating #### sztab = szdict[bv] @@ -1914,22 +1912,22 @@ def dump_formula(bk, data, fmlalen, bv, reldelta, blah=0, isname=0): sz = sztab[opx] if blah: - print >> bk.logfile, "Pos:%d Op:0x%02x Name:t%s Sz:%d opcode:%02xh optype:%02xh" \ - % (pos, op, oname, sz, opcode, optype) + print("Pos:%d Op:0x%02x Name:t%s Sz:%d opcode:%02xh optype:%02xh" \ + % (pos, op, oname, sz, opcode, optype), file=bk.logfile) if not optype: if 0x01 <= opcode <= 0x02: # tExp, tTbl # reference to a shared formula or table record rowx, colx = unpack("> bk.logfile, " ", (rowx, colx) + if blah: print(" ", (rowx, colx), file=bk.logfile) elif opcode == 0x10: # tList - if blah: print >> bk.logfile, "tList pre", stack + if blah: print("tList pre", stack, file=bk.logfile) assert len(stack) >= 2 bop = stack.pop() aop = stack.pop() spush(aop + bop) - if blah: print >> bk.logfile, "tlist post", stack + if blah: print("tlist post", stack, file=bk.logfile) elif opcode == 0x11: # tRange - if blah: print >> bk.logfile, "tRange pre", stack + if blah: print("tRange pre", stack, file=bk.logfile) assert len(stack) >= 2 bop = stack.pop() aop = stack.pop() @@ -1937,9 +1935,9 @@ def dump_formula(bk, data, fmlalen, bv, reldelta, blah=0, isname=0): assert len(bop) == 1 result = do_box_funcs(tRangeFuncs, aop[0], bop[0]) spush(result) - if blah: print >> bk.logfile, "tRange post", stack + if blah: print("tRange post", stack, file=bk.logfile) elif opcode == 0x0F: # tIsect - if blah: print >> bk.logfile, "tIsect pre", stack + if blah: print("tIsect pre", stack, file=bk.logfile) assert len(stack) >= 2 bop = stack.pop() aop = stack.pop() @@ -1947,7 +1945,7 @@ def dump_formula(bk, data, fmlalen, bv, reldelta, blah=0, isname=0): assert len(bop) == 1 result = do_box_funcs(tIsectFuncs, aop[0], bop[0]) spush(result) - if blah: print >> bk.logfile, "tIsect post", stack + if blah: print("tIsect post", stack, file=bk.logfile) elif opcode == 0x19: # tAttr subop, nc = unpack("> bk.logfile, " subop=%02xh subname=t%s sz=%d nc=%02xh" % (subop, subname, sz, nc) + if blah: print(" subop=%02xh subname=t%s sz=%d nc=%02xh" % (subop, subname, sz, nc), file=bk.logfile) elif opcode == 0x17: # tStr if bv <= 70: nc = BYTES_ORD(data[pos+1]) @@ -1964,10 +1962,10 @@ def dump_formula(bk, data, fmlalen, bv, reldelta, blah=0, isname=0): else: strg, newpos = unpack_unicode_update_pos(data, pos+1, lenlen=1) sz = newpos - pos - if blah: print >> bk.logfile, " sz=%d strg=%r" % (sz, strg) + if blah: print(" sz=%d strg=%r" % (sz, strg), file=bk.logfile) else: if sz <= 0: - print >> bk.logfile, "**** Dud size; exiting ****" + print("**** Dud size; exiting ****", file=bk.logfile) return pos += sz continue @@ -1976,76 +1974,76 @@ def dump_formula(bk, data, fmlalen, bv, reldelta, blah=0, isname=0): elif opcode == 0x01: # tFunc nb = 1 + int(bv >= 40) funcx = unpack("<" + " BH"[nb], data[pos+1:pos+1+nb]) - if blah: print >> bk.logfile, " FuncID=%d" % funcx + if blah: print(" FuncID=%d" % funcx, file=bk.logfile) elif opcode == 0x02: #tFuncVar nb = 1 + int(bv >= 40) nargs, funcx = unpack("> bk.logfile, " FuncID=%d nargs=%d macro=%d prompt=%d" % (funcx, nargs, macro, prompt) + if blah: print(" FuncID=%d nargs=%d macro=%d prompt=%d" % (funcx, nargs, macro, prompt), file=bk.logfile) elif opcode == 0x03: #tName namex = unpack("> bk.logfile, " namex=%d" % namex + if blah: print(" namex=%d" % namex, file=bk.logfile) elif opcode == 0x04: # tRef res = get_cell_addr(data, pos+1, bv, reldelta) - if blah: print >> bk.logfile, " ", res + if blah: print(" ", res, file=bk.logfile) elif opcode == 0x05: # tArea res = get_cell_range_addr(data, pos+1, bv, reldelta) - if blah: print >> bk.logfile, " ", res + if blah: print(" ", res, file=bk.logfile) elif opcode == 0x09: # tMemFunc nb = unpack("> bk.logfile, " %d bytes of cell ref formula" % nb + if blah: print(" %d bytes of cell ref formula" % nb, file=bk.logfile) elif opcode == 0x0C: #tRefN res = get_cell_addr(data, pos+1, bv, reldelta=1) # note *ALL* tRefN usage has signed offset for relative addresses any_rel = 1 - if blah: print >> bk.logfile, " ", res + if blah: print(" ", res, file=bk.logfile) elif opcode == 0x0D: #tAreaN res = get_cell_range_addr(data, pos+1, bv, reldelta=1) # note *ALL* tAreaN usage has signed offset for relative addresses any_rel = 1 - if blah: print >> bk.logfile, " ", res + if blah: print(" ", res, file=bk.logfile) elif opcode == 0x1A: # tRef3d refx = unpack("> bk.logfile, " ", refx, res + if blah: print(" ", refx, res, file=bk.logfile) rowx, colx, row_rel, col_rel = res any_rel = any_rel or row_rel or col_rel shx1, shx2 = get_externsheet_local_range(bk, refx, blah) any_err |= shx1 < -1 coords = (shx1, shx2+1, rowx, rowx+1, colx, colx+1) - if blah: print >> bk.logfile, " ", coords + if blah: print(" ", coords, file=bk.logfile) if optype == 1: spush([coords]) elif opcode == 0x1B: # tArea3d refx = unpack("> bk.logfile, " ", refx, res1, res2 + if blah: print(" ", refx, res1, res2, file=bk.logfile) rowx1, colx1, row_rel1, col_rel1 = res1 rowx2, colx2, row_rel2, col_rel2 = res2 any_rel = any_rel or row_rel1 or col_rel1 or row_rel2 or col_rel2 shx1, shx2 = get_externsheet_local_range(bk, refx, blah) any_err |= shx1 < -1 coords = (shx1, shx2+1, rowx1, rowx2+1, colx1, colx2+1) - if blah: print >> bk.logfile, " ", coords + if blah: print(" ", coords, file=bk.logfile) if optype == 1: spush([coords]) elif opcode == 0x19: # tNameX refx, namex = unpack("> bk.logfile, " refx=%d namex=%d" % (refx, namex) + if blah: print(" refx=%d namex=%d" % (refx, namex), file=bk.logfile) elif is_error_opcode(opcode): any_err = 1 else: - if blah: print >> bk.logfile, "FORMULA: /// Not handled yet: t" + oname + if blah: print("FORMULA: /// Not handled yet: t" + oname, file=bk.logfile) any_err = 1 if sz <= 0: - print >> bk.logfile, "**** Dud size; exiting ****" + print("**** Dud size; exiting ****", file=bk.logfile) return pos += sz if blah: - print >> bk.logfile, "End of formula. any_rel=%d any_err=%d stack=%r" % \ - (not not any_rel, any_err, stack) + print("End of formula. any_rel=%d any_err=%d stack=%r" % \ + (not not any_rel, any_err, stack), file=bk.logfile) if len(stack) >= 2: - print >> bk.logfile, "*** Stack has unprocessed args" + print("*** Stack has unprocessed args", file=bk.logfile) # === Some helper functions for displaying cell references === diff --git a/xlrd/sheet.py b/xlrd/sheet.py index 6881058a..1d35e2cf 100644 --- a/xlrd/sheet.py +++ b/xlrd/sheet.py @@ -27,7 +27,7 @@ # 2007-07-11 SJM Allow for BIFF2/3-style FORMAT record in BIFF4/8 file # 2007-04-22 SJM Remove experimental "trimming" facility. -from __future__ import unicode_literals +from __future__ import unicode_literals, print_function from struct import unpack, calcsize import time @@ -673,7 +673,7 @@ def put_cell_ragged(self, rowx, colx, ctype, value, xf_index): if fmt_info: fmt_row[colx] = xf_index except: - print >> self.logfile, "put_cell", rowx, colx + print("put_cell", rowx, colx, file=self.logfile) raise def put_cell_unragged(self, rowx, colx, ctype, value, xf_index): @@ -742,10 +742,10 @@ def put_cell_unragged(self, rowx, colx, ctype, value, xf_index): if self.formatting_info: self._cell_xf_indexes[rowx][colx] = xf_index except: - print >> self.logfile, "put_cell", rowx, colx + print("put_cell", rowx, colx, file=self.logfile) raise except: - print >> self.logfile, "put_cell", rowx, colx + print("put_cell", rowx, colx, file=self.logfile) raise @@ -845,10 +845,9 @@ def read(self, bk): if not fmt_info: continue rowx, bits1, bits2 = local_unpack('> self.logfile, \ - "*** NOTE: ROW record has row index %d; " \ + print("*** NOTE: ROW record has row index %d; " \ "should have 0 <= rowx < %d -- record ignored!" \ - % (rowx, self.utter_max_rows) + % (rowx, self.utter_max_rows), file=self.logfile) continue key = (bits1, bits2) r = rowinfo_sharing_dict.get(key) @@ -889,7 +888,7 @@ def read(self, bk): "**ROW %d %d %d\n", self.number, rowx, r.xf_index) if blah_rows: - print >> self.logfile, 'ROW', rowx, bits1, bits2 + print('ROW', rowx, bits1, bits2, file=self.logfile) r.dump(self.logfile, header="--- sh #%d, rowx=%d ---" % (self.number, rowx)) elif rc in XL_FORMULA_OPCODES: # 06, 0206, 0406 @@ -987,10 +986,9 @@ def read(self, bk): if not(0 <= first_colx <= last_colx <= 256): # Note: 256 instead of 255 is a common mistake. # We silently ignore the non-existing 257th column in that case. - print >> self.logfile, \ - "*** NOTE: COLINFO record has first col index %d, last %d; " \ + print("*** NOTE: COLINFO record has first col index %d, last %d; " \ "should have 0 <= first <= last <= 255 -- record ignored!" \ - % (first_colx, last_colx) + % (first_colx, last_colx), file=self.logfile) del c continue upkbits(c, flags, ( @@ -1017,12 +1015,12 @@ def read(self, bk): c.dump(self.logfile, header='===') elif rc == XL_DEFCOLWIDTH: self.defcolwidth, = local_unpack("> self.logfile, 'DEFCOLWIDTH', self.defcolwidth + if 0: print('DEFCOLWIDTH', self.defcolwidth, file=self.logfile) elif rc == XL_STANDARDWIDTH: if data_len != 2: - print >> self.logfile, '*** ERROR *** STANDARDWIDTH', data_len, repr(data) + print('*** ERROR *** STANDARDWIDTH', data_len, repr(data), file=self.logfile) self.standardwidth, = local_unpack("> self.logfile, 'STANDARDWIDTH', self.standardwidth + if 0: print('STANDARDWIDTH', self.standardwidth, file=self.logfile) elif rc == XL_GCW: if not fmt_info: continue # useless w/o COLINFO assert data_len == 34 @@ -1036,7 +1034,7 @@ def read(self, bk): self.gcw = tuple(gcw) if 0: showgcw = "".join(map(lambda x: "F "[x], gcw)).rstrip().replace(' ', '.') - print >> self.logfile, "GCW:", showgcw + print("GCW:", showgcw, file=self.logfile) elif rc == XL_BLANK: if not fmt_info: continue rowx, colx, xf_index = local_unpack('> self.logfile, "SHEET.READ: EOF" + if DEBUG: print("SHEET.READ: EOF", file=self.logfile) eof_found = 1 break elif rc == XL_OBJ: @@ -1099,14 +1097,13 @@ def read(self, bk): elif rc in bofcodes: ##### EMBEDDED BOF ##### version, boftype = local_unpack('> self.logfile, \ - "*** Unexpected embedded BOF (0x%04x) at offset %d: version=0x%04x type=0x%04x" \ - % (rc, bk._position - data_len - 4, version, boftype) + print("*** Unexpected embedded BOF (0x%04x) at offset %d: version=0x%04x type=0x%04x" \ + % (rc, bk._position - data_len - 4, version, boftype), file=self.logfile) while 1: code, data_len, data = bk.get_record_parts() if code == XL_EOF: break - if DEBUG: print >> self.logfile, "---> found EOF" + if DEBUG: print("---> found EOF", file=self.logfile) elif rc == XL_COUNTRY: bk.handle_country(data) elif rc == XL_LABELRANGES: @@ -1122,13 +1119,13 @@ def read(self, bk): row1x, rownx, col1x, colnx, array_flags, tokslen = \ local_unpack("> self.logfile, "ARRAY:", row1x, rownx, col1x, colnx, array_flags + print("ARRAY:", row1x, rownx, col1x, colnx, array_flags, file=self.logfile) # dump_formula(bk, data[14:], tokslen, bv, reldelta=0, blah=1) elif rc == XL_SHRFMLA: row1x, rownx, col1x, colnx, nfmlas, tokslen = \ local_unpack("> self.logfile, "SHRFMLA (main):", row1x, rownx, col1x, colnx, nfmlas + print("SHRFMLA (main):", row1x, rownx, col1x, colnx, nfmlas, file=self.logfile) decompile_formula(bk, data[10:], tokslen, FMLA_TYPE_SHARED, blah=1, browx=rowx, bcolx=colx, r1c1=r1c1) elif rc == XL_CONDFMT: @@ -1279,10 +1276,10 @@ def read(self, bk): result = int_floor_div(num * 100, den) if not(10 <= result <= 400): if DEBUG or self.verbosity >= 0: - print >> self.logfile, ( + print(( "WARNING *** SCL rcd sheet %d: should have 0.1 <= num/den <= 4; got %d/%d" % (self.number, num, den) - ) + ), file=self.logfile) result = 100 self.scl_mag_factor = result elif rc == XL_PANE: @@ -1371,10 +1368,9 @@ def read(self, bk): if not fmt_info: continue rowx, bits1, bits2 = local_unpack('> self.logfile, \ - "*** NOTE: ROW_B2 record has row index %d; " \ + print("*** NOTE: ROW_B2 record has row index %d; " \ "should have 0 <= rowx < %d -- record ignored!" \ - % (rowx, self.utter_max_rows) + % (rowx, self.utter_max_rows), file=self.logfile) continue if not (bits2 & 1): # has_default_xf_index is false xf_index = -1 @@ -1405,7 +1401,7 @@ def read(self, bk): "**ROW %d %d %d\n", self.number, rowx, r.xf_index) if blah_rows: - print >> self.logfile, 'ROW_B2', rowx, bits1, has_defaults + print('ROW_B2', rowx, bits1, has_defaults, file=self.logfile) r.dump(self.logfile, header="--- sh #%d, rowx=%d ---" % (self.number, rowx)) elif rc == XL_COLWIDTH: # BIFF2 only @@ -1413,10 +1409,9 @@ def read(self, bk): first_colx, last_colx, width\ = local_unpack("> self.logfile, \ - "*** NOTE: COLWIDTH record has first col index %d, last %d; " \ + print("*** NOTE: COLWIDTH record has first col index %d, last %d; " \ "should have first <= last -- record ignored!" \ - % (first_colx, last_colx) + % (first_colx, last_colx), file=self.logfile) continue for colx in xrange(first_colx, last_colx+1): if self.colinfo_map.has_key(colx): @@ -1442,10 +1437,9 @@ def read(self, bk): self.number, first_colx, last_colx ) if not(0 <= first_colx < last_colx <= 256): - print >> self.logfile, \ - "*** NOTE: COLUMNDEFAULT record has first col index %d, last %d; " \ + print("*** NOTE: COLUMNDEFAULT record has first col index %d, last %d; " \ "should have 0 <= first < last <= 256" \ - % (first_colx, last_colx) + % (first_colx, last_colx), file=self.logfile) last_colx = min(last_colx, 256) for colx in xrange(first_colx, last_colx): offset = 4 + 3 * (colx - first_colx) @@ -1529,10 +1523,10 @@ def update_cooked_mag_factors(self): zoom = self.cached_normal_view_mag_factor if not (10 <= zoom <=400): if blah: - print >> self.logfile, ( + print(( "WARNING *** WINDOW2 rcd sheet %d: Bad cached_normal_view_mag_factor: %d" % (self.number, self.cached_normal_view_mag_factor) - ) + ), file=self.logfile) zoom = self.cooked_page_break_preview_mag_factor self.cooked_normal_view_mag_factor = zoom else: @@ -1547,10 +1541,10 @@ def update_cooked_mag_factors(self): zoom = 60 elif not (10 <= zoom <= 400): if blah: - print >> self.logfile, ( + print(( "WARNING *** WINDOW2 rcd sheet %r: Bad cached_page_break_preview_mag_factor: %r" % (self.number, self.cached_page_break_preview_mag_factor) - ) + ), file=self.logfile) zoom = self.cooked_normal_view_mag_factor self.cooked_page_break_preview_mag_factor = zoom @@ -1706,13 +1700,13 @@ def computed_column_width(self, colx): def handle_hlink(self, data): # DEBUG = 1 - if DEBUG: print >> self.logfile, "\n=== hyperlink ===" + if DEBUG: print("\n=== hyperlink ===", file=self.logfile) record_size = len(data) h = Hyperlink() h.frowx, h.lrowx, h.fcolx, h.lcolx, guid0, dummy, options = unpack('> self.logfile, "options: %08X" % options + if DEBUG: print("options: %08X" % options, file=self.logfile) offset = 32 def get_nul_terminated_unicode(buf, ofs): @@ -1731,7 +1725,7 @@ def get_nul_terminated_unicode(buf, ofs): if (options & 1) and not (options & 0x100): # HasMoniker and not MonikerSavedAsString # an OLEMoniker structure clsid, = unpack('<16s', data[offset:offset + 16]) - if DEBUG: print >> self.logfile, "clsid=%r" %clsid + if DEBUG: print("clsid=%r" %clsid, file=self.logfile) offset += 16 if clsid == BYTES_LITERAL("\xE0\xC9\xEA\x79\xF9\xBA\xCE\x11\x8C\x82\x00\xAA\x00\x4B\xA9\x0B"): # E0H C9H EAH 79H F9H BAH CEH 11H 8CH 82H 00H AAH 00H 4BH A9H 0BH @@ -1740,18 +1734,18 @@ def get_nul_terminated_unicode(buf, ofs): nbytes = unpack('> self.logfile, "initial url=%r len=%d" % (h.url_or_path, len(h.url_or_path)) + if DEBUG: print("initial url=%r len=%d" % (h.url_or_path, len(h.url_or_path)), file=self.logfile) endpos = h.url_or_path.find('\x00') - if DEBUG: print >> self.logfile, "endpos=%d" % endpos + if DEBUG: print("endpos=%d" % endpos, file=self.logfile) h.url_or_path = h.url_or_path[:endpos] true_nbytes = 2 * (endpos + 1) offset += true_nbytes extra_nbytes = nbytes - true_nbytes extra_data = data[offset:offset + extra_nbytes] offset += extra_nbytes - if DEBUG: print >> self.logfile, "url=%r" % h.url_or_path - if DEBUG: print >> self.logfile, "extra=%r" % extra_data - if DEBUG: print >> self.logfile, "nbytes=%d true_nbytes=%d extra_nbytes=%d" % (nbytes, true_nbytes, extra_nbytes) + if DEBUG: print("url=%r" % h.url_or_path, file=self.logfile) + if DEBUG: print("extra=%r" % extra_data, file=self.logfile) + if DEBUG: print("nbytes=%d true_nbytes=%d extra_nbytes=%d" % (nbytes, true_nbytes, extra_nbytes), file=self.logfile) assert extra_nbytes in (24, 0) elif clsid == BYTES_LITERAL("\x03\x03\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46"): # file moniker @@ -1759,12 +1753,12 @@ def get_nul_terminated_unicode(buf, ofs): uplevels, nbytes = unpack("> self.logfile, "uplevels=%d shortpath=%r" % (uplevels, shortpath) + if DEBUG: print("uplevels=%d shortpath=%r" % (uplevels, shortpath), file=self.logfile) offset += nbytes offset += 24 # OOo: "unknown byte sequence" # above is version 0xDEAD + 20 reserved zero bytes sz = unpack('> self.logfile, "sz=%d" % sz + if DEBUG: print("sz=%d" % sz, file=self.logfile) offset += 4 if sz: xl = unpack('> self.logfile, "*** unknown clsid %r" % clsid + print("*** unknown clsid %r" % clsid, file=self.logfile) elif options & 0x163 == 0x103: # UNC h.type = 'unc' h.url_or_path, offset = get_nul_terminated_unicode(data, offset) @@ -2002,7 +1996,7 @@ def handle_txo(self, data): del o.rich_text_runlist[-1] if OBJ_MSO_DEBUG: o.dump(self.logfile, header="=== MSTxo ===", footer= " ") - print >> self.logfile, o.rich_text_runlist + print(o.rich_text_runlist, file=self.logfile) return o def handle_feat11(self, data): @@ -2025,7 +2019,7 @@ def handle_feat11(self, data): assert rt == 0x872 assert fHdr == 0 assert Ref1 == Ref0 - print >> self.logfile, "FEAT11: grbitFrt=%d Ref0=%r cref=%d cbFeatData=%d" % (grbitFrt, Ref0, cref, cbFeatData) + print("FEAT11: grbitFrt=%d Ref0=%r cref=%d cbFeatData=%d" % (grbitFrt, Ref0, cref, cbFeatData), file=self.logfile) # lt: Table data source type: # =0 for Excel Worksheet Table =1 for read-write SharePoint linked List # =2 for XML mapper Table =3 for Query Table @@ -2046,12 +2040,12 @@ def handle_feat11(self, data): (lt, idList, crwHeader, crwTotals, idFieldNext, cbFSData, rupBuild, unusedShort, listFlags, lPosStmCache, cbStmCache, cchStmCache, lem, rgbHashParam, cchName) = unpack('> self.logfile, "lt=%d idList=%d crwHeader=%d crwTotals=%d idFieldNext=%d cbFSData=%d\n"\ + print("lt=%d idList=%d crwHeader=%d crwTotals=%d idFieldNext=%d cbFSData=%d\n"\ "rupBuild=%d unusedShort=%d listFlags=%04X lPosStmCache=%d cbStmCache=%d\n"\ "cchStmCache=%d lem=%d rgbHashParam=%r cchName=%d" % ( lt, idList, crwHeader, crwTotals, idFieldNext, cbFSData, rupBuild, unusedShort,listFlags, lPosStmCache, cbStmCache, - cchStmCache, lem, rgbHashParam, cchName) + cchStmCache, lem, rgbHashParam, cchName), file=self.logfile) class MSODrawing(BaseObject): pass diff --git a/xlrd/xlsx.py b/xlrd/xlsx.py index 5a3f488f..c4d241d6 100644 --- a/xlrd/xlsx.py +++ b/xlrd/xlsx.py @@ -5,6 +5,8 @@ #

This module is part of the xlrd package, which is released under a BSD-style licence.

## +from __future__ import print_function + DEBUG = 0 import sys, zipfile, pprint @@ -53,7 +55,7 @@ def ensure_elementtree_imported(verbosity, logfile): for item in ET.__dict__.keys() if item.lower().replace('_', '') == 'version' ]) - print >> logfile, ET.__file__, ET.__name__, etree_version, ET_has_iterparse + print(ET.__file__, ET.__name__, etree_version, ET_has_iterparse, file=logfile) def split_tag(tag): pos = tag.rfind('}') + 1 @@ -244,7 +246,7 @@ def make_name_access_maps(bk): raise XLRDError(msg) else: if bk.verbosity: - print >> bk.logfile, msg + print(msg, file=bk.logfile) name_and_scope_map[key] = nobj if name_map.has_key(name_lcase): name_map[name_lcase].append((nobj.scope, nobj)) @@ -438,7 +440,7 @@ def process_stream_iterparse(self, stream, heading=None): self.dumpout('Entries in SST: %d', len(sst)) if self.verbosity >= 3: for x, s in enumerate(sst): - print "SST x=%d s=%r" % (x, s) + print("SST x=%d s=%r" % (x, s)) def process_stream_findall(self, stream, heading=None): if self.verbosity >= 2 and heading is not None: @@ -736,7 +738,7 @@ def open_workbook_2007_xml( bk.on_demand = on_demand if on_demand: if verbosity: - print >> bk.logfile, "WARNING *** on_demand=True not yet implemented; falling back to False" + print("WARNING *** on_demand=True not yet implemented; falling back to False", file=bk.logfile) bk.on_demand = False bk.ragged_rows = ragged_rows From f26169741d8db4d86f8fd5d8249c01907519280a Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 26 Oct 2012 14:32:46 +0100 Subject: [PATCH 022/319] More syntax fixes --- xlrd/formatting.py | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/xlrd/formatting.py b/xlrd/formatting.py index 8a0b5cf0..5084d9b0 100644 --- a/xlrd/formatting.py +++ b/xlrd/formatting.py @@ -22,7 +22,7 @@ # 2007-09-08 SJM Work around corrupt STYLE record # 2007-07-11 SJM Allow for BIFF2/3-style FORMAT record in BIFF4/8 file -from __future__ import print_function +from __future__ import print_function, unicode_literals DEBUG = 0 import copy, re @@ -221,7 +221,7 @@ class Font(BaseObject, EqNeAttrs): italic = 0 ## # The name of the font. Example: u"Arial" - name = u"" + name = "" ## # 1 = Characters are struck out. struck_out = 0 @@ -261,7 +261,7 @@ def handle_font(book, data): k = len(book.font_list) if k == 4: f = Font() - f.name = u'Dummy Font' + f.name = 'Dummy Font' f.font_index = k book.font_list.append(f) k += 1 @@ -343,7 +343,7 @@ class Format(BaseObject, EqNeAttrs): type = FUN ## # The format string - format_str = u'' + format_str = '' def __init__(self, format_key, ty, format_str): self.format_key = format_key @@ -416,29 +416,29 @@ def __init__(self, format_key, ty, format_str): std_format_code_types[x] = ty del lo, hi, ty, x -date_chars = u'ymdhs' # year, month/minute, day, hour, second +date_chars = 'ymdhs' # year, month/minute, day, hour, second date_char_dict = {} for _c in date_chars + date_chars.upper(): date_char_dict[_c] = 5 del _c, date_chars skip_char_dict = {} -for _c in u'$-+/(): ': +for _c in '$-+/(): ': skip_char_dict[_c] = 1 num_char_dict = { - u'0': 5, - u'#': 5, - u'?': 5, + '0': 5, + '#': 5, + '?': 5, } non_date_formats = { - u'0.00E+00':1, - u'##0.0E+0':1, - u'General' :1, - u'GENERAL' :1, # OOo Calc 1.1.4 does this. - u'general' :1, # pyExcelerator 0.6.3 does this. - u'@' :1, + '0.00E+00':1, + '##0.0E+0':1, + 'General' :1, + 'GENERAL' :1, # OOo Calc 1.1.4 does this. + 'general' :1, # pyExcelerator 0.6.3 does this. + '@' :1, } fmt_bracketed_sub = re.compile(r'\[[^]]*\]').sub @@ -465,16 +465,16 @@ def ignorable(c): for c in fmt: if state == 0: - if c == u'"': + if c == '"': state = 1 - elif c in ur"\_*": + elif c in r"\_*": state = 2 elif ignorable(c): pass else: s += c elif state == 1: - if c == u'"': + if c == '"': state = 0 elif state == 2: # Ignore char after backslash, underscore or asterisk @@ -755,7 +755,7 @@ def handle_xf(self, data): (16, 0x007f0000, 'left_colour_index'), (23, 0x3f800000, 'right_colour_index'), (30, 0x40000000, 'diag_down'), - (31, 0x80000000L, 'diag_up'), + (31, 0x80000000, 'diag_up'), )) upkbits(xf.border, pkd_brdbkg2, ( (0, 0x0000007F, 'top_colour_index'), @@ -764,7 +764,7 @@ def handle_xf(self, data): (21, 0x01E00000, 'diag_line_style'), )) upkbitsL(xf.background, pkd_brdbkg2, ( - (26, 0xFC000000L, 'fill_pattern'), + (26, 0xFC000000, 'fill_pattern'), )) upkbits(xf.background, pkd_brdbkg3, ( (0, 0x007F, 'pattern_colour_index'), @@ -805,7 +805,7 @@ def handle_xf(self, data): )) upkbitsL(xf.border, pkd_brdbkg1, ( (22, 0x01C00000, 'bottom_line_style'), - (25, 0xFE000000L, 'bottom_colour_index'), + (25, 0xFE000000, 'bottom_colour_index'), )) upkbits(xf.border, pkd_brdbkg2, ( ( 0, 0x00000007, 'top_line_style'), @@ -856,7 +856,7 @@ def handle_xf(self, data): (16, 0x00070000, 'bottom_line_style'), (19, 0x00F80000, 'bottom_colour_index'), (24, 0x07000000, 'right_line_style'), - (27, 0xF8000000L, 'right_colour_index'), + (27, 0xF8000000, 'right_colour_index'), )) elif bv == 30: unpack_fmt = ' Date: Fri, 26 Oct 2012 14:38:51 +0100 Subject: [PATCH 023/319] More syntax fixes --- xlrd/compdoc.py | 2 +- xlrd/xldate.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/xlrd/compdoc.py b/xlrd/compdoc.py index 8d16bbf5..260cb78c 100644 --- a/xlrd/compdoc.py +++ b/xlrd/compdoc.py @@ -46,7 +46,7 @@ def __init__(self, DID, dent, DEBUG=0, logfile=sys.stdout): (self.first_SID, self.tot_size) = \ unpack(' Date: Fri, 26 Oct 2012 14:41:33 +0100 Subject: [PATCH 024/319] More unicode literal fixes --- xlrd/xlsx.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/xlrd/xlsx.py b/xlrd/xlsx.py index c4d241d6..73640aa7 100644 --- a/xlrd/xlsx.py +++ b/xlrd/xlsx.py @@ -5,7 +5,7 @@ #

This module is part of the xlrd package, which is released under a BSD-style licence.

## -from __future__ import print_function +from __future__ import print_function, unicode_literals DEBUG = 0 @@ -108,7 +108,7 @@ def cell_name_to_rowx_colx(cell_name, letter_value=_UPPERCASE_1_REL_INDEX): U_DC = "{http://purl.org/dc/elements/1.1/}" U_DCTERMS = "{http://purl.org/dc/terms/}" XML_SPACE_ATTR = "{http://www.w3.org/XML/1998/namespace}space" -XML_WHITESPACE = u"\t\n \r" +XML_WHITESPACE = "\t\n \r" X12_MAX_ROWS = 2 ** 20 X12_MAX_COLS = 2 ** 14 V_TAG = U_SSML12 + 'v' # cell child: value @@ -119,7 +119,7 @@ def unescape(s, subber=re.compile(r'_x[0-9A-Fa-f]{4,4}_', re.UNICODE).sub, repl=lambda mobj: unichr(int(mobj.group(0)[2:6], 16)), ): - if u"_" in s: + if "_" in s: return subber(repl, s) return s @@ -138,7 +138,7 @@ def strip_xml_ws(s, def cooked_text(self, elem): t = elem.text if t is None: - return u'' + return '' if elem.get(XML_SPACE_ATTR) != 'preserve': t = strip_xml_ws(t) return unicode(unescape(t)) @@ -147,7 +147,7 @@ def cooked_text(self, elem): def cooked_text(self, elem): t = elem.text if t is None: - return u'' + return '' if elem.get(XML_SPACE_ATTR) != 'preserve': t = t.strip(XML_WHITESPACE) return unicode(unescape(t)) @@ -168,7 +168,7 @@ def get_text_from_si_or_is(self, elem, r_tag=U_SSML12+'r', t_tag=U_SSML12 +'t'): t = cooked_text(self, tnode) if t: accum.append(t) - return u''.join(accum) + return ''.join(accum) def map_attributes(amap, elem, obj): for xml_attr, obj_attr, cnv_func_or_const in amap: @@ -181,7 +181,7 @@ def map_attributes(amap, elem, obj): setattr(obj, obj_attr, cooked_value) def cnv_ST_Xstring(s): - if s is None: return u"" + if s is None: return "" return unicode(s) def cnv_xsd_unsignedInt(s): @@ -359,7 +359,7 @@ def do_defined_name(self, elem): map_attributes(_defined_name_attribute_map, elem, nobj) if nobj.scope is None: nobj.scope = -1 # global - if nobj.name.startswith(u"_xlnm."): + if nobj.name.startswith("_xlnm."): nobj.builtin = 1 if self.verbosity >= 2: nobj.dump(header='=== Name object ===') From 8b9eaa08b9f864800919d91a0da316f1cb0c6572 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 26 Oct 2012 14:42:42 +0100 Subject: [PATCH 025/319] Don't use 2to3 --- setup.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/setup.py b/setup.py index 76d7ee5b..a1b837e7 100644 --- a/setup.py +++ b/setup.py @@ -76,8 +76,4 @@ def mkargs(**kwargs): ) args.update(args24) -if python_version >= (3,): - from distutils.command.build_py import build_py_2to3 - args['cmdclass'] = {'build_py': build_py_2to3} - setup(**args) From b461b1e9925e0ba0d8ec446fe5031bff009bed14 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 26 Oct 2012 14:43:00 +0100 Subject: [PATCH 026/319] Alias xrange for Python 3 --- xlrd/timemachine.py | 1 + 1 file changed, 1 insertion(+) diff --git a/xlrd/timemachine.py b/xlrd/timemachine.py index ce7dc493..cc1b1643 100644 --- a/xlrd/timemachine.py +++ b/xlrd/timemachine.py @@ -30,6 +30,7 @@ def fprintf(f, fmt, *vargs): f.write(fmt % vargs) EXCEL_TEXT_TYPES = (str, bytes, bytearray) # xlwt: isinstance(obj, EXCEL_TEXT_TYPES) REPR = ascii + xrange = range else: BYTES_LITERAL = lambda x: x UNICODE_LITERAL = lambda x: x.decode('latin1') From f9bb3badccf83b3a2d5a10b65eb2a3a788d9c7cb Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 26 Oct 2012 14:46:40 +0100 Subject: [PATCH 027/319] Fix more relative imports --- xlrd/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/xlrd/__init__.py b/xlrd/__init__.py index d9ea0284..5ee281be 100644 --- a/xlrd/__init__.py +++ b/xlrd/__init__.py @@ -410,7 +410,7 @@ def open_workbook(filename=None, logfile.write('ZIP component_names:\n') pprint.pprint(component_names, logfile) if 'xl/workbook.xml' in component_names: - import xlsx + from . import xlsx bk = xlsx.open_workbook_2007_xml( zf, component_names, @@ -429,7 +429,7 @@ def open_workbook(filename=None, raise XLRDError('Openoffice.org ODS file; not supported') raise XLRDError('ZIP file contents not a known type of workbook') - import book + from . import book bk = book.open_workbook_xls( filename=filename, logfile=logfile, @@ -451,8 +451,8 @@ def open_workbook(filename=None, # @param unnumbered If true, omit offsets (for meaningful diffs). def dump(filename, outfile=sys.stdout, unnumbered=False): - from book import Book - from biffh import biff_dump + from .book import Book + from .biffh import biff_dump bk = Book() bk.biff2_8_load(filename=filename, logfile=outfile, ) biff_dump(bk.mem, bk.base, bk.stream_len, 0, outfile, unnumbered) @@ -464,8 +464,8 @@ def dump(filename, outfile=sys.stdout, unnumbered=False): # @param outfile An open file, to which the summary is written. def count_records(filename, outfile=sys.stdout): - from book import Book - from biffh import biff_count_records + from .book import Book + from .biffh import biff_count_records bk = Book() bk.biff2_8_load(filename=filename, logfile=outfile, ) biff_count_records(bk.mem, bk.base, bk.stream_len, outfile) From 99aa22b5a5fbeb43e7db544c011f2823fea5a62f Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 26 Oct 2012 14:46:59 +0100 Subject: [PATCH 028/319] Alias unicode for Python 3 --- xlrd/timemachine.py | 1 + 1 file changed, 1 insertion(+) diff --git a/xlrd/timemachine.py b/xlrd/timemachine.py index cc1b1643..6fd20ac4 100644 --- a/xlrd/timemachine.py +++ b/xlrd/timemachine.py @@ -31,6 +31,7 @@ def fprintf(f, fmt, *vargs): EXCEL_TEXT_TYPES = (str, bytes, bytearray) # xlwt: isinstance(obj, EXCEL_TEXT_TYPES) REPR = ascii xrange = range + unicode = lambda b, enc: b.decode(enc) else: BYTES_LITERAL = lambda x: x UNICODE_LITERAL = lambda x: x.decode('latin1') From 2cd01dd93ed0f66c9bd9701db336de1d5d8ab4a2 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 26 Oct 2012 14:49:23 +0100 Subject: [PATCH 029/319] Apply 2to3 has_key fixer --- xlrd/biffh.py | 2 +- xlrd/book.py | 6 +++--- xlrd/formatting.py | 16 ++++++++-------- xlrd/sheet.py | 6 +++--- xlrd/xlsx.py | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/xlrd/biffh.py b/xlrd/biffh.py index 2522f683..f5228db9 100644 --- a/xlrd/biffh.py +++ b/xlrd/biffh.py @@ -641,7 +641,7 @@ def biff_count_records(mem, stream_offset, stream_len, fout=sys.stdout): recname = biff_rec_name_dict.get(rc, None) if recname is None: recname = "Unknown_0x%04X" % rc - if tally.has_key(recname): + if recname in tally: tally[recname] += 1 else: tally[recname] = 1 diff --git a/xlrd/book.py b/xlrd/book.py index 5c4b1f1d..d5a4a478 100644 --- a/xlrd/book.py +++ b/xlrd/book.py @@ -784,7 +784,7 @@ def derive_encoding(self): fprintf(self.logfile, "*** No CODEPAGE record; assuming 1200 (utf_16_le)\n") else: codepage = self.codepage - if encoding_from_codepage.has_key(codepage): + if codepage in encoding_from_codepage: encoding = encoding_from_codepage[codepage] elif 300 <= codepage <= 1999: encoding = 'cp' + str(codepage) @@ -1035,7 +1035,7 @@ def names_epilogue(self): nobj = self.name_obj_list[namex] name_lcase = nobj.name.lower() key = (name_lcase, nobj.scope) - if name_and_scope_map.has_key(key): + if key in name_and_scope_map: msg = 'Duplicate entry %r in name_and_scope_map' % (key, ) if 0: raise XLRDError(msg) @@ -1043,7 +1043,7 @@ def names_epilogue(self): if self.verbosity: print(msg, file=f) name_and_scope_map[key] = nobj - if name_map.has_key(name_lcase): + if name_lcase in name_map: name_map[name_lcase].append((nobj.scope, nobj)) else: name_map[name_lcase] = [(nobj.scope, nobj)] diff --git a/xlrd/formatting.py b/xlrd/formatting.py index 5084d9b0..90e57cd9 100644 --- a/xlrd/formatting.py +++ b/xlrd/formatting.py @@ -483,16 +483,16 @@ def ignorable(c): if book.verbosity >= 4: print("is_date_format_string: reduced format is %r" % s, file=book.logfile) s = fmt_bracketed_sub('', s) - if non_date_formats.has_key(s): + if s in non_date_formats: return False state = 0 separator = ";" got_sep = 0 date_count = num_count = 0 for c in s: - if date_char_dict.has_key(c): + if c in date_char_dict: date_count += date_char_dict[c] - elif num_char_dict.has_key(c): + elif c in num_char_dict: num_count += num_char_dict[c] elif c == separator: got_sep = 1 @@ -612,7 +612,7 @@ def palette_epilogue(book): cx = font.colour_index if cx == 0x7fff: # system window text colour continue - if book.colour_map.has_key(cx): + if cx in book.colour_map: book.colour_indexes_used[cx] = 1 elif book.verbosity: print("Size of colour table:", len(book.colour_map), file=book.logfile) @@ -674,7 +674,7 @@ def check_colour_indexes_in_obj(book, obj, orig_index): if hasattr(nobj, 'dump'): check_colour_indexes_in_obj(book, nobj, orig_index) elif attr.find('colour_index') >= 0: - if book.colour_map.has_key(nobj): + if nobj in book.colour_map: book.colour_indexes_used[nobj] = 1 continue oname = obj.__class__.__name__ @@ -683,7 +683,7 @@ def check_colour_indexes_in_obj(book, obj, orig_index): def fill_in_standard_formats(book): for x in std_format_code_types.keys(): - if not book.format_map.has_key(x): + if x not in book.format_map: ty = std_format_code_types[x] # Note: many standard format codes (mostly CJK date formats) have # format strings that vary by locale; xlrd does not (yet) @@ -955,7 +955,7 @@ def handle_xf(self, data): msg = "WARNING *** XF[%d] is a style XF but parent_style_index is 0x%04x, not 0x0fff\n" fprintf(self.logfile, msg, xf.xf_index, xf.parent_style_index) check_colour_indexes_in_obj(self, xf, xf.xf_index) - if not self.format_map.has_key(xf.format_key): + if xf.format_key not in self.format_map: msg = "WARNING *** XF[%d] unknown (raw) format key (%d, 0x%04x)\n" if self.verbosity: fprintf(self.logfile, msg, @@ -980,7 +980,7 @@ def check_same(book_arg, xf_arg, parent_arg, attr): for xfx in xrange(num_xfs): xf = self.xf_list[xfx] - if not self.format_map.has_key(xf.format_key): + if xf.format_key not in self.format_map: msg = "ERROR *** XF[%d] unknown format key (%d, 0x%04x)\n" fprintf(self.logfile, msg, xf.xf_index, xf.format_key, xf.format_key) diff --git a/xlrd/sheet.py b/xlrd/sheet.py index 1d35e2cf..7c6ede16 100644 --- a/xlrd/sheet.py +++ b/xlrd/sheet.py @@ -1414,7 +1414,7 @@ def read(self, bk): % (first_colx, last_colx), file=self.logfile) continue for colx in xrange(first_colx, last_colx+1): - if self.colinfo_map.has_key(colx): + if colx in self.colinfo_map: c = self.colinfo_map[colx] else: c = Colinfo() @@ -1445,7 +1445,7 @@ def read(self, bk): offset = 4 + 3 * (colx - first_colx) cell_attr = data[offset:offset+3] xf_index = self.fixed_BIFF2_xfindex(cell_attr, rowx=-1, colx=colx) - if self.colinfo_map.has_key(colx): + if colx in self.colinfo_map: c = self.colinfo_map[colx] else: c = Colinfo() @@ -1592,7 +1592,7 @@ def insert_new_BIFF20_xf(self, cell_attr, style=0): book.xf_list.append(xf) if blah: xf.dump(self.logfile, header="=== Faked XF %d ===" % xfx, footer="======") - if not book.format_map.has_key(xf.format_key): + if xf.format_key not in book.format_map: if xf.format_key: msg = "ERROR *** XF[%d] unknown format key (%d, 0x%04x)\n" fprintf(self.logfile, msg, diff --git a/xlrd/xlsx.py b/xlrd/xlsx.py index 73640aa7..28f97e2f 100644 --- a/xlrd/xlsx.py +++ b/xlrd/xlsx.py @@ -240,7 +240,7 @@ def make_name_access_maps(bk): nobj = bk.name_obj_list[namex] name_lcase = nobj.name.lower() key = (name_lcase, nobj.scope) - if name_and_scope_map.has_key(key): + if key in name_and_scope_map: msg = 'Duplicate entry %r in name_and_scope_map' % (key, ) if 0: raise XLRDError(msg) @@ -248,7 +248,7 @@ def make_name_access_maps(bk): if bk.verbosity: print(msg, file=bk.logfile) name_and_scope_map[key] = nobj - if name_map.has_key(name_lcase): + if name_lcase in name_map: name_map[name_lcase].append((nobj.scope, nobj)) else: name_map[name_lcase] = [(nobj.scope, nobj)] From b111025a6a4a00d0d07e89b37307ad6fbe7dc161 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 26 Oct 2012 14:52:05 +0100 Subject: [PATCH 030/319] Fix for sorting items from dictionary --- xlrd/formatting.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xlrd/formatting.py b/xlrd/formatting.py index 90e57cd9..bd746ee5 100644 --- a/xlrd/formatting.py +++ b/xlrd/formatting.py @@ -668,8 +668,7 @@ def handle_style(book, data): % (built_in, xf_index, built_in_id, level, name), file=book.logfile) def check_colour_indexes_in_obj(book, obj, orig_index): - alist = obj.__dict__.items() - alist.sort() + alist = sorted(obj.__dict__.items()) for attr, nobj in alist: if hasattr(nobj, 'dump'): check_colour_indexes_in_obj(book, nobj, orig_index) From 96418b385748977774b7afb20ea4cdcb1981d4bf Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 26 Oct 2012 14:59:10 +0100 Subject: [PATCH 031/319] Use UNICODE_LITERAL in xlrd.formatting --- xlrd/formatting.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/xlrd/formatting.py b/xlrd/formatting.py index bd746ee5..56cc526e 100644 --- a/xlrd/formatting.py +++ b/xlrd/formatting.py @@ -22,7 +22,7 @@ # 2007-09-08 SJM Work around corrupt STYLE record # 2007-07-11 SJM Allow for BIFF2/3-style FORMAT record in BIFF4/8 file -from __future__ import print_function, unicode_literals +from __future__ import print_function DEBUG = 0 import copy, re @@ -221,7 +221,7 @@ class Font(BaseObject, EqNeAttrs): italic = 0 ## # The name of the font. Example: u"Arial" - name = "" + name = UNICODE_LITERAL("") ## # 1 = Characters are struck out. struck_out = 0 @@ -261,7 +261,7 @@ def handle_font(book, data): k = len(book.font_list) if k == 4: f = Font() - f.name = 'Dummy Font' + f.name = UNICODE_LITERAL('Dummy Font') f.font_index = k book.font_list.append(f) k += 1 @@ -343,7 +343,7 @@ class Format(BaseObject, EqNeAttrs): type = FUN ## # The format string - format_str = '' + format_str = UNICODE_LITERAL('') def __init__(self, format_key, ty, format_str): self.format_key = format_key @@ -416,29 +416,29 @@ def __init__(self, format_key, ty, format_str): std_format_code_types[x] = ty del lo, hi, ty, x -date_chars = 'ymdhs' # year, month/minute, day, hour, second +date_chars = UNICODE_LITERAL('ymdhs') # year, month/minute, day, hour, second date_char_dict = {} for _c in date_chars + date_chars.upper(): date_char_dict[_c] = 5 del _c, date_chars skip_char_dict = {} -for _c in '$-+/(): ': +for _c in UNICODE_LITERAL('$-+/(): '): skip_char_dict[_c] = 1 num_char_dict = { - '0': 5, - '#': 5, - '?': 5, + UNICODE_LITERAL('0'): 5, + UNICODE_LITERAL('#'): 5, + UNICODE_LITERAL('?'): 5, } non_date_formats = { - '0.00E+00':1, - '##0.0E+0':1, - 'General' :1, - 'GENERAL' :1, # OOo Calc 1.1.4 does this. - 'general' :1, # pyExcelerator 0.6.3 does this. - '@' :1, + UNICODE_LITERAL('0.00E+00'):1, + UNICODE_LITERAL('##0.0E+0'):1, + UNICODE_LITERAL('General') :1, + UNICODE_LITERAL('GENERAL') :1, # OOo Calc 1.1.4 does this. + UNICODE_LITERAL('general') :1, # pyExcelerator 0.6.3 does this. + UNICODE_LITERAL('@') :1, } fmt_bracketed_sub = re.compile(r'\[[^]]*\]').sub @@ -465,16 +465,16 @@ def ignorable(c): for c in fmt: if state == 0: - if c == '"': + if c == UNICODE_LITERAL('"'): state = 1 - elif c in r"\_*": + elif c in UNICODE_LITERAL(r"\_*"): state = 2 elif ignorable(c): pass else: s += c elif state == 1: - if c == '"': + if c == UNICODE_LITERAL('"'): state = 0 elif state == 2: # Ignore char after backslash, underscore or asterisk From 6117bb33c9c3d7472172bdade45b308fbdd80f5a Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 26 Oct 2012 15:05:55 +0100 Subject: [PATCH 032/319] Use UNICODE_LITERAL in xlrd.book --- xlrd/book.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/xlrd/book.py b/xlrd/book.py index d5a4a478..960463fb 100644 --- a/xlrd/book.py +++ b/xlrd/book.py @@ -4,7 +4,7 @@ #

This module is part of the xlrd package, which is released under a # BSD-style licence.

-from __future__ import unicode_literals, print_function +from __future__ import print_function from .timemachine import * from .biffh import * @@ -43,7 +43,7 @@ SUPPORTED_VERSIONS = (80, 70, 50, 45, 40, 30, 21, 20) -code_from_builtin_name = { +_code_from_builtin_name = { "Consolidate_Area": "\x00", "Auto_Open": "\x01", "Auto_Close": "\x02", @@ -60,9 +60,13 @@ "_FilterDatabase": "\x0D", } builtin_name_from_code = {} -for _bin, _bic in code_from_builtin_name.items(): +code_from_builtin_name = {} +for _bin, _bic in _code_from_builtin_name.items(): + _bin = UNICODE_LITERAL(_bin) + _bic = UNICODE_LITERAL(_bic) + code_from_builtin_name[_bin] = _bic builtin_name_from_code[_bic] = _bin -del _bin, _bic +del _bin, _bic, _code_from_builtin_name def open_workbook_xls(filename=None, logfile=sys.stdout, verbosity=0, pickleable=True, use_mmap=USE_MMAP, @@ -209,7 +213,7 @@ class Name(BaseObject): ## # A Unicode string. If builtin, decoded as per OOo docs. - name = "" + name = UNICODE_LITERAL("") ## # An 8-bit string. @@ -343,7 +347,7 @@ class Book(BaseObject): ## # What (if anything) is recorded as the name of the last user to save the file. - user_name = '' + user_name = UNICODE_LITERAL('') ## # A list of Font class instances, each corresponding to a FONT record. @@ -615,13 +619,14 @@ def biff2_8_load(self, filename=None, file_contents=None, cd = compdoc.CompDoc(self.filestr, logfile=self.logfile) if USE_FANCY_CD: for qname in ['Workbook', 'Book']: - self.mem, self.base, self.stream_len = cd.locate_named_stream(qname) + self.mem, self.base, self.stream_len = \ + cd.locate_named_stream(UNICODE_LITERAL(qname)) if self.mem: break else: raise XLRDError("Can't find workbook in OLE2 compound document") else: for qname in ['Workbook', 'Book']: - self.mem = cd.get_named_stream(qname) + self.mem = cd.get_named_stream(UNICODE_LITERAL(qname)) if self.mem: break else: raise XLRDError("Can't find workbook in OLE2 compound document") @@ -705,7 +710,7 @@ def get_sheets(self): def fake_globals_get_sheet(self): # for BIFF 4.0 and earlier formatting.initialise_book(self) - fake_sheet_name = 'Sheet 1' + fake_sheet_name = UNICODE_LITERAL('Sheet 1') self._sheet_names = [fake_sheet_name] self._sh_abs_posn = [0] self._sheet_visibility = [0] # one sheet, visible @@ -1339,7 +1344,7 @@ def expand_cell_address(inrow, incol): def colname(colx, _A2Z="ABCDEFGHIJKLMNOPQRSTUVWXYZ"): assert colx >= 0 - name = '' + name = UNICODE_LITERAL('') while 1: quot, rem = divmod(colx, 26) name = _A2Z[rem] + name @@ -1385,7 +1390,7 @@ def unpack_SST_table(datatab, nstrings): if options & 0x04: # phonetic phosz = local_unpack(' Date: Fri, 26 Oct 2012 15:11:36 +0100 Subject: [PATCH 033/319] Use UNICODE_LITERAL in xlrd.sheet --- xlrd/sheet.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/xlrd/sheet.py b/xlrd/sheet.py index 7c6ede16..be3724ae 100644 --- a/xlrd/sheet.py +++ b/xlrd/sheet.py @@ -27,7 +27,7 @@ # 2007-07-11 SJM Allow for BIFF2/3-style FORMAT record in BIFF4/8 file # 2007-04-22 SJM Remove experimental "trimming" facility. -from __future__ import unicode_literals, print_function +from __future__ import print_function from struct import unpack, calcsize import time @@ -1484,7 +1484,7 @@ def string_record_contents(self, data): if bv < 80: enc = bk.encoding or bk.derive_encoding() nchars_found = 0 - result = "" + result = UNICODE_LITERAL("") while 1: if bv >= 80: flag = BYTES_ORD(data[offset]) & 1 @@ -1597,7 +1597,7 @@ def insert_new_BIFF20_xf(self, cell_attr, style=0): msg = "ERROR *** XF[%d] unknown format key (%d, 0x%04x)\n" fprintf(self.logfile, msg, xf.xf_index, xf.format_key, xf.format_key) - fmt = Format(xf.format_key, FUN, "General") + fmt = Format(xf.format_key, FUN, UNICODE_LITERAL("General")) book.format_map[xf.format_key] = fmt book.format_list.append(fmt) cellty_from_fmtty = { @@ -1730,7 +1730,7 @@ def get_nul_terminated_unicode(buf, ofs): if clsid == BYTES_LITERAL("\xE0\xC9\xEA\x79\xF9\xBA\xCE\x11\x8C\x82\x00\xAA\x00\x4B\xA9\x0B"): # E0H C9H EAH 79H F9H BAH CEH 11H 8CH 82H 00H AAH 00H 4BH A9H 0BH # URL Moniker - h.type = 'url' + h.type = UNICODE_LITERAL('url') nbytes = unpack('