From 693e4f48a3cf3655d6a2bfa99a58a4eddad98535 Mon Sep 17 00:00:00 2001 From: Ev2geny Date: Mon, 26 Oct 2020 12:10:11 +0300 Subject: [PATCH] Issue #469 is fixed (When run on Windows a lot of tests fail with the error: [Errno 13] Permission denied) (#484) Closes #469 * Issue #469 is fixed * one extra comment to code is added * TemporaryFilePath context manager is added to facilitate tests * flake8 complaints fixed * Update docs of tempfilepath.py * Fix flake8 Co-authored-by: Pieter Marsman --- CHANGELOG.md | 2 ++ tests/tempfilepath.py | 58 +++++++++++++++++++++++++++++++++++++ tests/test_tools_dumppdf.py | 9 +++--- tests/test_tools_pdf2txt.py | 14 +++++---- 4 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 tests/tempfilepath.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 9428db9..30d9e11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,12 @@ All notable changes in pdfminer.six will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + ## [Unreleased] ### Fixed - Fix issue of TypeError: cannot unpack non-iterable PDFObjRef object, when unpacking the value of 'DW2' ([#529](https://github.com/pdfminer/pdfminer.six/pull/529)) +- `PermissionError` when creating temporary filepaths on windows when running tests ([#469](https://github.com/pdfminer/pdfminer.six/issues/469)) ## Removed - Support for Python 3.4 and 3.5 ([#522](https://github.com/pdfminer/pdfminer.six/pull/522)) diff --git a/tests/tempfilepath.py b/tests/tempfilepath.py new file mode 100644 index 0000000..39fb816 --- /dev/null +++ b/tests/tempfilepath.py @@ -0,0 +1,58 @@ +"""Helper module, which provides a TemporaryFilePath() context manager""" + +import tempfile +import os + + +class TemporaryFilePath(): + """Context manager class, which generates temporary file name + + Coonroraly to standard tempfile.NamedTemporaryFile(), it does not + create file. Upon exit from the context manager block, it will + attempt to delete the file with the generated file name. + + Example: + + >>> with TemporaryFilePath() as temp_file_name: + >>> with open(temp_file_name, "w") as temp_file: + >>> temp_file.write("some test data, which goes to the file") + >>> # some test code is here which reads data out of temp_file + + Args: + suffix: If 'suffix' is not None, the file name will end with that + suffix, otherwise there will be no suffix. + prefix: If 'prefix' is not None, the file name will begin with that + prefix, otherwise a default prefix is used. + dir: If 'dir' is not None, the file will be created in that directory, + otherwise a default directory is used. + delete: whether the file is deleted at the end (default True) + """ + + def __init__(self, suffix=None, prefix=None, dir=None, delete=True): + self.suffix = suffix + self.prefix = prefix + self.dir = dir + self.delete = delete + + def __enter__(self) -> str: + """Create temporary file path + + `tempfile.NamedTemporaryFile` will create and delete a file, and + this method only returns the filepath of the non-existing file. + """ + with tempfile.NamedTemporaryFile(suffix=self.suffix, + prefix=self.prefix, + dir=self.dir) as file: + self.temp_file_name = file.name + + return self.temp_file_name + + def __exit__(self, exc_type, exc_val, exc_tb): + if self.delete: + try: + os.remove(self.temp_file_name) + + # Exception 'FileNotFoundError' is acceptable as user may have not + # created the file to start with or has deleted it himself + except FileNotFoundError: + pass diff --git a/tests/test_tools_dumppdf.py b/tests/test_tools_dumppdf.py index 34b8bfe..8fcb769 100644 --- a/tests/test_tools_dumppdf.py +++ b/tests/test_tools_dumppdf.py @@ -1,19 +1,20 @@ import warnings -from tempfile import NamedTemporaryFile from helpers import absolute_sample_path +from tempfilepath import TemporaryFilePath from pdfminer.pdfdocument import PDFNoValidXRefWarning from tools import dumppdf def run(filename, options=None): absolute_path = absolute_sample_path(filename) - with NamedTemporaryFile() as output_file: + with TemporaryFilePath() as output_file_name: if options: - s = 'dumppdf -o %s %s %s' % (output_file.name, + s = 'dumppdf -o %s %s %s' % (output_file_name, options, absolute_path) else: - s = 'dumppdf -o %s %s' % (output_file.name, absolute_path) + s = 'dumppdf -o %s %s' % (output_file_name, absolute_path) + dumppdf.main(s.split(' ')[1:]) diff --git a/tests/test_tools_pdf2txt.py b/tests/test_tools_pdf2txt.py index 64ede32..b2604cc 100644 --- a/tests/test_tools_pdf2txt.py +++ b/tests/test_tools_pdf2txt.py @@ -1,19 +1,21 @@ import os from shutil import rmtree -from tempfile import NamedTemporaryFile, mkdtemp +from tempfile import mkdtemp import tools.pdf2txt as pdf2txt from helpers import absolute_sample_path +from tempfilepath import TemporaryFilePath def run(sample_path, options=None): absolute_path = absolute_sample_path(sample_path) - with NamedTemporaryFile() as output_file: + with TemporaryFilePath() as output_file_name: if options: s = 'pdf2txt -o{} {} {}' \ - .format(output_file.name, options, absolute_path) + .format(output_file_name, options, absolute_path) else: - s = 'pdf2txt -o{} {}'.format(output_file.name, absolute_path) + s = 'pdf2txt -o{} {}'.format(output_file_name, absolute_path) + pdf2txt.main(s.split(' ')[1:]) @@ -109,8 +111,8 @@ class TestDumpImages: @staticmethod def extract_images(input_file): output_dir = mkdtemp() - with NamedTemporaryFile() as output_file: - commands = ['-o', output_file.name, '--output-dir', + with TemporaryFilePath() as output_file_name: + commands = ['-o', output_file_name, '--output-dir', output_dir, input_file] pdf2txt.main(commands) image_files = os.listdir(output_dir)