diff --git a/README.md b/README.md index 4fa68d0..4408087 100644 --- a/README.md +++ b/README.md @@ -365,7 +365,7 @@ Package names of arguments can be separated by spaces. ```bash (venv) $ pip-licenses --with-system --ignore-packages django pip pip-licenses Name Version License - prettytable 3.5.0 BSD License + prettytable 3.12.0 BSD License pytz 2017.3 MIT setuptools 38.5.0 UNKNOWN wcwidth 0.2.5 MIT License @@ -376,7 +376,7 @@ Packages can also be specified with a version, only ignoring that specific versi ```bash (venv) $ pip-licenses --with-system --ignore-packages django pytz:2017.3 Name Version License - prettytable 3.5.0 BSD License + prettytable 3.12.0 BSD License setuptools 38.5.0 UNKNOWN wcwidth 0.2.5 MIT License ``` @@ -396,7 +396,7 @@ Package names of arguments can be separated by spaces. ```bash (venv) $ pip-licenses --with-system --packages prettytable pytz Name Version License - prettytable 3.5.0 BSD License + prettytable 3.12.0 BSD License pytz 2017.3 MIT ``` diff --git a/dev-requirements.txt b/dev-requirements.txt index edae1c3..daf6fdf 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -79,7 +79,7 @@ platformdirs==2.6.0 # via black pluggy==1.0.0 # via pytest -prettytable==3.9.0 +prettytable==3.12.0 # via -r requirements.in py==1.11.0 # via pytest-pycodestyle diff --git a/piplicenses.py b/piplicenses.py index b2e09ef..5826076 100755 --- a/piplicenses.py +++ b/piplicenses.py @@ -43,11 +43,7 @@ from typing import TYPE_CHECKING, Iterable, List, Type, cast import tomli -from prettytable import ALL as RULE_ALL -from prettytable import FRAME as RULE_FRAME -from prettytable import HEADER as RULE_HEADER -from prettytable import NONE as RULE_NONE -from prettytable import PrettyTable +from prettytable import HRuleStyle, PrettyTable, RowType if TYPE_CHECKING: from email.message import Message @@ -206,7 +202,7 @@ def get_pkg_included_file( lambda file: pattern.match(file.name), pkg_files ) for rel_path in matched_rel_paths: - abs_path = Path(pkg.locate_file(rel_path)) + abs_path = Path(str(pkg.locate_file(rel_path))) if not abs_path.is_file(): continue included_file = str(abs_path) @@ -362,7 +358,7 @@ def get_python_sys_path(executable: str) -> list[str]: def create_licenses_table( args: CustomNamespace, - output_fields: Iterable[str] = DEFAULT_OUTPUT_FIELDS, + output_fields: Sequence[str] = DEFAULT_OUTPUT_FIELDS, ) -> PrettyTable: table = factory_styled_table_with_args(args, output_fields) @@ -452,8 +448,8 @@ def case_insensitive_set_diff(set_a, set_b): class JsonPrettyTable(PrettyTable): """PrettyTable-like class exporting to JSON""" - def _format_row(self, row: Iterable[str]) -> dict[str, str | list[str]]: - resrow: dict[str, str | List[str]] = {} + def format_row(self, row: RowType) -> dict[str, str | list[str]]: + resrow: dict[str, str | list[str]] = {} for field, value in zip(self._field_names, row): resrow[field] = value @@ -467,17 +463,12 @@ def get_string(self, **kwargs: str | list[str]) -> str: options = self._get_options(kwargs) rows = self._get_rows(options) - formatted_rows = self._format_rows(rows) - - lines = [] - for row in formatted_rows: - lines.append(row) - + lines = [self.format_row(row) for row in rows] return json.dumps(lines, indent=2, sort_keys=True) class JsonLicenseFinderTable(JsonPrettyTable): - def _format_row(self, row: Iterable[str]) -> dict[str, str | list[str]]: + def format_row(self, row: RowType) -> dict[str, str | list[str]]: resrow: dict[str, str | List[str]] = {} for field, value in zip(self._field_names, row): if field == "Name": @@ -499,12 +490,7 @@ def get_string(self, **kwargs: str | list[str]) -> str: options = self._get_options(kwargs) rows = self._get_rows(options) - formatted_rows = self._format_rows(rows) - - lines = [] - for row in formatted_rows: - lines.append(row) - + lines = [self.format_row(row) for row in rows] return json.dumps(lines, sort_keys=True) @@ -530,16 +516,17 @@ def esc_quotes(val: bytes | str) -> str: rows = self._get_rows(options) formatted_rows = self._format_rows(rows) - lines = [] + lines: list[str] = [] formatted_header = ",".join( ['"%s"' % (esc_quotes(val),) for val in self._field_names] ) lines.append(formatted_header) - for row in formatted_rows: - formatted_row = ",".join( - ['"%s"' % (esc_quotes(val),) for val in row] - ) - lines.append(formatted_row) + lines.extend( + [ + ",".join(['"%s"' % (esc_quotes(val),) for val in row]) + for row in formatted_rows + ] + ) return "\n".join(lines) @@ -566,7 +553,7 @@ def get_string(self, **kwargs: str | list[str]) -> str: def factory_styled_table_with_args( args: CustomNamespace, - output_fields: Iterable[str] = DEFAULT_OUTPUT_FIELDS, + output_fields: Sequence[str] = DEFAULT_OUTPUT_FIELDS, ) -> PrettyTable: table = PrettyTable() table.field_names = output_fields # type: ignore[assignment] @@ -581,13 +568,13 @@ def factory_styled_table_with_args( if args.format_ == FormatArg.MARKDOWN: table.junction_char = "|" - table.hrules = RULE_HEADER + table.hrules = HRuleStyle.HEADER elif args.format_ == FormatArg.RST: table.junction_char = "+" - table.hrules = RULE_ALL + table.hrules = HRuleStyle.ALL elif args.format_ == FormatArg.CONFLUENCE: table.junction_char = "|" - table.hrules = RULE_NONE + table.hrules = HRuleStyle.NONE elif args.format_ == FormatArg.JSON: table = JsonPrettyTable(table.field_names) elif args.format_ == FormatArg.JSON_LICENSE_FINDER: diff --git a/pyproject.toml b/pyproject.toml index 54af8eb..0a0c39c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ "Typing :: Typed" ] dependencies = [ - "prettytable >= 2.3.0", + "prettytable >= 3.12.0", "tomli >= 2" ] @@ -75,7 +75,6 @@ known_first_party = ["piplicenses"] profile = "black" [tool.mypy] -mypy_path = "stubs/" exclude = ["venv"] [tool.coverage.run] diff --git a/requirements.txt b/requirements.txt index d49ddac..88b48de 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ # # pip-compile --output-file=requirements.txt pyproject.toml # -prettytable==3.9.0 +prettytable==3.12.0 # via pip-licenses (pyproject.toml) tomli==2.0.1 # via pip-licenses (pyproject.toml) diff --git a/stubs/prettytable/__init__.pyi b/stubs/prettytable/__init__.pyi deleted file mode 100644 index a57f015..0000000 --- a/stubs/prettytable/__init__.pyi +++ /dev/null @@ -1,5 +0,0 @@ -from .prettytable import ALL as ALL -from .prettytable import FRAME as FRAME -from .prettytable import HEADER as HEADER -from .prettytable import NONE as NONE -from .prettytable import PrettyTable as PrettyTable diff --git a/stubs/prettytable/prettytable.pyi b/stubs/prettytable/prettytable.pyi deleted file mode 100644 index 8203696..0000000 --- a/stubs/prettytable/prettytable.pyi +++ /dev/null @@ -1,53 +0,0 @@ -from __future__ import annotations - -from typing import Any, Iterable - -FRAME: int -ALL: int -NONE: int -HEADER: int - -class PrettyTable: - _field_names: list[str] - def __init__( - self, field_names: None | Iterable[str] = None, **kwargs: str - ) -> None: ... - def _format_row( - self, row: Iterable[str] - ) -> dict[str, str | list[str]]: ... - def _format_rows( - self, row: Iterable[str] - ) -> list[dict[str, str | list[str]]]: ... - def _get_options( - self, kwargs: dict[str, str | list[str]] - ) -> dict[str, str | list[str]]: ... - def _get_rows(self, options: dict[str, str | list[str]]) -> list[str]: ... - def add_row(self, row: list[Any]) -> None: ... - @property - def align(self) -> dict[str, str]: ... - @align.setter - def align(self, val: str | dict[str, str]) -> None: ... - @property - def border(self) -> bool: ... - @border.setter - def border(self, val: bool) -> None: ... - @property - def field_names(self) -> list[str]: ... - @field_names.setter - def field_names(self, val: Iterable[str]) -> None: ... - def get_html_string(self, **kwargs: str | list[str]) -> str: ... - def get_string(self, **kwargs: str | list[str]) -> str: ... - @property - def header(self) -> bool: ... - @header.setter - def header(self, val: bool) -> None: ... - @property - def hrules(self) -> int: ... - @hrules.setter - def hrules(self, val: int) -> None: ... - @property - def junction_char(self) -> str: ... - @junction_char.setter - def junction_char(self, val: str) -> None: ... - @property - def rows(self) -> list[tuple[str]]: ... diff --git a/test_piplicenses.py b/test_piplicenses.py index ca5623b..df44ca4 100644 --- a/test_piplicenses.py +++ b/test_piplicenses.py @@ -27,10 +27,6 @@ from piplicenses import ( DEFAULT_OUTPUT_FIELDS, LICENSE_UNKNOWN, - RULE_ALL, - RULE_FRAME, - RULE_HEADER, - RULE_NONE, SYSTEM_PACKAGES, CompatibleArgumentParser, FromArg, @@ -56,6 +52,7 @@ select_license_by_source, value_to_enum_key, ) +from prettytable import HRuleStyle if TYPE_CHECKING: if sys.version_info >= (3, 10): @@ -156,7 +153,7 @@ def test_with_empty_args(self) -> None: self.assertFalse(table.border) self.assertTrue(table.header) self.assertEqual("+", table.junction_char) - self.assertEqual(RULE_FRAME, table.hrules) + self.assertEqual(HRuleStyle.FRAME, table.hrules) output_fields = get_output_fields(args) self.assertEqual( @@ -542,7 +539,7 @@ def test_format_plain(self) -> None: self.assertFalse(table.border) self.assertTrue(table.header) self.assertEqual("+", table.junction_char) - self.assertEqual(RULE_FRAME, table.hrules) + self.assertEqual(HRuleStyle.FRAME, table.hrules) def test_format_plain_vertical(self) -> None: format_plain_args = ["--format=plain-vertical", "--from=classifier"] @@ -561,7 +558,7 @@ def test_format_markdown(self) -> None: self.assertTrue(table.border) self.assertTrue(table.header) self.assertEqual("|", table.junction_char) - self.assertEqual(RULE_HEADER, table.hrules) + self.assertEqual(HRuleStyle.HEADER, table.hrules) @unittest.skipIf( sys.version_info < (3, 6, 0), @@ -579,7 +576,7 @@ def test_format_rst_without_filter(self) -> None: self.assertTrue(table.border) self.assertTrue(table.header) self.assertEqual("+", table.junction_char) - self.assertEqual(RULE_ALL, table.hrules) + self.assertEqual(HRuleStyle.ALL, table.hrules) piplicenses.importlib_metadata.distributions = ( importlib_metadata_distributions_orig ) @@ -596,7 +593,7 @@ def test_format_rst_default_filter(self) -> None: self.assertTrue(table.border) self.assertTrue(table.header) self.assertEqual("+", table.junction_char) - self.assertEqual(RULE_ALL, table.hrules) + self.assertEqual(HRuleStyle.ALL, table.hrules) self.check_rst(str(table)) piplicenses.importlib_metadata.distributions = ( importlib_metadata_distributions_orig @@ -611,7 +608,7 @@ def test_format_confluence(self) -> None: self.assertTrue(table.border) self.assertTrue(table.header) self.assertEqual("|", table.junction_char) - self.assertEqual(RULE_NONE, table.hrules) + self.assertEqual(HRuleStyle.NONE, table.hrules) def test_format_html(self) -> None: format_html_args = ["--format=html", "--with-authors"]