Search code examples
python-3.xxlsxwriterqpythonqpython3

PermissionError when closing xlsxwriter Workbook in QPython despite having permissions


I do have permission to write to a specific directory, and the file gets created too. But the line w.close() causes the error.

Since I'm using this module to create the file, it isn't open in any other application.

If it's relevant, other modules like csv are working fine.

/data/user/0/org.qpython.qpy/files/bin/qpython3-android5.sh && exit
n/qpython3-android5.sh && exit          <
Python 3.6.6 (qpyc:3.6.6, Jul 26 2018, 03:54:22) [BUILD WITH QPY3-TOOLCHAIN (https://github.com/qpython-android) ] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.chdir('scripts3')
>>> os.getcwd()
'/storage/emulated/0/qpython/scripts3'
>>> import xlsxwriter
>>> w = xlsxwriter.Workbook('0.xlsx')
>>> w.close()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/data/user/0/org.qpython.qpy/files/lib/python3.6/site-packages/xlsxwriter/workbook.py", line 306, in close
    self._store_workbook()
  File "/data/user/0/org.qpython.qpy/files/lib/python3.6/site-packages/xlsxwriter/workbook.py", line 675, in _store_workbook
    os.utime(os_filename, (timestamp, timestamp))
PermissionError: [Errno 1] Operation not permitted
>>>

EDIT: Solution

If someone encounters this error in a PC, jmcnamara's solution will be appropriate.

w = xlsxwriter.Workbook('0.xlsx', {'tmpdir': 'path/to/tmpdir'})

That didn't work with qpython. So I used in_memory parameter of the constructor, which worked.

w = xlsxwriter.Workbook('0.xlsx', {'in_memory': True})

Solution

  • XlsxWriter uses tmp files to create the XML files that make up an xlsx file before zipping them into the xlsx file.

    The error you are seeing is due to a lack of permissions on the tmp dir that Python is using on your system. Note, this directory isn't the same as the directory where the output file is being created.

    You can find the tmpdir location by running the following in the same environment as your application:

    import tempfile
    print(tempfile.gettempdir())
    

    You can resolve this in 2 ways:

    1. Change permission on the default tmp dir use by Python, and thus by XlsxWriter.
    2. Change the location of the tmp dir used by XlsxWriter using the tmpdir parameter of the constructor.