tmp_file_type

pytest_tmp_files.tmp_file_type(type: str)[source]

Teach pytest_tmp_files how to make a new kind of file.

Parameters:

type – The string that will identify this kind of file in the specification dictionary.

This function is a decorator. When a file of the given type is requested, the decorated function will be called with two arguments: path and meta. The former is the path to create, and the latter is a free-form dictionary containing any user-specified information about the requested file. These arguments directly correspond to the key and value of an item in the specification dictionary. The function should create the requested file and return nothing.

Example

The following snippet defines a custom file type called “xlsx” for making Excel spreadsheets. It’s hard to write tests involving these files because they have a binary format. This file type helps by allowing each sheet to be specified in the CSV format. Specifically, this file type expects the metadata to include a field called ‘sheets’, which should be a dictionary mapping sheet names to CSV strings.

I apologize if this example is a bit hard to understand, on account of using a third-party library and just having a lot of code. I chose this example because (i) it was a real problem I had to solve for myself and (ii) it perfectly embodies the intended use-case of this function, which is to make it easier to parametrize binary files.

>>> from pytest_tmp_files import *
>>> @tmp_file_type('xlsx')
... def make_xlsx_file(path, meta):
...     import csv, io, openpyxl
...     wb = openpyxl.Workbook()
...
...     def iter_worksheets():
...         for i, title in enumerate(meta['sheets']):
...             if i == 0:
...                 wb.active.title = title
...                 yield wb.active
...             else:
...                 yield wb.create_sheet(title)
...
...     for ws in iter_worksheets():
...         content = meta['sheets'][ws.title]
...         content_io = io.StringIO(content)
...
...         for i, row in enumerate(csv.reader(content_io), 1):
...             for j, value in enumerate(row, 1):
...                 ws.cell(i, j).value = value
...
...     wb.save(path)

Here’s how this custom file type could be used:

>>> make_files(Path.cwd(), {
...     'demo.xlsx': {
...         'type': 'xlsx',
...         'sheets': {'Sheet1': "Hello,World"},
...     }
... })
...
>>> from openpyxl import load_workbook
>>> wb = load_workbook('demo.xlsx')
>>> wb['Sheet1']['A1'].value
'Hello'
>>> wb['Sheet1']['B1'].value
'World'