Missing default for refersTo (=None): workbook.names.external.External(name, refersTo, sheetId=None)

Issue #409 resolved
Bitbucket user
created an issue

Setting: - Ubuntu 14.0.4 - Python 2.7.6 - openpyxl 2.1.4

In our code we load a workbook (attached: Titelanalyse_USA3.xlsm):

wb = load_workbook(filename=file_path, data_only=True, guess_types=True)

And while reading the file an exception is thrown on line 85:

/usr/local/lib/python2.7/dist-packages/openpyxl/workbook/names/external.py in parse_ranges

    def parse_ranges(xml):
        tree = fromstring(xml)
        book = tree.find('{%s}externalBook' % SHEET_MAIN_NS)
        names = book.find('{%s}definedNames' % SHEET_MAIN_NS)
        for n in safe_iterator(names, '{%s}definedName' % SHEET_MAIN_NS):
            yield ExternalRange(**n.attrib)  # <------ Throws: __init__() takes at least 3 arguments (2 given) --> n.attrib = {'name': 'FT'}

The problem arises with a call to:

class openpyxl.workbook.names.external.External(name, refersTo, sheetId=None)

A look at the xml of the function parse_ranges(xml):

--- xml ---

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<externalLink xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main">
  <externalBook xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId1">
    <sheetNames>
      <sheetName val="sample"/>
    </sheetNames>
    <definedNames><definedName name="FT"/></definedNames>
    <sheetDataSet><sheetData sheetId="0"/></sheetDataSet>
  </externalBook>
</externalLink>

So, the refersTo-part is not in the dictionary

n.attrib = {'name': 'FT'}

This load_workbook function loaded without problems with openpyxl 2.0.5/1.8.4

Cheers, Marco

Comments (4)

  1. Bitbucket user reporter

    Some snippets out of the discussion thread from above:

    Charlie: I'm not sure if it's related to: https://bitbucket.org/openpyxl/openpyxl/issue/406/excel-gives-an-error-opening-the-xlsm-file

    wb = load_workbook(filename=file_path, data_only=True, guess_types=True)
    

    Charlie: I think you probably don't want guess_types=True for an existing file, but you probably know what you're doing.

    Marco: It is a generic importer for xlsm/x-files - so I don't know what type of value will be in the cell.

    The problem arises with a call to: class openpyxl.workbook.names.external.External(name, refersTo, sheetId=None)

    Charlie: I don't know why I didn't do it at the time, but refersTo can be optional. Simply setting the descriptor to String(allow_none=True) and making None the default value for refersTo in the init will avoid this. Just tried this locally and it's fine but I get an exception elsewhere trying to save the file.

    Marco: In my case this would be sufficient - I am reading the file only - but then... when it needs to be fixed why not fixing it properly.

    So, the refersTo-part is not in the dictionary n.attrib = {'name': 'FT'} This load_workbook function loaded without problems with openpyxl 2.0.5/1.8.4

    Charlie: Support for external links was only added in 2.1 and is still a bit rough, so you get no errors in earlier versions because they are just ignored (and stripped out). Seeing as you're disabling macros and working with the values only, I suspect you're not interested in preserving everything in the workbook anyway.

    Marco: As I am reading the files only (read-only) it, I don't care about preserving anything.

    Marco: What patch would resolve the issue? Should I adapt External.init(name, refersTo=None, sheetId=None)

    Thanks for your quick input - Have a splendid day! Marco

  2. Log in to comment