For my package dealing with pptx-files I need to create a temporary *.pptx file, to open in PowerPoint (e.g. to export as PDF). After some research I found that tempfile.NamedTemporaryFile is broken on Windows (you could have a temporary file, or you could get a filename - but you cannot have both). So I tried to build a function, that returns a filename of a temporary file, and takes care of creating and deleting the file internally. After going in circles many times I came up with the following code monster:
import os from typing import Generator import tempfile import pptx class TempFileGenerator: generator = None @classmethod def get_new_generator(cls, prs): TempFileGenerator.generator = cls.temp_generator(prs) return cls.generator @staticmethod def temp_generator(prs: pptx.presentation.Presentation) -> Generator[str, None, None]: temp_pptx = None try: with tempfile.NamedTemporaryFile(suffix='.pptx', delete=False) as temp_pptx: temp_pptx.close() # needed on windows systems to access file prs.save(temp_pptx.name) yield temp_pptx.name finally: if temp_pptx is not None: try: os.remove(temp_pptx.name) except PermissionError as e: # file still in use somewhere pass else: print("How did I get here?") def get_temporary_pptx_filename(prs: pptx.presentation.Presentation) -> str: """ Generates a temporary pptx file. Returns the filename of the temporary file. """ my_generator = TempFileGenerator.get_new_generator(prs) for filename in my_generator: return filename
get_temporary_pptx_filename() does what I want. Using a class to save the generator ensures, that the clean up in finally does not happen as soon as I return the filename in
get_temporary_pptx_filename. But looking at this code monster, I hope there is a better way to do it? If not I guess it would be easier to not use the tempfile module at all.