diff --git a/.travis.yml b/.travis.yml index 7426bb0..e370649 100755 --- a/.travis.yml +++ b/.travis.yml @@ -8,14 +8,6 @@ install: - make install jobs: include: - - stage: test - script: - - make test - python: '2.7' - - stage: test - script: - - make test - python: '3.5' - stage: test script: - make test @@ -25,8 +17,13 @@ jobs: - make test python: '3.7' dist: xenial + - stage: test + script: + - make test + python: '3.8' + dist: xenial - stage: coverage - python: '3.6' + python: '3.8' script: - make test - codecov --verbose diff --git a/camelot/__main__.py b/camelot/__main__.py index 93040c6..a0b82a6 100755 --- a/camelot/__main__.py +++ b/camelot/__main__.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import - __all__ = ("main",) diff --git a/camelot/__version__.py b/camelot/__version__.py index f4e1005..145df48 100644 --- a/camelot/__version__.py +++ b/camelot/__version__.py @@ -8,9 +8,9 @@ REVISION = None def generate_version(version, prerelease=None, revision=None): version_parts = [".".join(map(str, version))] if prerelease is not None: - version_parts.append("-{}".format(prerelease)) + version_parts.append(f"-{prerelease}") if revision is not None: - version_parts.append(".{}".format(revision)) + version_parts.append(f".{revision}") return "".join(version_parts) diff --git a/camelot/cli.py b/camelot/cli.py index 0298992..1715e6f 100644 --- a/camelot/cli.py +++ b/camelot/cli.py @@ -204,7 +204,7 @@ def lattice(c, *args, **kwargs): tables = read_pdf( filepath, pages=pages, flavor="lattice", suppress_stdout=quiet, **kwargs ) - click.echo("Found {} tables".format(tables.n)) + click.echo(f"Found {tables.n} tables") if plot_type is not None: for table in tables: plot(table, kind=plot_type) @@ -295,7 +295,7 @@ def stream(c, *args, **kwargs): tables = read_pdf( filepath, pages=pages, flavor="stream", suppress_stdout=quiet, **kwargs ) - click.echo("Found {} tables".format(tables.n)) + click.echo(f"Found {tables.n} tables") if plot_type is not None: for table in tables: plot(table, kind=plot_type) diff --git a/camelot/core.py b/camelot/core.py index b7a02b1..3ea2c5e 100644 --- a/camelot/core.py +++ b/camelot/core.py @@ -52,13 +52,10 @@ class TextEdge(object): self.is_valid = False def __repr__(self): - return "".format( - round(self.x, 2), - round(self.y0, 2), - round(self.y1, 2), - self.align, - self.is_valid, - ) + x = round(self.x, 2) + y0 = round(self.y0, 2) + y1 = round(self.y1, 2) + return f"" def update_coords(self, x, y0, edge_tol=50): """Updates the text edge's x and bottom y coordinates and sets @@ -291,9 +288,11 @@ class Cell(object): self._text = "" def __repr__(self): - return "".format( - round(self.x1, 2), round(self.y1, 2), round(self.x2, 2), round(self.y2, 2) - ) + x1 = round(self.x1, 2) + y1 = round(self.y1, 2) + x2 = round(self.x2, 2) + y2 = round(self.y2, 2) + return f"" @property def text(self): @@ -351,7 +350,7 @@ class Table(object): self.page = None def __repr__(self): - return "<{} shape={}>".format(self.__class__.__name__, self.shape) + return f"<{self.__class__.__name__} shape={self.shape}>" def __lt__(self, other): if self.page == other.page: @@ -612,7 +611,7 @@ class Table(object): """ kw = { - "sheet_name": "page-{}-table-{}".format(self.page, self.order), + "sheet_name": f"page-{self.page}-table-{self.order}", "encoding": "utf-8", } kw.update(kwargs) @@ -649,7 +648,7 @@ class Table(object): kw = {"if_exists": "replace", "index": False} kw.update(kwargs) conn = sqlite3.connect(path) - table_name = "page-{}-table-{}".format(self.page, self.order) + table_name = f"page-{self.page}-table-{self.order}" self.df.to_sql(table_name, conn, **kw) conn.commit() conn.close() @@ -670,7 +669,7 @@ class TableList(object): self._tables = tables def __repr__(self): - return "<{} n={}>".format(self.__class__.__name__, self.n) + return f"<{self.__class__.__name__} n={self.n}>" def __len__(self): return len(self._tables) @@ -680,7 +679,7 @@ class TableList(object): @staticmethod def _format_func(table, f): - return getattr(table, "to_{}".format(f)) + return getattr(table, f"to_{f}") @property def n(self): @@ -691,9 +690,7 @@ class TableList(object): root = kwargs.get("root") ext = kwargs.get("ext") for table in self._tables: - filename = os.path.join( - "{}-page-{}-table-{}{}".format(root, table.page, table.order, ext) - ) + filename = f"{root}-page-{table.page}-table-{table.order}{ext}" filepath = os.path.join(dirname, filename) to_format = self._format_func(table, f) to_format(filepath) @@ -706,9 +703,7 @@ class TableList(object): zipname = os.path.join(os.path.dirname(path), root) + ".zip" with zipfile.ZipFile(zipname, "w", allowZip64=True) as z: for table in self._tables: - filename = os.path.join( - "{}-page-{}-table-{}{}".format(root, table.page, table.order, ext) - ) + filename = f"{root}-page-{table.page}-table-{table.order}{ext}" filepath = os.path.join(dirname, filename) z.write(filepath, os.path.basename(filepath)) @@ -741,7 +736,7 @@ class TableList(object): filepath = os.path.join(dirname, basename) writer = pd.ExcelWriter(filepath) for table in self._tables: - sheet_name = "page-{}-table-{}".format(table.page, table.order) + sheet_name = f"page-{table.page}-table-{table.order}" table.df.to_excel(writer, sheet_name=sheet_name, encoding="utf-8") writer.save() if compress: diff --git a/camelot/ext/ghostscript/_gsprint.py b/camelot/ext/ghostscript/_gsprint.py index b31b768..9896805 100644 --- a/camelot/ext/ghostscript/_gsprint.py +++ b/camelot/ext/ghostscript/_gsprint.py @@ -81,6 +81,7 @@ def delete_instance(instance): """ return libgs.gsapi_delete_instance(instance) + if sys.platform == "win32": c_stdstream_call_t = WINFUNCTYPE(c_int, gs_main_instance, POINTER(c_char), c_int) else: @@ -247,7 +248,10 @@ if sys.platform == "win32": libgs = __win32_finddll() if not libgs: import ctypes.util - libgs = ctypes.util.find_library("".join(("gsdll", str(ctypes.sizeof(ctypes.c_voidp) * 8), ".dll"))) # finds in %PATH% + + libgs = ctypes.util.find_library( + "".join(("gsdll", str(ctypes.sizeof(ctypes.c_voidp) * 8), ".dll")) + ) # finds in %PATH% if not libgs: raise RuntimeError("Please make sure that Ghostscript is installed") libgs = windll.LoadLibrary(libgs) diff --git a/camelot/handlers.py b/camelot/handlers.py index 3a6d663..6aa3a31 100644 --- a/camelot/handlers.py +++ b/camelot/handlers.py @@ -106,7 +106,7 @@ class PDFHandler(object): infile = PdfFileReader(fileobj, strict=False) if infile.isEncrypted: infile.decrypt(self.password) - fpath = os.path.join(temp, "page-{0}.pdf".format(page)) + fpath = os.path.join(temp, f"page-{page}.pdf") froot, fext = os.path.splitext(fpath) p = infile.getPage(page - 1) outfile = PdfFileWriter() @@ -164,7 +164,7 @@ class PDFHandler(object): for p in self.pages: self._save_page(self.filepath, p, tempdir) pages = [ - os.path.join(tempdir, "page-{0}.pdf".format(p)) for p in self.pages + os.path.join(tempdir, f"page-{p}.pdf") for p in self.pages ] parser = Lattice(**kwargs) if flavor == "lattice" else Stream(**kwargs) for p in pages: diff --git a/camelot/image_processing.py b/camelot/image_processing.py index 7b87101..08acb23 100644 --- a/camelot/image_processing.py +++ b/camelot/image_processing.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division - import cv2 import numpy as np diff --git a/camelot/parsers/lattice.py b/camelot/parsers/lattice.py index 197ff9f..5469fac 100644 --- a/camelot/parsers/lattice.py +++ b/camelot/parsers/lattice.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division import os import sys import copy diff --git a/camelot/parsers/stream.py b/camelot/parsers/stream.py index 33f2fe5..3749028 100644 --- a/camelot/parsers/stream.py +++ b/camelot/parsers/stream.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import division import os import logging import warnings @@ -358,7 +357,7 @@ class Stream(BaseParser): ncols = max(set(elements), key=elements.count) else: warnings.warn( - "No tables found in table area {}".format(table_idx + 1) + f"No tables found in table area {table_idx + 1}" ) cols = [(t.x0, t.x1) for r in rows_grouped if len(r) == ncols for t in r] cols = self._merge_columns(sorted(cols), column_tol=self.column_tol) @@ -433,19 +432,19 @@ class Stream(BaseParser): def extract_tables(self, filename, suppress_stdout=False, layout_kwargs={}): self._generate_layout(filename, layout_kwargs) + base_filename = os.path.basename(self.rootname) + if not suppress_stdout: - logger.info("Processing {}".format(os.path.basename(self.rootname))) + logger.info(f"Processing {base_filename}") if not self.horizontal_text: if self.images: warnings.warn( - "{} is image-based, camelot only works on" - " text-based pages.".format(os.path.basename(self.rootname)) + f"{base_filename} is image-based, camelot only works on" + " text-based pages." ) else: - warnings.warn( - "No tables found on {}".format(os.path.basename(self.rootname)) - ) + warnings.warn(f"No tables found on {base_filename}") return [] self._generate_table_bbox() diff --git a/camelot/plotting.py b/camelot/plotting.py index 5e0dc0c..a5930c2 100644 --- a/camelot/plotting.py +++ b/camelot/plotting.py @@ -35,11 +35,11 @@ class PlotMethods(object): if table.flavor == "lattice" and kind in ["textedge"]: raise NotImplementedError( - "Lattice flavor does not support kind='{}'".format(kind) + f"Lattice flavor does not support kind='{kind}'" ) elif table.flavor == "stream" and kind in ["joint", "line"]: raise NotImplementedError( - "Stream flavor does not support kind='{}'".format(kind) + f"Stream flavor does not support kind='{kind}'" ) plot_method = getattr(self, kind) diff --git a/camelot/utils.py b/camelot/utils.py index e7ad848..1f54485 100644 --- a/camelot/utils.py +++ b/camelot/utils.py @@ -1,9 +1,7 @@ # -*- coding: utf-8 -*- -from __future__ import division -import re import os -import sys +import re import random import shutil import string @@ -29,16 +27,9 @@ from pdfminer.layout import ( LTImage, ) - -PY3 = sys.version_info[0] >= 3 -if PY3: - from urllib.request import urlopen - from urllib.parse import urlparse as parse_url - from urllib.parse import uses_relative, uses_netloc, uses_params -else: - from urllib2 import urlopen - from urlparse import urlparse as parse_url - from urlparse import uses_relative, uses_netloc, uses_params +from urllib.request import Request, urlopen +from urllib.parse import urlparse as parse_url +from urllib.parse import uses_relative, uses_netloc, uses_params _VALID_URLS = set(uses_relative + uses_netloc + uses_params) @@ -88,13 +79,12 @@ def download_url(url): Temporary filepath. """ - filename = "{}.pdf".format(random_string(6)) + filename = f"{random_string(6)}.pdf" with tempfile.NamedTemporaryFile("wb", delete=False) as f: - obj = urlopen(url) - if PY3: - content_type = obj.info().get_content_type() - else: - content_type = obj.info().getheader("Content-Type") + headers = {"User-Agent": "Mozilla/5.0"} + request = Request(url, None, headers) + obj = urlopen(request) + content_type = obj.info().get_content_type() if content_type != "application/pdf": raise NotImplementedError("File format not supported") f.write(obj.read()) @@ -123,9 +113,7 @@ def validate_input(kwargs, flavor="lattice"): isec = set(parser_kwargs).intersection(set(input_kwargs.keys())) if isec: raise ValueError( - "{} cannot be used with flavor='{}'".format( - ",".join(sorted(isec)), flavor - ) + f"{','.join(sorted(isec))} cannot be used with flavor='{flavor}'" ) if flavor == "lattice": @@ -423,7 +411,7 @@ def text_strip(text, strip=""): return text stripped = re.sub( - r"[{}]".format("".join(map(re.escape, strip))), "", text, re.UNICODE + fr"[{''.join(map(re.escape, strip))}]", "", text, re.UNICODE ) return stripped @@ -660,9 +648,7 @@ def get_table_index( text_range = (t.x0, t.x1) col_range = (table.cols[0][0], table.cols[-1][1]) warnings.warn( - "{} {} does not lie in column range {}".format( - text, text_range, col_range - ) + f"{text} {text_range} does not lie in column range {col_range}" ) r_idx = r c_idx = lt_col_overlap.index(max(lt_col_overlap)) diff --git a/setup.py b/setup.py index b83f566..0619f12 100644 --- a/setup.py +++ b/setup.py @@ -71,10 +71,10 @@ def setup_package(): # Trove classifiers # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7' + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8' ]) try: diff --git a/tests/__init__.py b/tests/__init__.py index a946ff7..96c475e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,2 +1,3 @@ import matplotlib -matplotlib.use('agg') + +matplotlib.use("agg") diff --git a/tests/data.py b/tests/data.py index 3338a81..7e53792 100755 --- a/tests/data.py +++ b/tests/data.py @@ -1,19 +1,7 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals - data_stream = [ - [ - "", - "Table: 5 Public Health Outlay 2012-13 (Budget Estimates) (Rs. in 000)", - "", - "", - "", - "", - "", - "", - ], ["States-A", "Revenue", "", "Capital", "", "Total", "Others(1)", "Total"], ["", "", "", "", "", "Revenue &", "", ""], ["", "Medical &", "Family", "Medical &", "Family", "", "", ""], @@ -829,18 +817,6 @@ data_stream_table_rotated = [ ] data_stream_two_tables_1 = [ - [ - "[In thousands (11,062.6 represents 11,062,600) For year ending December 31. Based on Uniform Crime Reporting (UCR)", - "", - "", - "", - "", - "", - "", - "", - "", - "", - ], [ "Program. Represents arrests reported (not charged) by 12,910 agencies with a total population of 247,526,916 as estimated", "", @@ -915,7 +891,7 @@ data_stream_two_tables_1 = [ "2,330 .9", ], [ - "Violent crime . . . . . . . .\n . .\n . .\n . .\n . .\n . .", + "Violent crime . . . . . . . .\n . .\n . .\n . .\n . .\n . .", "467 .9", "69 .1", "398 .8", @@ -1300,29 +1276,10 @@ data_stream_two_tables_1 = [ "", "", ], - [ - "", - "Source: U.S. Department of Justice, Federal Bureau of Investigation, Uniform Crime Reports, Arrests Master Files.", - "", - "", - "", - "", - "", - "", - "", - "", - ], ] + data_stream_two_tables_2 = [ - [ - "", - "Source: U.S. Department of Justice, Federal Bureau of Investigation, Uniform Crime Reports, Arrests Master Files.", - "", - "", - "", - "", - ], ["Table 325. Arrests by Race: 2009", "", "", "", "", ""], [ "[Based on Uniform Crime Reporting (UCR) Program. Represents arrests reported (not charged) by 12,371 agencies", @@ -1352,7 +1309,7 @@ data_stream_two_tables_2 = [ "123,656", ], [ - "Violent crime . . . . . . . .\n . .\n . .\n . .\n . .\n .\n .\n . .\n . .\n .\n .\n .\n .\n . .", + "Violent crime . . . . . . . .\n . .\n . .\n . .\n . .\n .\n .\n . .\n . .\n .\n .\n .\n .\n . .", "456,965", "268,346", "177,766", @@ -1600,16 +1557,9 @@ data_stream_two_tables_2 = [ "3,950", ], ["1 Except forcible rape and prostitution.", "", "", "", "", ""], - [ - "", - "Source: U.S. Department of Justice, Federal Bureau of Investigation, “Crime in the United States, Arrests,” September 2010,", - "", - "", - "", - "", - ], ] + data_stream_table_areas = [ ["", "One Withholding"], ["Payroll Period", "Allowance"], @@ -1776,18 +1726,7 @@ data_stream_columns = [ ] data_stream_split_text = [ - [ - "FEB", - "RUAR", - "Y 2014 M27 (BUS)", - "", - "ALPHABETIC LISTING BY T", - "YPE", - "", - "", - "", - "ABLPDM27", - ], + ["FEB", "RUAR", "Y 2014 M27 (BUS)", "", "", "", "", "", "", ""], ["", "", "", "", "OF ACTIVE LICENSES", "", "", "", "", "3/19/2014"], ["", "", "", "", "OKLAHOMA ABLE COMMIS", "SION", "", "", "", ""], ["LICENSE", "", "", "", "PREMISE", "", "", "", "", ""], @@ -2121,6 +2060,7 @@ data_stream_split_text = [ ], ] + data_stream_flag_size = [ [ "States", @@ -2820,7 +2760,7 @@ data_arabic = [ ] data_stream_layout_kwargs = [ - ["V i n s a u Ve r r e", ""], + ["V i n s a u V e r r e", ""], ["Les Blancs", "12.5CL"], ["A.O.P Côtes du Rhône", ""], ["Domaine de la Guicharde « Autour de la chapelle » 2016", "8 €"], diff --git a/tests/files/baseline_plots/test_joint_plot.png b/tests/files/baseline_plots/test_joint_plot.png index e9e40ec..61df900 100644 Binary files a/tests/files/baseline_plots/test_joint_plot.png and b/tests/files/baseline_plots/test_joint_plot.png differ diff --git a/tests/files/baseline_plots/test_line_plot.png b/tests/files/baseline_plots/test_line_plot.png index e8099ce..12c44c0 100644 Binary files a/tests/files/baseline_plots/test_line_plot.png and b/tests/files/baseline_plots/test_line_plot.png differ diff --git a/tests/files/baseline_plots/test_stream_contour_plot.png b/tests/files/baseline_plots/test_stream_contour_plot.png index a6e77f7..958ea0a 100644 Binary files a/tests/files/baseline_plots/test_stream_contour_plot.png and b/tests/files/baseline_plots/test_stream_contour_plot.png differ diff --git a/tests/files/baseline_plots/test_text_plot.png b/tests/files/baseline_plots/test_text_plot.png index 8cc3825..63b5520 100644 Binary files a/tests/files/baseline_plots/test_text_plot.png and b/tests/files/baseline_plots/test_text_plot.png differ diff --git a/tests/files/baseline_plots/test_textedge_plot.png b/tests/files/baseline_plots/test_textedge_plot.png index 63fc236..1de4e9c 100644 Binary files a/tests/files/baseline_plots/test_textedge_plot.png and b/tests/files/baseline_plots/test_textedge_plot.png differ diff --git a/tests/test_cli.py b/tests/test_cli.py index d1a660f..cddc9a2 100755 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -114,31 +114,35 @@ def test_cli_password(): def test_cli_output_format(): with TemporaryDirectory() as tempdir: infile = os.path.join(testdir, "health.pdf") - outfile = os.path.join(tempdir, "health.{}") + runner = CliRunner() # json + outfile = os.path.join(tempdir, "health.json") result = runner.invoke( cli, - ["--format", "json", "--output", outfile.format("json"), "stream", infile], + ["--format", "json", "--output", outfile, "stream", infile], ) assert result.exit_code == 0 # excel + outfile = os.path.join(tempdir, "health.xlsx") result = runner.invoke( cli, - ["--format", "excel", "--output", outfile.format("xlsx"), "stream", infile], + ["--format", "excel", "--output", outfile, "stream", infile], ) assert result.exit_code == 0 # html + outfile = os.path.join(tempdir, "health.html") result = runner.invoke( cli, - ["--format", "html", "--output", outfile.format("html"), "stream", infile], + ["--format", "html", "--output", outfile, "stream", infile], ) assert result.exit_code == 0 # zip + outfile = os.path.join(tempdir, "health.csv") result = runner.invoke( cli, [ @@ -146,7 +150,7 @@ def test_cli_output_format(): "--format", "csv", "--output", - outfile.format("csv"), + outfile, "stream", infile, ], diff --git a/tests/test_errors.py b/tests/test_errors.py index 0a11c55..2849110 100755 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -10,88 +10,93 @@ import camelot testdir = os.path.dirname(os.path.abspath(__file__)) testdir = os.path.join(testdir, "files") -filename = os.path.join(testdir, 'foo.pdf') +filename = os.path.join(testdir, "foo.pdf") def test_unknown_flavor(): - message = ("Unknown flavor specified." - " Use either 'lattice' or 'stream'") + message = "Unknown flavor specified." " Use either 'lattice' or 'stream'" with pytest.raises(NotImplementedError, match=message): - tables = camelot.read_pdf(filename, flavor='chocolate') + tables = camelot.read_pdf(filename, flavor="chocolate") def test_input_kwargs(): message = "columns cannot be used with flavor='lattice'" with pytest.raises(ValueError, match=message): - tables = camelot.read_pdf(filename, columns=['10,20,30,40']) + tables = camelot.read_pdf(filename, columns=["10,20,30,40"]) def test_unsupported_format(): - message = 'File format not supported' - filename = os.path.join(testdir, 'foo.csv') + message = "File format not supported" + filename = os.path.join(testdir, "foo.csv") with pytest.raises(NotImplementedError, match=message): tables = camelot.read_pdf(filename) def test_stream_equal_length(): - message = ("Length of table_areas and columns" - " should be equal") + message = "Length of table_areas and columns" " should be equal" with pytest.raises(ValueError, match=message): - tables = camelot.read_pdf(filename, flavor='stream', - table_areas=['10,20,30,40'], columns=['10,20,30,40', '10,20,30,40']) + tables = camelot.read_pdf( + filename, + flavor="stream", + table_areas=["10,20,30,40"], + columns=["10,20,30,40", "10,20,30,40"], + ) def test_image_warning(): - filename = os.path.join(testdir, 'image.pdf') + filename = os.path.join(testdir, "image.pdf") with warnings.catch_warnings(): - warnings.simplefilter('error') + warnings.simplefilter("error") with pytest.raises(UserWarning) as e: tables = camelot.read_pdf(filename) - assert str(e.value) == 'page-1 is image-based, camelot only works on text-based pages.' + assert ( + str(e.value) + == "page-1 is image-based, camelot only works on text-based pages." + ) def test_no_tables_found(): - filename = os.path.join(testdir, 'blank.pdf') + filename = os.path.join(testdir, "blank.pdf") with warnings.catch_warnings(): - warnings.simplefilter('error') + warnings.simplefilter("error") with pytest.raises(UserWarning) as e: tables = camelot.read_pdf(filename) - assert str(e.value) == 'No tables found on page-1' + assert str(e.value) == "No tables found on page-1" def test_no_tables_found_logs_suppressed(): - filename = os.path.join(testdir, 'foo.pdf') + filename = os.path.join(testdir, "foo.pdf") with warnings.catch_warnings(): # the test should fail if any warning is thrown - warnings.simplefilter('error') + warnings.simplefilter("error") try: tables = camelot.read_pdf(filename, suppress_stdout=True) except Warning as e: warning_text = str(e) - pytest.fail('Unexpected warning: {}'.format(warning_text)) + pytest.fail(f"Unexpected warning: {warning_text}") def test_no_tables_found_warnings_suppressed(): - filename = os.path.join(testdir, 'blank.pdf') + filename = os.path.join(testdir, "blank.pdf") with warnings.catch_warnings(): # the test should fail if any warning is thrown - warnings.simplefilter('error') + warnings.simplefilter("error") try: tables = camelot.read_pdf(filename, suppress_stdout=True) except Warning as e: warning_text = str(e) - pytest.fail('Unexpected warning: {}'.format(warning_text)) + pytest.fail(f"Unexpected warning: {warning_text}") def test_no_password(): - filename = os.path.join(testdir, 'health_protected.pdf') - message = 'file has not been decrypted' + filename = os.path.join(testdir, "health_protected.pdf") + message = "file has not been decrypted" with pytest.raises(Exception, match=message): tables = camelot.read_pdf(filename) def test_bad_password(): - filename = os.path.join(testdir, 'health_protected.pdf') - message = 'file has not been decrypted' + filename = os.path.join(testdir, "health_protected.pdf") + message = "file has not been decrypted" with pytest.raises(Exception, match=message): - tables = camelot.read_pdf(filename, password='wrongpass') + tables = camelot.read_pdf(filename, password="wrongpass") diff --git a/tests/test_plotting.py b/tests/test_plotting.py index f267e29..cec9df6 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -11,57 +11,50 @@ testdir = os.path.dirname(os.path.abspath(__file__)) testdir = os.path.join(testdir, "files") -@pytest.mark.mpl_image_compare( - baseline_dir="files/baseline_plots", remove_text=True) +@pytest.mark.mpl_image_compare(baseline_dir="files/baseline_plots", remove_text=True) def test_text_plot(): filename = os.path.join(testdir, "foo.pdf") tables = camelot.read_pdf(filename) - return camelot.plot(tables[0], kind='text') + return camelot.plot(tables[0], kind="text") -@pytest.mark.mpl_image_compare( - baseline_dir="files/baseline_plots", remove_text=True) +@pytest.mark.mpl_image_compare(baseline_dir="files/baseline_plots", remove_text=True) def test_grid_plot(): filename = os.path.join(testdir, "foo.pdf") tables = camelot.read_pdf(filename) - return camelot.plot(tables[0], kind='grid') + return camelot.plot(tables[0], kind="grid") -@pytest.mark.mpl_image_compare( - baseline_dir="files/baseline_plots", remove_text=True) +@pytest.mark.mpl_image_compare(baseline_dir="files/baseline_plots", remove_text=True) def test_lattice_contour_plot(): filename = os.path.join(testdir, "foo.pdf") tables = camelot.read_pdf(filename) - return camelot.plot(tables[0], kind='contour') + return camelot.plot(tables[0], kind="contour") -@pytest.mark.mpl_image_compare( - baseline_dir="files/baseline_plots", remove_text=True) +@pytest.mark.mpl_image_compare(baseline_dir="files/baseline_plots", remove_text=True) def test_stream_contour_plot(): filename = os.path.join(testdir, "tabula/12s0324.pdf") - tables = camelot.read_pdf(filename, flavor='stream') - return camelot.plot(tables[0], kind='contour') + tables = camelot.read_pdf(filename, flavor="stream") + return camelot.plot(tables[0], kind="contour") -@pytest.mark.mpl_image_compare( - baseline_dir="files/baseline_plots", remove_text=True) +@pytest.mark.mpl_image_compare(baseline_dir="files/baseline_plots", remove_text=True) def test_line_plot(): filename = os.path.join(testdir, "foo.pdf") tables = camelot.read_pdf(filename) - return camelot.plot(tables[0], kind='line') + return camelot.plot(tables[0], kind="line") -@pytest.mark.mpl_image_compare( - baseline_dir="files/baseline_plots", remove_text=True) +@pytest.mark.mpl_image_compare(baseline_dir="files/baseline_plots", remove_text=True) def test_joint_plot(): filename = os.path.join(testdir, "foo.pdf") tables = camelot.read_pdf(filename) - return camelot.plot(tables[0], kind='joint') + return camelot.plot(tables[0], kind="joint") -@pytest.mark.mpl_image_compare( - baseline_dir="files/baseline_plots", remove_text=True) +@pytest.mark.mpl_image_compare(baseline_dir="files/baseline_plots", remove_text=True) def test_textedge_plot(): filename = os.path.join(testdir, "tabula/12s0324.pdf") - tables = camelot.read_pdf(filename, flavor='stream') - return camelot.plot(tables[0], kind='textedge') + tables = camelot.read_pdf(filename, flavor="stream") + return camelot.plot(tables[0], kind="textedge")