0

The issue described here looked initially like it was solvable by just having the spreadsheet closed in Excel before running the program.

It transpires, however, that having Excel closed is a necessary, but not sufficient, condition. The issue still occurs, but not on every Windows machine, and not every time (sometimes it occurs after a single execution, sometimes two).

I've modified the program such that it now reads from one spreadsheet and writes to a different one, still the issue presents itself. I even go on to programmatically kill any lingering Python processes before running the program. Still no joy.

The openpyxl save() function instantiates ZipFile thus:

archive = ZipFile(filename, 'w', ZIP_DEFLATED, allowZip64=True) 

... with Zipfile then using that to attempt to open the file in mode 'wb' thus:

if isinstance(file, basestring): self._filePassed = 0 self.filename = file modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'} try: self.fp = open(file, modeDict[mode]) except IOError: if mode == 'a': mode = key = 'w' self.fp = open(file, modeDict[mode]) else: raise 

According to the docs:

On Windows, 'b' appended to the mode opens the file in binary mode, so there are also modes like 'rb', 'wb', and 'r+b'. Python on Windows makes a distinction between text and binary files; the end-of-line characters in text files are automatically altered slightly when data is read or written. This behind-the-scenes modification to file data is fine for ASCII text files, but it’ll corrupt binary data like that in JPEG or EXE files. Be very careful to use binary mode when reading and writing such files. On Unix, it doesn’t hurt to append a 'b' to the mode, so you can use it platform-independently for all binary files.

... which explains why mode 'wb' must be used.

Is there something in Python file opening that could possibly leave the file in some state of "openness"?

Windows: 8

Python: 2.7.10

openpyxl: latest

9
  • Not sure if I understand your problem, but shouldn't you just self.fp.close() at the end of your operation? Commented Jul 22, 2015 at 17:08
  • It would be useful to record Windows, python and openpyxl versions when it works and when it doesn't. Have you thought of filling a bug-report? Commented Jul 22, 2015 at 17:25
  • @rroszkowiak The code above is an extract from ZipFile, part of the Python standard library. I'd prefer not to touch it. Commented Jul 22, 2015 at 17:26
  • 1
    @CraigS.Anderson Better to use the with syntax. Commented Jul 22, 2015 at 18:41
  • 1
    Sorry, I don't understand what the problem is. The Python close is immediate. If Excel is invoked, it is far more likely that is the cause of any file sharing problems. It is sloppy about closing the data file after reading it and intentionally creates a file lock file which persists for many seconds after it is no longer needed. Can you narrow down what symptoms you are seeing? Commented Jul 22, 2015 at 18:48

1 Answer 1

2

Two suggestions:

First is to use with to close the file correctly.

with open("some.xls", "wb") as excel_file: #Do something 

At the end of that the file will close on its own (see this).

You can also make a copy of the file and work on the copied file.

import shutil shutil.copyfile(src, dst) 

https://docs.python.org/2/library/shutil.html#shutil.copyfile

Sign up to request clarification or add additional context in comments.

1 Comment

It's openpyxl code that does the file opening, so I'd rather leave that alone. Your suggestion to copy the file is an excellent one though, and I will certainly trial it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.