├── tests ├── expected │ ├── xlrd │ │ ├── errors.txt │ │ ├── large_files.txt │ │ ├── emptyblank.txt │ │ ├── utilities.txt │ │ ├── cell_access.txt │ │ ├── open.txt │ │ ├── introspect_sheet.txt │ │ ├── simple.txt │ │ ├── introspect_book.txt │ │ ├── dates.txt │ │ ├── sheet_iteration.txt │ │ └── cell_types.txt │ ├── xlutils │ │ ├── styles.txt │ │ ├── copy │ │ │ └── output.xls │ │ ├── display.txt │ │ └── filter │ │ │ └── filtered-source.xls │ └── xlwt │ │ ├── zoom │ │ └── zoom.xls │ │ ├── panes │ │ └── panes.xls │ │ ├── images │ │ └── images.xls │ │ ├── merged │ │ └── merged.xls │ │ ├── simple │ │ └── simple.xls │ │ ├── borders │ │ └── borders.xls │ │ ├── cell_types │ │ └── types.xls │ │ ├── formulae │ │ └── formula.xls │ │ ├── easyxf_format │ │ └── date.xls │ │ ├── outlines │ │ └── outlines.xls │ │ ├── xfstyle_format │ │ └── date.xls │ │ ├── hyperlinks │ │ └── hyperlinks.xls │ │ ├── stylecompression │ │ ├── 1xf1font.xls │ │ ├── 3xf1font.xls │ │ └── 3xf3fonts.xls │ │ ├── format_rowscols │ │ └── format_rowscols.xls │ │ ├── overwriting.txt │ │ └── utilities.txt └── test_examples.py ├── .gitignore ├── 80x15.png ├── notes.odt ├── python-excel.pdf ├── students ├── xlrd │ ├── odd.xls │ ├── types.xls │ ├── simple.xls │ ├── utilities.py │ ├── errors.py │ ├── large_files.py │ ├── cell_access.py │ ├── simple.py │ ├── open.py │ ├── introspect_book.py │ ├── introspect_sheet.py │ ├── emptyblank.py │ ├── dates.py │ ├── sheet_iteration.py │ └── cell_types.py ├── xlwt │ ├── python.bmp │ ├── images.py │ ├── merged.py │ ├── zoom.py │ ├── overwriting.py │ ├── easyxf_format.py │ ├── formulae.py │ ├── hyperlinks.py │ ├── panes.py │ ├── simple.py │ ├── stylecompression.py │ ├── borders.py │ ├── xfstyle_format.py │ ├── outlines.py │ ├── format_rowscols.py │ ├── utilities.py │ └── cell_types.py └── xlutils │ ├── source.xls │ ├── styles.py │ ├── display.py │ ├── copy.py │ └── filter.py ├── README.md └── bootstrap.py /tests/expected/xlrd/errors.txt: -------------------------------------------------------------------------------- 1 | #REF! 2 | #NULL! -------------------------------------------------------------------------------- /tests/expected/xlrd/large_files.txt: -------------------------------------------------------------------------------- 1 | S2R1CA 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.installed.cfg 2 | /bin 3 | /parts 4 | -------------------------------------------------------------------------------- /tests/expected/xlutils/styles.txt: -------------------------------------------------------------------------------- 1 | Person 2 | Country 3 | None -------------------------------------------------------------------------------- /tests/expected/xlrd/emptyblank.txt: -------------------------------------------------------------------------------- 1 | False False False 2 | 6 '' 3 | 0 '' -------------------------------------------------------------------------------- /80x15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/80x15.png -------------------------------------------------------------------------------- /notes.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/notes.odt -------------------------------------------------------------------------------- /tests/expected/xlrd/utilities.txt: -------------------------------------------------------------------------------- 1 | A1 K11 CW101 2 | $B$4 $BH$42 $MU$266 3 | A K CW -------------------------------------------------------------------------------- /python-excel.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/python-excel.pdf -------------------------------------------------------------------------------- /students/xlrd/odd.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/students/xlrd/odd.xls -------------------------------------------------------------------------------- /students/xlrd/types.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/students/xlrd/types.xls -------------------------------------------------------------------------------- /tests/expected/xlrd/cell_access.txt: -------------------------------------------------------------------------------- 1 | text:u'S2R1CA' 2 | S2R1CA 3 | True 4 | 1 S2R2CA 5 | 1 S2R2CB 6 | -------------------------------------------------------------------------------- /students/xlrd/simple.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/students/xlrd/simple.xls -------------------------------------------------------------------------------- /students/xlwt/python.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/students/xlwt/python.bmp -------------------------------------------------------------------------------- /students/xlutils/source.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/students/xlutils/source.xls -------------------------------------------------------------------------------- /tests/expected/xlrd/open.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /tests/expected/xlwt/zoom/zoom.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/zoom/zoom.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/panes/panes.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/panes/panes.xls -------------------------------------------------------------------------------- /tests/expected/xlutils/copy/output.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlutils/copy/output.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/images/images.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/images/images.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/merged/merged.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/merged/merged.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/simple/simple.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/simple/simple.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/borders/borders.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/borders/borders.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/cell_types/types.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/cell_types/types.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/formulae/formula.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/formulae/formula.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/easyxf_format/date.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/easyxf_format/date.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/outlines/outlines.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/outlines/outlines.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/xfstyle_format/date.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/xfstyle_format/date.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/hyperlinks/hyperlinks.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/hyperlinks/hyperlinks.xls -------------------------------------------------------------------------------- /tests/expected/xlutils/display.txt: -------------------------------------------------------------------------------- 1 | People 2 | 'Price(\xc2\xa3)' 3 | 'My Sheet' 4 | 'John''s Sheet' 5 | text (Adam Adamson) 6 | date (1978-06-13 00:00:00) -------------------------------------------------------------------------------- /tests/expected/xlrd/introspect_sheet.txt: -------------------------------------------------------------------------------- 1 | Sheet1 2 | 2 3 | 3 4 | A1 - S1R1CA 5 | B1 - S1R1CB 6 | C1 - S1R1CC 7 | A2 - S1R2CA 8 | B2 - S1R2CB 9 | C2 - S1R2CC -------------------------------------------------------------------------------- /tests/expected/xlutils/filter/filtered-source.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlutils/filter/filtered-source.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/stylecompression/1xf1font.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/stylecompression/1xf1font.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/stylecompression/3xf1font.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/stylecompression/3xf1font.xls -------------------------------------------------------------------------------- /tests/expected/xlwt/stylecompression/3xf3fonts.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/stylecompression/3xf3fonts.xls -------------------------------------------------------------------------------- /students/xlwt/images.py: -------------------------------------------------------------------------------- 1 | from xlwt import Workbook 2 | w = Workbook() 3 | ws = w.add_sheet('Image') 4 | ws.insert_bitmap('python.bmp', 0, 0) 5 | w.save('images.xls') 6 | -------------------------------------------------------------------------------- /tests/expected/xlwt/format_rowscols/format_rowscols.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-excel/tutorial/HEAD/tests/expected/xlwt/format_rowscols/format_rowscols.xls -------------------------------------------------------------------------------- /tests/expected/xlrd/simple.txt: -------------------------------------------------------------------------------- 1 | Sheet: Sheet1 2 | S1R1CA,S1R1CB,S1R1CC 3 | S1R2CA,S1R2CB,S1R2CC 4 | S1R3CA,S1R3CB,S1R3CC 5 | 6 | Sheet: Sheet2 7 | S2R1CA,S2R1CB,S2R1CC 8 | S2R2CA,S2R2CB,S2R2CC 9 | S2R3CA,S2R3CB,S2R3CC 10 | -------------------------------------------------------------------------------- /students/xlrd/utilities.py: -------------------------------------------------------------------------------- 1 | from xlrd import cellname, cellnameabs, colname 2 | 3 | print cellname(0,0),cellname(10,10),cellname(100,100) 4 | print cellnameabs(3,1),cellnameabs(41,59),cellnameabs(265,358) 5 | print colname(0),colname(10),colname(100) 6 | -------------------------------------------------------------------------------- /students/xlrd/errors.py: -------------------------------------------------------------------------------- 1 | from xlrd import open_workbook,error_text_from_code 2 | 3 | book = open_workbook('types.xls') 4 | sheet = book.sheet_by_index(0) 5 | 6 | print error_text_from_code[sheet.cell(5,2).value] 7 | print error_text_from_code[sheet.cell(5,3).value] 8 | 9 | -------------------------------------------------------------------------------- /tests/expected/xlrd/introspect_book.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 3 | 4 | [u'Sheet1', u'Sheet2'] 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /students/xlwt/merged.py: -------------------------------------------------------------------------------- 1 | from xlwt import Workbook,easyxf 2 | style = easyxf( 3 | 'pattern: pattern solid, fore_colour red;' 4 | 'align: vertical center, horizontal center;' 5 | ) 6 | w = Workbook() 7 | ws = w.add_sheet('Merged') 8 | ws.write_merge(1,5,1,5,'Merged',style) 9 | w.save('merged.xls') 10 | -------------------------------------------------------------------------------- /students/xlrd/large_files.py: -------------------------------------------------------------------------------- 1 | from xlrd import open_workbook 2 | 3 | book = open_workbook('simple.xls',on_demand=True) 4 | 5 | for name in book.sheet_names(): 6 | if name.endswith('2'): 7 | sheet = book.sheet_by_name(name) 8 | print sheet.cell_value(0,0) 9 | book.unload_sheet(name) 10 | -------------------------------------------------------------------------------- /tests/expected/xlrd/dates.txt: -------------------------------------------------------------------------------- 1 | 2009-03-18 00:00:00 2009-03-18 2 | 2009-03-18 21:06:44 3 | 21:06:44 4 | Traceback (most recent call last): 5 | File "bin/py", line 33, in 6 | execfile(__file__) 7 | File "dates.py", line 13, in 8 | print datetime(*time_value) 9 | ValueError: year is out of range 10 | -------------------------------------------------------------------------------- /students/xlwt/zoom.py: -------------------------------------------------------------------------------- 1 | from xlwt import Workbook 2 | 3 | w = Workbook() 4 | 5 | ws = w.add_sheet('Normal') 6 | ws.write(0,0,'Some text') 7 | ws.normal_magn = 75 8 | 9 | ws = w.add_sheet('Page Break Preview') 10 | ws.write(0,0,'Some text') 11 | ws.preview_magn = 150 12 | ws.page_preview = True 13 | 14 | w.save('zoom.xls') 15 | -------------------------------------------------------------------------------- /students/xlwt/overwriting.py: -------------------------------------------------------------------------------- 1 | from xlwt import Workbook 2 | 3 | book = Workbook() 4 | sheet1 = book.add_sheet('Sheet 1',cell_overwrite_ok=True) 5 | sheet1.write(0,0,'original') 6 | sheet = book.get_sheet(0) 7 | sheet.write(0,0,'new') 8 | 9 | sheet2 = book.add_sheet('Sheet 2') 10 | sheet2.write(0,0,'original') 11 | sheet2.write(0,0,'new') 12 | -------------------------------------------------------------------------------- /students/xlrd/cell_access.py: -------------------------------------------------------------------------------- 1 | from xlrd import open_workbook,XL_CELL_TEXT 2 | 3 | book = open_workbook('odd.xls') 4 | sheet = book.sheet_by_index(1) 5 | 6 | cell = sheet.cell(0,0) 7 | print cell 8 | print cell.value 9 | print cell.ctype==XL_CELL_TEXT 10 | 11 | for i in range(sheet.ncols): 12 | print sheet.cell_type(1,i),sheet.cell_value(1,i) 13 | -------------------------------------------------------------------------------- /students/xlrd/simple.py: -------------------------------------------------------------------------------- 1 | from xlrd import open_workbook 2 | 3 | wb = open_workbook('simple.xls') 4 | 5 | for s in wb.sheets(): 6 | print 'Sheet:',s.name 7 | for row in range(s.nrows): 8 | values = [] 9 | for col in range(s.ncols): 10 | values.append(s.cell(row,col).value) 11 | print ','.join(values) 12 | print 13 | -------------------------------------------------------------------------------- /students/xlrd/open.py: -------------------------------------------------------------------------------- 1 | from mmap import mmap,ACCESS_READ 2 | from xlrd import open_workbook 3 | 4 | print open_workbook('simple.xls') 5 | 6 | with open('simple.xls', 'rb') as f: 7 | print open_workbook( 8 | file_contents=mmap(f.fileno(),0,access=ACCESS_READ) 9 | ) 10 | 11 | aString = open('simple.xls','rb').read() 12 | print open_workbook(file_contents=aString) 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/expected/xlrd/sheet_iteration.txt: -------------------------------------------------------------------------------- 1 | [text:u'S1R1CA', text:u'S1R1CB', text:u'S1R1CC'] 2 | [text:u'S1R1CA', text:u'S1R2CA'] 3 | 4 | [text:u'S1R1CB', text:u'S1R1CC'] 5 | [text:u'S1R1CB'] 6 | [u'S1R1CB', u'S1R1CC'] 7 | [u'S1R1CB'] 8 | array('B', [1, 1]) 9 | array('B', [1]) 10 | 11 | [text:u'S2R2CA', text:u'S2R3CA'] 12 | [text:u'S1R2CA'] 13 | [u'S2R2CA', u'S2R3CA'] 14 | [u'S1R2CA'] 15 | [1, 1] 16 | [1] -------------------------------------------------------------------------------- /students/xlrd/introspect_book.py: -------------------------------------------------------------------------------- 1 | from xlrd import open_workbook 2 | 3 | book = open_workbook('simple.xls') 4 | 5 | print book.nsheets 6 | 7 | for sheet_index in range(book.nsheets): 8 | print book.sheet_by_index(sheet_index) 9 | 10 | print book.sheet_names() 11 | for sheet_name in book.sheet_names(): 12 | print book.sheet_by_name(sheet_name) 13 | 14 | for sheet in book.sheets(): 15 | print sheet 16 | -------------------------------------------------------------------------------- /students/xlrd/introspect_sheet.py: -------------------------------------------------------------------------------- 1 | from xlrd import open_workbook,cellname 2 | 3 | book = open_workbook('odd.xls') 4 | sheet = book.sheet_by_index(0) 5 | 6 | print sheet.name 7 | 8 | print sheet.nrows 9 | print sheet.ncols 10 | 11 | for row_index in range(sheet.nrows): 12 | for col_index in range(sheet.ncols): 13 | print cellname(row_index,col_index),'-', 14 | print sheet.cell(row_index,col_index).value 15 | -------------------------------------------------------------------------------- /students/xlwt/easyxf_format.py: -------------------------------------------------------------------------------- 1 | from datetime import date 2 | from xlwt import Workbook, easyxf 3 | 4 | book = Workbook() 5 | sheet = book.add_sheet('A Date') 6 | 7 | sheet.write(1,1,date(2009,3,18),easyxf( 8 | 'font: name Arial;' 9 | 'borders: left thick, right thick, top thick, bottom thick;' 10 | 'pattern: pattern solid, fore_colour red;', 11 | num_format_str='YYYY-MM-DD' 12 | )) 13 | 14 | book.save('date.xls') 15 | -------------------------------------------------------------------------------- /students/xlutils/styles.py: -------------------------------------------------------------------------------- 1 | from xlrd import open_workbook 2 | from xlutils.styles import Styles 3 | 4 | book = open_workbook('source.xls',formatting_info=True) 5 | styles = Styles(book) 6 | sheet = book.sheet_by_index(0) 7 | 8 | print styles[sheet.cell(1,1)].name 9 | print styles[sheet.cell(1,2)].name 10 | 11 | A1_style = styles[sheet.cell(0,0)] 12 | A1_font = book.font_list[A1_style.xf.font_index] 13 | print book.colour_map[A1_font.colour_index] 14 | -------------------------------------------------------------------------------- /students/xlwt/formulae.py: -------------------------------------------------------------------------------- 1 | from xlwt import Workbook, Formula 2 | 3 | book = Workbook() 4 | 5 | sheet1 = book.add_sheet('Sheet 1') 6 | sheet1.write(0,0,10) 7 | sheet1.write(0,1,20) 8 | sheet1.write(1,0,Formula('A1/B1')) 9 | 10 | sheet2 = book.add_sheet('Sheet 2') 11 | row = sheet2.row(0) 12 | row.write(0,Formula('sum(1,2,3)')) 13 | row.write(1,Formula('SuM(1;2;3)')) 14 | row.write(2,Formula("$A$1+$B$1*SUM('ShEEt 1'!$A$1:$b$2)")) 15 | 16 | book.save('formula.xls') 17 | -------------------------------------------------------------------------------- /students/xlwt/hyperlinks.py: -------------------------------------------------------------------------------- 1 | from xlwt import Workbook,easyxf,Formula 2 | 3 | style = easyxf('font: underline single') 4 | 5 | book = Workbook() 6 | sheet = book.add_sheet('Hyperlinks') 7 | 8 | sheet.write( 9 | 0, 0, 10 | Formula('HYPERLINK("http://www.python.org";"Python")'), 11 | style) 12 | 13 | sheet.write( 14 | 1,0, 15 | Formula('HYPERLINK("mailto:python-excel@googlegroups.com";"help")'), 16 | style) 17 | 18 | book.save("hyperlinks.xls") 19 | -------------------------------------------------------------------------------- /students/xlwt/panes.py: -------------------------------------------------------------------------------- 1 | from xlwt import Workbook 2 | from xlwt.Utils import rowcol_to_cell 3 | 4 | w = Workbook() 5 | sheet = w.add_sheet('Freeze') 6 | sheet.panes_frozen = True 7 | sheet.remove_splits = True 8 | sheet.vert_split_pos = 2 9 | sheet.horz_split_pos = 10 10 | sheet.vert_split_first_visible = 5 11 | sheet.horz_split_first_visible = 40 12 | 13 | for col in range(20): 14 | for row in range(80): 15 | sheet.write(row,col,rowcol_to_cell(row,col)) 16 | 17 | w.save('panes.xls') 18 | -------------------------------------------------------------------------------- /students/xlutils/display.py: -------------------------------------------------------------------------------- 1 | from xlrd import open_workbook 2 | from xlutils.display import quoted_sheet_name 3 | from xlutils.display import cell_display 4 | 5 | wb = open_workbook('source.xls') 6 | 7 | print quoted_sheet_name(wb.sheet_names()[0]) 8 | print repr(quoted_sheet_name(u'Price(\xa3)','utf-8')) 9 | print quoted_sheet_name(u'My Sheet') 10 | print quoted_sheet_name(u"John's Sheet") 11 | 12 | sheet = wb.sheet_by_index(0) 13 | print cell_display(sheet.cell(1,1)) 14 | print cell_display(sheet.cell(1,3),wb.datemode) 15 | -------------------------------------------------------------------------------- /students/xlrd/emptyblank.py: -------------------------------------------------------------------------------- 1 | from xlrd import open_workbook,empty_cell 2 | 3 | print empty_cell.value 4 | 5 | book = open_workbook('types.xls') 6 | sheet = book.sheet_by_index(0) 7 | empty = sheet.cell(6,2) 8 | blank = sheet.cell(7,2) 9 | print empty is blank, empty is empty_cell, blank is empty_cell 10 | 11 | book = open_workbook('types.xls',formatting_info=True) 12 | sheet = book.sheet_by_index(0) 13 | empty = sheet.cell(6,2) 14 | blank = sheet.cell(7,2) 15 | print empty.ctype,repr(empty.value) 16 | print blank.ctype,repr(blank.value) 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repo is the home of an effort to turn the orignal tutorial covering [xlrd][1], [xlwt][2] and [xlutils][3] into a [Sphinx][4] project. 2 | 3 | It is currently stalled and likely always will be. In the meantime, here's a link to a PDF rendering of the original Open Office document: 4 | 5 | https://github.com/python-excel/tutorial/raw/master/python-excel.pdf 6 | 7 | [1]: https://github.com/python-excel/xlrd 8 | [2]: https://github.com/python-excel/xlwt 9 | [3]: https://github.com/python-excel/xlutils 10 | [4]: http://sphinx-doc.org/ 11 | 12 | -------------------------------------------------------------------------------- /students/xlutils/copy.py: -------------------------------------------------------------------------------- 1 | from xlrd import open_workbook 2 | from xlwt import easyxf 3 | from xlutils.copy import copy 4 | 5 | rb = open_workbook('source.xls',formatting_info=True) 6 | rs = rb.sheet_by_index(0) 7 | wb = copy(rb) 8 | ws = wb.get_sheet(0) 9 | 10 | plain = easyxf('') 11 | for i,cell in enumerate(rs.col(2)): 12 | if not i: 13 | continue 14 | ws.write(i,2,cell.value,plain) 15 | 16 | for i,cell in enumerate(rs.col(4)): 17 | if not i: 18 | continue 19 | ws.write(i,4,cell.value-1000) 20 | 21 | wb.save('output.xls') 22 | -------------------------------------------------------------------------------- /students/xlrd/dates.py: -------------------------------------------------------------------------------- 1 | from datetime import date,datetime,time 2 | from xlrd import open_workbook,xldate_as_tuple 3 | 4 | book = open_workbook('types.xls') 5 | sheet = book.sheet_by_index(0) 6 | import math 7 | 8 | date_value = xldate_as_tuple(sheet.cell(3,2).value,book.datemode) 9 | print datetime(*date_value),date(*date_value[:3]) 10 | datetime_value = xldate_as_tuple(sheet.cell(3,3).value,book.datemode) 11 | print datetime(*datetime_value) 12 | time_value = xldate_as_tuple(sheet.cell(3,4).value,book.datemode) 13 | print time(*time_value[3:]) 14 | print datetime(*time_value) 15 | -------------------------------------------------------------------------------- /tests/expected/xlwt/overwriting.txt: -------------------------------------------------------------------------------- 1 | Traceback (most recent call last): 2 | File "bin/py", line 33, in 3 | execfile(__file__) 4 | File "overwriting.py", line 11, in 5 | sheet2.write(0,0,'new') 6 | File "Worksheet.py", line 1032, in write 7 | self.row(r).write(c, label, style) 8 | File "Row.py", line 233, in write 9 | StrCell(self.__idx, col, style_index, self.__parent_wb.add_str(label)) 10 | File "Row.py", line 152, in insert_cell 11 | raise Exception(msg) 12 | Exception: Attempt to overwrite cell: sheetname=u'Sheet 2' rowx=0 colx=0 13 | -------------------------------------------------------------------------------- /tests/expected/xlwt/utilities.txt: -------------------------------------------------------------------------------- 1 | AA -> 26 2 | A -> 0 3 | A1 -> (0, 0, False, False) 4 | $A$1 -> (0, 0, True, True) 5 | A1 -> (0, 0) 6 | (0, 0) -> A1 7 | (0, 0, False, True) -> $A1 8 | (0, 0, True, True) -> $A$1 9 | 1:3 -> (0, 0, 2, -1) 10 | B:G -> (0, 1, -1, 6) 11 | A2:B7 -> (1, 0, 6, 1) 12 | A1 -> (0, 0, 0, 0) 13 | (0, 0, 100, 100) -> A1:CW101 14 | (0, 0, 100, 100, True, False, False, False) -> A$1:$CW101 15 | Is '' a valid sheet name? No 16 | Is "'quoted'" a valid sheet name? No 17 | Is "O'hare" a valid sheet name? Yes 18 | Is 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' a valid sheet name? No 19 | Is '[]:\\?/*\x00' a valid sheet name? No 20 | -------------------------------------------------------------------------------- /students/xlrd/sheet_iteration.py: -------------------------------------------------------------------------------- 1 | from xlrd import open_workbook 2 | 3 | book = open_workbook('odd.xls') 4 | sheet0 = book.sheet_by_index(0) 5 | sheet1 = book.sheet_by_index(1) 6 | 7 | print sheet0.row(0) 8 | print sheet0.col(0) 9 | print 10 | print sheet0.row_slice(0,1) 11 | print sheet0.row_slice(0,1,2) 12 | print sheet0.row_values(0,1) 13 | print sheet0.row_values(0,1,2) 14 | print sheet0.row_types(0,1) 15 | print sheet0.row_types(0,1,2) 16 | print 17 | print sheet1.col_slice(0,1) 18 | print sheet0.col_slice(0,1,2) 19 | print sheet1.col_values(0,1) 20 | print sheet0.col_values(0,1,2) 21 | print sheet1.col_types(0,1) 22 | print sheet0.col_types(0,1,2) 23 | -------------------------------------------------------------------------------- /students/xlwt/simple.py: -------------------------------------------------------------------------------- 1 | from tempfile import TemporaryFile 2 | from xlwt import Workbook 3 | 4 | book = Workbook() 5 | sheet1 = book.add_sheet('Sheet 1') 6 | book.add_sheet('Sheet 2') 7 | 8 | sheet1.write(0,0,'A1') 9 | sheet1.write(0,1,'B1') 10 | row1 = sheet1.row(1) 11 | row1.write(0,'A2') 12 | row1.write(1,'B2') 13 | sheet1.col(0).width = 10000 14 | 15 | sheet2 = book.get_sheet(1) 16 | sheet2.row(0).write(0,'Sheet 2 A1') 17 | sheet2.row(0).write(1,'Sheet 2 B1') 18 | sheet2.flush_row_data() 19 | sheet2.write(1,0,'Sheet 2 A3') 20 | sheet2.col(0).width = 5000 21 | sheet2.col(0).hidden = True 22 | 23 | book.save('simple.xls') 24 | book.save(TemporaryFile()) 25 | -------------------------------------------------------------------------------- /students/xlwt/stylecompression.py: -------------------------------------------------------------------------------- 1 | from xlwt import Workbook, easyxf 2 | 3 | style1 = easyxf('font: name Times New Roman') 4 | style2 = easyxf('font: name Times New Roman') 5 | style3 = easyxf('font: name Times New Roman') 6 | 7 | def write_cells(book): 8 | sheet = book.add_sheet('Content') 9 | sheet.write(0,0,'A1',style1) 10 | sheet.write(0,1,'B1',style2) 11 | sheet.write(0,2,'C1',style3) 12 | 13 | book = Workbook() 14 | write_cells(book) 15 | book.save('3xf3fonts.xls') 16 | 17 | book = Workbook(style_compression=1) 18 | write_cells(book) 19 | book.save('3xf1font.xls') 20 | 21 | book = Workbook(style_compression=2) 22 | write_cells(book) 23 | book.save('1xf1font.xls') 24 | -------------------------------------------------------------------------------- /students/xlwt/borders.py: -------------------------------------------------------------------------------- 1 | from xlwt import Workbook,easyxf 2 | tl = easyxf('border: left thick, top thick') 3 | t = easyxf('border: top thick') 4 | tr = easyxf('border: right thick, top thick') 5 | r = easyxf('border: right thick') 6 | br = easyxf('border: right thick, bottom thick') 7 | b = easyxf('border: bottom thick') 8 | bl = easyxf('border: left thick, bottom thick') 9 | l = easyxf('border: left thick') 10 | 11 | w = Workbook() 12 | ws = w.add_sheet('Border') 13 | ws.write(1,1,style=tl) 14 | ws.write(1,2,style=t) 15 | ws.write(1,3,style=tr) 16 | ws.write(2,3,style=r) 17 | ws.write(3,3,style=br) 18 | ws.write(3,2,style=b) 19 | ws.write(3,1,style=bl) 20 | ws.write(2,1,style=l) 21 | 22 | w.save('borders.xls') 23 | -------------------------------------------------------------------------------- /students/xlwt/xfstyle_format.py: -------------------------------------------------------------------------------- 1 | from datetime import date 2 | from xlwt import Workbook, XFStyle, Borders, Pattern, Font 3 | 4 | fnt = Font() 5 | fnt.name = 'Arial' 6 | 7 | borders = Borders() 8 | borders.left = Borders.THICK 9 | borders.right = Borders.THICK 10 | borders.top = Borders.THICK 11 | borders.bottom = Borders.THICK 12 | 13 | pattern = Pattern() 14 | pattern.pattern = Pattern.SOLID_PATTERN 15 | pattern.pattern_fore_colour = 0x0A 16 | 17 | style = XFStyle() 18 | style.num_format_str='YYYY-MM-DD' 19 | style.font = fnt 20 | style.borders = borders 21 | style.pattern = pattern 22 | 23 | book = Workbook() 24 | sheet = book.add_sheet('A Date') 25 | sheet.write(1,1,date(2009,3,18),style) 26 | 27 | book.save('date.xls') 28 | -------------------------------------------------------------------------------- /students/xlwt/outlines.py: -------------------------------------------------------------------------------- 1 | from xlwt import Workbook 2 | 3 | data = [ 4 | ['','','2008','','2009'], 5 | ['','','Jan','Feb','Jan','Feb'], 6 | ['Company X'], 7 | ['','Division A'], 8 | ['','',100,200,300,400], 9 | ['','Division B'], 10 | ['','',100,99,98,50], 11 | ['Company Y'], 12 | ['','Division A'], 13 | ['','',100,100,100,100], 14 | ['','Division B'], 15 | ['','',100,101,102,103], 16 | ] 17 | 18 | w = Workbook() 19 | ws = w.add_sheet('Outlines') 20 | for i,row in enumerate(data): 21 | for j,cell in enumerate(row): 22 | ws.write(i,j,cell) 23 | 24 | ws.row(2).level = 1 25 | ws.row(3).level = 2 26 | ws.row(4).level = 3 27 | ws.row(5).level = 2 28 | ws.row(6).level = 3 29 | ws.row(7).level = 1 30 | ws.row(8).level = 2 31 | ws.row(9).level = 3 32 | ws.row(10).level = 2 33 | ws.row(11).level = 3 34 | 35 | ws.col(2).level = 1 36 | ws.col(3).level = 2 37 | ws.col(4).level = 1 38 | ws.col(5).level = 2 39 | 40 | w.save('outlines.xls') 41 | -------------------------------------------------------------------------------- /students/xlwt/format_rowscols.py: -------------------------------------------------------------------------------- 1 | from xlwt import Workbook, easyxf 2 | from xlwt.Utils import rowcol_to_cell 3 | 4 | row = easyxf('pattern: pattern solid, fore_colour blue') 5 | col = easyxf('pattern: pattern solid, fore_colour green') 6 | cell = easyxf('pattern: pattern solid, fore_colour red') 7 | 8 | book = Workbook() 9 | 10 | sheet = book.add_sheet('Precedence') 11 | for i in range(0,10,2): 12 | sheet.row(i).set_style(row) 13 | for i in range(0,10,2): 14 | sheet.col(i).set_style(col) 15 | for i in range(10): 16 | sheet.write(i,i,None,cell) 17 | 18 | sheet = book.add_sheet('Hiding') 19 | for rowx in range(10): 20 | for colx in range(10): 21 | sheet.write(rowx,colx,rowcol_to_cell(rowx,colx)) 22 | for i in range(0,10,2): 23 | sheet.row(i).hidden = True 24 | sheet.col(i).hidden = True 25 | 26 | sheet = book.add_sheet('Row height and Column width') 27 | for i in range(10): 28 | sheet.write(0,i,0) 29 | for i in range(10): 30 | sheet.row(i).set_style(easyxf('font:height '+str(200*i))) 31 | sheet.col(i).width = 256*i 32 | 33 | book.save('format_rowscols.xls') 34 | -------------------------------------------------------------------------------- /students/xlrd/cell_types.py: -------------------------------------------------------------------------------- 1 | from xlrd import open_workbook 2 | 3 | def cell_contents(sheet,row_x): 4 | result = [] 5 | for col_x in range(2,sheet.ncols): 6 | cell = sheet.cell(row_x,col_x) 7 | result.append((cell.ctype,cell,cell.value)) 8 | return result 9 | 10 | sheet = open_workbook('types.xls').sheet_by_index(0) 11 | 12 | print 'XL_CELL_TEXT',cell_contents(sheet,1) 13 | print 'XL_CELL_NUMBER',cell_contents(sheet,2) 14 | print 'XL_CELL_DATE',cell_contents(sheet,3) 15 | print 'XL_CELL_BOOLEAN',cell_contents(sheet,4) 16 | print 'XL_CELL_ERROR',cell_contents(sheet,5) 17 | print 'XL_CELL_BLANK',cell_contents(sheet,6) 18 | print 'XL_CELL_EMPTY',cell_contents(sheet,7) 19 | 20 | print 21 | sheet = open_workbook( 22 | 'types.xls',formatting_info=True 23 | ).sheet_by_index(0) 24 | 25 | print 'XL_CELL_TEXT',cell_contents(sheet,1) 26 | print 'XL_CELL_NUMBER',cell_contents(sheet,2) 27 | print 'XL_CELL_DATE',cell_contents(sheet,3) 28 | print 'XL_CELL_BOOLEAN',cell_contents(sheet,4) 29 | print 'XL_CELL_ERROR',cell_contents(sheet,5) 30 | print 'XL_CELL_BLANK',cell_contents(sheet,6) 31 | print 'XL_CELL_EMPTY',cell_contents(sheet,7) 32 | 33 | -------------------------------------------------------------------------------- /students/xlutils/filter.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from xlutils.filter import BaseReader,BaseFilter,BaseWriter,process 4 | 5 | class Reader(BaseReader): 6 | def get_filepaths(self): 7 | return [os.path.abspath('source.xls')] 8 | 9 | class Writer(BaseWriter): 10 | def get_stream(self,filename): 11 | return file(filename,'wb') 12 | 13 | class Filter(BaseFilter): 14 | 15 | pending_row = None 16 | wtrowxi = 0 17 | 18 | def workbook(self,rdbook,wtbook_name): 19 | self.next.workbook(rdbook,'filtered-'+wtbook_name) 20 | 21 | def row(self,rdrowx,wtrowx): 22 | self.pending_row = (rdrowx,wtrowx) 23 | 24 | def cell(self,rdrowx,rdcolx,wtrowx,wtcolx): 25 | if rdcolx==0: 26 | value = self.rdsheet.cell(rdrowx,rdcolx).value 27 | if value.strip().lower()=='x': 28 | self.ignore_row = True 29 | self.wtrowxi -= 1 30 | else: 31 | self.ignore_row = False 32 | rdrowx, wtrowx = self.pending_row 33 | self.next.row(rdrowx,wtrowx+self.wtrowxi) 34 | elif not self.ignore_row: 35 | self.next.cell( 36 | rdrowx,rdcolx,wtrowx+self.wtrowxi,wtcolx-1 37 | ) 38 | 39 | process(Reader(),Filter(),Writer()) 40 | -------------------------------------------------------------------------------- /students/xlwt/utilities.py: -------------------------------------------------------------------------------- 1 | from xlwt import Utils 2 | 3 | print 'AA ->',Utils.col_by_name('AA') 4 | print 'A ->',Utils.col_by_name('A') 5 | 6 | print 'A1 ->',Utils.cell_to_rowcol('A1') 7 | print '$A$1 ->',Utils.cell_to_rowcol('$A$1') 8 | 9 | print 'A1 ->',Utils.cell_to_rowcol2('A1') 10 | 11 | print (0,0),'->',Utils.rowcol_to_cell(0,0) 12 | print (0,0,False,True),'->', 13 | print Utils.rowcol_to_cell(0,0,False,True) 14 | print (0,0,True,True),'->', 15 | print Utils.rowcol_to_cell( 16 | row=0,col=0,row_abs=True,col_abs=True 17 | ) 18 | 19 | print '1:3 ->',Utils.cellrange_to_rowcol_pair('1:3') 20 | print 'B:G ->',Utils.cellrange_to_rowcol_pair('B:G') 21 | print 'A2:B7 ->',Utils.cellrange_to_rowcol_pair('A2:B7') 22 | print 'A1 ->',Utils.cellrange_to_rowcol_pair('A1') 23 | 24 | print (0,0,100,100),'->', 25 | print Utils.rowcol_pair_to_cellrange(0,0,100,100) 26 | print (0,0,100,100,True,False,False,False),'->', 27 | print Utils.rowcol_pair_to_cellrange( 28 | row1=0,col1=0,row2=100,col2=100, 29 | row1_abs=True,col1_abs=False, 30 | row2_abs=False,col2_abs=True 31 | ) 32 | 33 | for name in ( 34 | '',"'quoted'","O'hare","X"*32,"[]:\\?/*\x00" 35 | ): 36 | print 'Is %r a valid sheet name?' % name, 37 | if Utils.valid_sheet_name(name): 38 | print "Yes" 39 | else: 40 | print "No" 41 | -------------------------------------------------------------------------------- /tests/expected/xlrd/cell_types.txt: -------------------------------------------------------------------------------- 1 | XL_CELL_TEXT [(1, text:u'Text', u'Text'), (0, empty:'', ''), (0, empty:'', '')] 2 | XL_CELL_NUMBER [(2, number:13.0, 13.0), (2, number:4.2000000000000002, 4.2000000000000002), (0, empty:'', '')] 3 | XL_CELL_DATE [(3, xldate:39890.0, 39890.0), (3, xldate:39890.879675925928, 39890.879675925928), (3, xldate:0.87967592592592592, 0.87967592592592592)] 4 | XL_CELL_BOOLEAN [(4, bool:0, 0), (4, bool:1, 1), (0, empty:'', '')] 5 | XL_CELL_ERROR [(5, error:23, 23), (5, error:0, 0), (0, empty:'', '')] 6 | XL_CELL_BLANK [(0, empty:'', ''), (0, empty:'', ''), (0, empty:'', '')] 7 | XL_CELL_EMPTY [(0, empty:'', ''), (0, empty:'', ''), (0, empty:'', '')] 8 | 9 | XL_CELL_TEXT [(1, text:u'Text' (XF:25), u'Text'), (0, empty:'' (XF:15), ''), (0, empty:'' (XF:15), '')] 10 | XL_CELL_NUMBER [(2, number:13.0 (XF:25), 13.0), (2, number:4.2000000000000002 (XF:25), 4.2000000000000002), (0, empty:'' (XF:15), '')] 11 | XL_CELL_DATE [(3, xldate:39890.0 (XF:26), 39890.0), (3, xldate:39890.879675925928 (XF:27), 39890.879675925928), (3, xldate:0.87967592592592592 (XF:28), 0.87967592592592592)] 12 | XL_CELL_BOOLEAN [(4, bool:0 (XF:29), 0), (4, bool:1 (XF:29), 1), (0, empty:'' (XF:15), '')] 13 | XL_CELL_ERROR [(5, error:23 (XF:25), 23), (5, error:0 (XF:25), 0), (0, empty:'' (XF:15), '')] 14 | XL_CELL_BLANK [(6, blank:'' (XF:24), ''), (0, empty:'' (XF:15), ''), (0, empty:'' (XF:15), '')] 15 | XL_CELL_EMPTY [(0, empty:'' (XF:15), ''), (0, empty:'' (XF:15), ''), (0, empty:'' (XF:15), '')] -------------------------------------------------------------------------------- /students/xlwt/cell_types.py: -------------------------------------------------------------------------------- 1 | from datetime import date,time,datetime 2 | from decimal import Decimal 3 | from xlwt import Workbook,Style 4 | 5 | wb = Workbook() 6 | 7 | ws = wb.add_sheet('Type examples') 8 | 9 | ws.row(0).write(0,u'\xa3') 10 | ws.row(0).write(1,'Text') 11 | 12 | ws.row(1).write(0,3.1415) 13 | ws.row(1).write(1,15) 14 | ws.row(1).write(2,265L) 15 | ws.row(1).write(3,Decimal('3.65')) 16 | ws.row(2).set_cell_number(0,3.1415) 17 | ws.row(2).set_cell_number(1,15) 18 | ws.row(2).set_cell_number(2,265L) 19 | ws.row(2).set_cell_number(3,Decimal('3.65')) 20 | 21 | ws.row(3).write(0,date(2009,3,18)) 22 | ws.row(3).write(1,datetime(2009,3,18,17,0,1)) 23 | ws.row(3).write(2,time(17,1)) 24 | ws.row(4).set_cell_date(0,date(2009,3,18)) 25 | ws.row(4).set_cell_date(1,datetime(2009,3,18,17,0,1)) 26 | ws.row(4).set_cell_date(2,time(17,1)) 27 | 28 | ws.row(5).write(0,False) 29 | ws.row(5).write(1,True) 30 | ws.row(6).set_cell_boolean(0,False) 31 | ws.row(6).set_cell_boolean(1,True) 32 | 33 | ws.row(7).set_cell_error(0,0x17) 34 | ws.row(7).set_cell_error(1,'#NULL!') 35 | 36 | ws.row(8).write( 37 | 0,'',Style.easyxf('pattern: pattern solid, fore_colour green;')) 38 | ws.row(8).write( 39 | 1,None,Style.easyxf('pattern: pattern solid, fore_colour blue;')) 40 | ws.row(9).set_cell_blank( 41 | 0,Style.easyxf('pattern: pattern solid, fore_colour yellow;')) 42 | 43 | ws.row(10).set_cell_mulblanks( 44 | 5,10,Style.easyxf('pattern: pattern solid, fore_colour red;') 45 | ) 46 | 47 | wb.save('types.xls') 48 | -------------------------------------------------------------------------------- /tests/test_examples.py: -------------------------------------------------------------------------------- 1 | from __future__ import with_statement 2 | 3 | import os 4 | 5 | from cStringIO import StringIO 6 | from glob import glob 7 | from os import path, environ 8 | from os.path import abspath 9 | from re import compile 10 | from shutil import copy 11 | from subprocess import call, STDOUT 12 | from tempfile import TemporaryFile 13 | from testfixtures import TempDirectory, compare 14 | from xlrd import Book, biff_dump 15 | 16 | initial = os.getcwd() 17 | base = abspath(path.join(path.dirname(abspath(__file__)), os.pardir)) 18 | runner = abspath(path.join(base, 'bin', 'py')) 19 | examples = path.join(base, 'students') 20 | expected = path.join(base, 'tests', 'expected') 21 | 22 | sub_res = [ 23 | (compile('0+x[0-9A-Fa-f]+'), '...'), 24 | (compile('".+'+os.sep.replace('\\','\\\\')+'(.+.py)"'), '"\\1"'), 25 | ] 26 | 27 | def get_biff_records(data): 28 | outfile = StringIO() 29 | bk = Book() 30 | bk.biff2_8_load(file_contents=data, logfile=outfile, ) 31 | biff_dump(bk.mem, bk.base, bk.stream_len, 0, outfile, unnumbered=True) 32 | return outfile.getvalue() 33 | 34 | def check_example(package, filename): 35 | example_dir = path.join(examples, package) 36 | expected_dir = path.join(expected, package) 37 | expected_base = path.join(expected_dir, path.splitext(filename)[0]) 38 | 39 | try: 40 | 41 | with TempDirectory() as actual: 42 | # copy files to the directory 43 | copy(path.join(example_dir, filename), actual.path) 44 | for pattern in ('*.xls', '*.bmp'): 45 | for fixture in glob(path.join(example_dir, pattern)): 46 | copy(fixture, actual.path) 47 | 48 | os.chdir(actual.path) 49 | output = TemporaryFile('w+') 50 | 51 | # run the example 52 | before_listing = set(os.listdir(actual.path)) 53 | call([runner, filename], stdout=output, stderr=STDOUT) 54 | after_listing = set(os.listdir(actual.path)) 55 | 56 | # check the console output 57 | output.seek(0) 58 | actual_output = output.read().strip().replace('\r', '') 59 | for re, rp in sub_res: 60 | actual_output = re.sub(rp, actual_output) 61 | expected_path = expected_base+'.txt' 62 | if not path.exists(expected_path): 63 | expected_output = '' 64 | else: 65 | expected_output = open(expected_path).read().strip().replace('\r', '') 66 | compare(expected_output, actual_output) 67 | 68 | # check the files created 69 | created = after_listing.difference(before_listing) 70 | 71 | expected_names = set() 72 | if os.path.exists(expected_base): 73 | expected_names = set(os.listdir(expected_base)) 74 | 75 | for name in created: 76 | with open(path.join(actual.path, name), 'rb') as af: 77 | actual_data = af.read() 78 | 79 | if name in expected_names: 80 | expected_path = path.join(expected_base, name) 81 | expected_data = open(expected_path, 'rb').read() 82 | expected_names.remove(name) 83 | if actual_data != expected_data: 84 | if environ.get('REPLACE_EXAMPLES'): 85 | with open(expected_path, 'wb') as new_expected: 86 | new_expected.write(actual_data) 87 | compare( 88 | get_biff_records(expected_data), 89 | get_biff_records(actual_data), 90 | ) 91 | else: 92 | raise AssertionError("unexpected output: %s" % name) 93 | 94 | for name in expected_names: 95 | if name != '.svn': 96 | print created 97 | raise AssertionError("expected output missing: %s" % name) 98 | 99 | 100 | finally: 101 | os.chdir(initial) 102 | 103 | def test_examples(): 104 | for package in ('xlrd', 'xlwt', 'xlutils'): 105 | for py in glob(path.join(examples, package, '*.py')): 106 | yield check_example, package, path.split(py)[1] 107 | 108 | -------------------------------------------------------------------------------- /bootstrap.py: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # 3 | # Copyright (c) 2006 Zope Foundation and Contributors. 4 | # All Rights Reserved. 5 | # 6 | # This software is subject to the provisions of the Zope Public License, 7 | # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. 8 | # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED 9 | # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 10 | # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS 11 | # FOR A PARTICULAR PURPOSE. 12 | # 13 | ############################################################################## 14 | """Bootstrap a buildout-based project 15 | 16 | Simply run this script in a directory containing a buildout.cfg. 17 | The script accepts buildout command-line options, so you can 18 | use the -c option to specify an alternate configuration file. 19 | """ 20 | 21 | import os, shutil, sys, tempfile, urllib, urllib2, subprocess 22 | from optparse import OptionParser 23 | 24 | if sys.platform == 'win32': 25 | def quote(c): 26 | if ' ' in c: 27 | return '"%s"' % c # work around spawn lamosity on windows 28 | else: 29 | return c 30 | else: 31 | quote = str 32 | 33 | # See zc.buildout.easy_install._has_broken_dash_S for motivation and comments. 34 | stdout, stderr = subprocess.Popen( 35 | [sys.executable, '-Sc', 36 | 'try:\n' 37 | ' import ConfigParser\n' 38 | 'except ImportError:\n' 39 | ' print 1\n' 40 | 'else:\n' 41 | ' print 0\n'], 42 | stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() 43 | has_broken_dash_S = bool(int(stdout.strip())) 44 | 45 | # In order to be more robust in the face of system Pythons, we want to 46 | # run without site-packages loaded. This is somewhat tricky, in 47 | # particular because Python 2.6's distutils imports site, so starting 48 | # with the -S flag is not sufficient. However, we'll start with that: 49 | if not has_broken_dash_S and 'site' in sys.modules: 50 | # We will restart with python -S. 51 | args = sys.argv[:] 52 | args[0:0] = [sys.executable, '-S'] 53 | args = map(quote, args) 54 | os.execv(sys.executable, args) 55 | # Now we are running with -S. We'll get the clean sys.path, import site 56 | # because distutils will do it later, and then reset the path and clean 57 | # out any namespace packages from site-packages that might have been 58 | # loaded by .pth files. 59 | clean_path = sys.path[:] 60 | import site # imported because of its side effects 61 | sys.path[:] = clean_path 62 | for k, v in sys.modules.items(): 63 | if k in ('setuptools', 'pkg_resources') or ( 64 | hasattr(v, '__path__') and 65 | len(v.__path__) == 1 and 66 | not os.path.exists(os.path.join(v.__path__[0], '__init__.py'))): 67 | # This is a namespace package. Remove it. 68 | sys.modules.pop(k) 69 | 70 | is_jython = sys.platform.startswith('java') 71 | 72 | setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py' 73 | distribute_source = 'http://python-distribute.org/distribute_setup.py' 74 | 75 | 76 | # parsing arguments 77 | def normalize_to_url(option, opt_str, value, parser): 78 | if value: 79 | if '://' not in value: # It doesn't smell like a URL. 80 | value = 'file://%s' % ( 81 | urllib.pathname2url( 82 | os.path.abspath(os.path.expanduser(value))),) 83 | if opt_str == '--download-base' and not value.endswith('/'): 84 | # Download base needs a trailing slash to make the world happy. 85 | value += '/' 86 | else: 87 | value = None 88 | name = opt_str[2:].replace('-', '_') 89 | setattr(parser.values, name, value) 90 | 91 | usage = '''\ 92 | [DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options] 93 | 94 | Bootstraps a buildout-based project. 95 | 96 | Simply run this script in a directory containing a buildout.cfg, using the 97 | Python that you want bin/buildout to use. 98 | 99 | Note that by using --setup-source and --download-base to point to 100 | local resources, you can keep this script from going over the network. 101 | ''' 102 | 103 | parser = OptionParser(usage=usage) 104 | parser.add_option("-v", "--version", dest="version", 105 | help="use a specific zc.buildout version") 106 | parser.add_option("-d", "--distribute", 107 | action="store_true", dest="use_distribute", default=False, 108 | help="Use Distribute rather than Setuptools.") 109 | parser.add_option("--setup-source", action="callback", dest="setup_source", 110 | callback=normalize_to_url, nargs=1, type="string", 111 | help=("Specify a URL or file location for the setup file. " 112 | "If you use Setuptools, this will default to " + 113 | setuptools_source + "; if you use Distribute, this " 114 | "will default to " + distribute_source + ".")) 115 | parser.add_option("--download-base", action="callback", dest="download_base", 116 | callback=normalize_to_url, nargs=1, type="string", 117 | help=("Specify a URL or directory for downloading " 118 | "zc.buildout and either Setuptools or Distribute. " 119 | "Defaults to PyPI.")) 120 | parser.add_option("--eggs", 121 | help=("Specify a directory for storing eggs. Defaults to " 122 | "a temporary directory that is deleted when the " 123 | "bootstrap script completes.")) 124 | parser.add_option("-t", "--accept-buildout-test-releases", 125 | dest='accept_buildout_test_releases', 126 | action="store_true", default=False, 127 | help=("Normally, if you do not specify a --version, the " 128 | "bootstrap script and buildout gets the newest " 129 | "*final* versions of zc.buildout and its recipes and " 130 | "extensions for you. If you use this flag, " 131 | "bootstrap and buildout will get the newest releases " 132 | "even if they are alphas or betas.")) 133 | parser.add_option("-c", None, action="store", dest="config_file", 134 | help=("Specify the path to the buildout configuration " 135 | "file to be used.")) 136 | 137 | options, args = parser.parse_args() 138 | 139 | # if -c was provided, we push it back into args for buildout's main function 140 | if options.config_file is not None: 141 | args += ['-c', options.config_file] 142 | 143 | if options.eggs: 144 | eggs_dir = os.path.abspath(os.path.expanduser(options.eggs)) 145 | else: 146 | eggs_dir = tempfile.mkdtemp() 147 | 148 | if options.setup_source is None: 149 | if options.use_distribute: 150 | options.setup_source = distribute_source 151 | else: 152 | options.setup_source = setuptools_source 153 | 154 | if options.accept_buildout_test_releases: 155 | args.append('buildout:accept-buildout-test-releases=true') 156 | args.append('bootstrap') 157 | 158 | try: 159 | import pkg_resources 160 | import setuptools # A flag. Sometimes pkg_resources is installed alone. 161 | if not hasattr(pkg_resources, '_distribute'): 162 | raise ImportError 163 | except ImportError: 164 | ez_code = urllib2.urlopen( 165 | options.setup_source).read().replace('\r\n', '\n') 166 | ez = {} 167 | exec ez_code in ez 168 | setup_args = dict(to_dir=eggs_dir, download_delay=0) 169 | if options.download_base: 170 | setup_args['download_base'] = options.download_base 171 | if options.use_distribute: 172 | setup_args['no_fake'] = True 173 | ez['use_setuptools'](**setup_args) 174 | if 'pkg_resources' in sys.modules: 175 | reload(sys.modules['pkg_resources']) 176 | import pkg_resources 177 | # This does not (always?) update the default working set. We will 178 | # do it. 179 | for path in sys.path: 180 | if path not in pkg_resources.working_set.entries: 181 | pkg_resources.working_set.add_entry(path) 182 | 183 | cmd = [quote(sys.executable), 184 | '-c', 185 | quote('from setuptools.command.easy_install import main; main()'), 186 | '-mqNxd', 187 | quote(eggs_dir)] 188 | 189 | if not has_broken_dash_S: 190 | cmd.insert(1, '-S') 191 | 192 | find_links = options.download_base 193 | if not find_links: 194 | find_links = os.environ.get('bootstrap-testing-find-links') 195 | if find_links: 196 | cmd.extend(['-f', quote(find_links)]) 197 | 198 | if options.use_distribute: 199 | setup_requirement = 'distribute' 200 | else: 201 | setup_requirement = 'setuptools' 202 | ws = pkg_resources.working_set 203 | setup_requirement_path = ws.find( 204 | pkg_resources.Requirement.parse(setup_requirement)).location 205 | env = dict( 206 | os.environ, 207 | PYTHONPATH=setup_requirement_path) 208 | 209 | requirement = 'zc.buildout' 210 | version = options.version 211 | if version is None and not options.accept_buildout_test_releases: 212 | # Figure out the most recent final version of zc.buildout. 213 | import setuptools.package_index 214 | _final_parts = '*final-', '*final' 215 | 216 | def _final_version(parsed_version): 217 | for part in parsed_version: 218 | if (part[:1] == '*') and (part not in _final_parts): 219 | return False 220 | return True 221 | index = setuptools.package_index.PackageIndex( 222 | search_path=[setup_requirement_path]) 223 | if find_links: 224 | index.add_find_links((find_links,)) 225 | req = pkg_resources.Requirement.parse(requirement) 226 | if index.obtain(req) is not None: 227 | best = [] 228 | bestv = None 229 | for dist in index[req.project_name]: 230 | distv = dist.parsed_version 231 | if _final_version(distv): 232 | if bestv is None or distv > bestv: 233 | best = [dist] 234 | bestv = distv 235 | elif distv == bestv: 236 | best.append(dist) 237 | if best: 238 | best.sort() 239 | version = best[-1].version 240 | if version: 241 | requirement = '=='.join((requirement, version)) 242 | cmd.append(requirement) 243 | 244 | if is_jython: 245 | import subprocess 246 | exitcode = subprocess.Popen(cmd, env=env).wait() 247 | else: # Windows prefers this, apparently; otherwise we would prefer subprocess 248 | exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env])) 249 | if exitcode != 0: 250 | sys.stdout.flush() 251 | sys.stderr.flush() 252 | print ("An error occurred when trying to install zc.buildout. " 253 | "Look above this message for any errors that " 254 | "were output by easy_install.") 255 | sys.exit(exitcode) 256 | 257 | ws.add_entry(eggs_dir) 258 | ws.require(requirement) 259 | import zc.buildout.buildout 260 | zc.buildout.buildout.main(args) 261 | if not options.eggs: # clean up temporary egg directory 262 | shutil.rmtree(eggs_dir) 263 | --------------------------------------------------------------------------------