aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/prettytable
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2024-11-14 07:33:20 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2024-11-14 07:42:43 +0300
commitbe3f129280eabea23fd7feb5ab9637418d8fce34 (patch)
tree5c4d1f7357f0094f735a25c90f271257d81f9c1c /contrib/python/prettytable
parent7de479157f34bbce462b90d7626676dc46b55382 (diff)
downloadydb-be3f129280eabea23fd7feb5ab9637418d8fce34.tar.gz
Intermediate changes
commit_hash:3686ebe90c261233292d0ccb4dc131386ef2b33a
Diffstat (limited to 'contrib/python/prettytable')
-rw-r--r--contrib/python/prettytable/py3/.dist-info/METADATA28
-rw-r--r--contrib/python/prettytable/py3/README.md12
-rw-r--r--contrib/python/prettytable/py3/prettytable/__init__.py45
-rw-r--r--contrib/python/prettytable/py3/prettytable/_version.py16
-rw-r--r--contrib/python/prettytable/py3/prettytable/colortable.py42
-rw-r--r--contrib/python/prettytable/py3/prettytable/prettytable.py710
-rw-r--r--contrib/python/prettytable/py3/tests/test_colortable.py39
-rw-r--r--contrib/python/prettytable/py3/tests/test_prettytable.py169
-rw-r--r--contrib/python/prettytable/py3/ya.make3
9 files changed, 695 insertions, 369 deletions
diff --git a/contrib/python/prettytable/py3/.dist-info/METADATA b/contrib/python/prettytable/py3/.dist-info/METADATA
index 6df980cfd8..e44b80cd6e 100644
--- a/contrib/python/prettytable/py3/.dist-info/METADATA
+++ b/contrib/python/prettytable/py3/.dist-info/METADATA
@@ -1,18 +1,18 @@
Metadata-Version: 2.3
Name: prettytable
-Version: 3.11.0
+Version: 3.12.0
Summary: A simple Python library for easily displaying tabular data in a visually appealing ASCII table format
-Project-URL: Changelog, https://github.com/jazzband/prettytable/releases
-Project-URL: Homepage, https://github.com/jazzband/prettytable
-Project-URL: Source, https://github.com/jazzband/prettytable
+Project-URL: Changelog, https://github.com/prettytable/prettytable/releases
+Project-URL: Funding, https://tidelift.com/subscription/pkg/pypi-prettytable?utm_source=pypi-prettytable&utm_medium=pypi
+Project-URL: Homepage, https://github.com/prettytable/prettytable
+Project-URL: Source, https://github.com/prettytable/prettytable
Author-email: Luke Maurits <luke@maurits.id.au>
-Maintainer: Jazzband
-License: BSD (3 clause)
+Maintainer: Hugo van Kemenade
+License-Expression: BSD-3-Clause
License-File: LICENSE
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
@@ -22,7 +22,7 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Text Processing
Classifier: Typing :: Typed
-Requires-Python: >=3.8
+Requires-Python: >=3.9
Requires-Dist: wcwidth
Provides-Extra: tests
Requires-Dist: pytest; extra == 'tests'
@@ -32,13 +32,13 @@ Description-Content-Type: text/markdown
# PrettyTable
-[![Jazzband](https://jazzband.co/static/img/badge.svg)](https://jazzband.co/)
[![PyPI version](https://img.shields.io/pypi/v/prettytable.svg?logo=pypi&logoColor=FFE873)](https://pypi.org/project/prettytable/)
[![Supported Python versions](https://img.shields.io/pypi/pyversions/prettytable.svg?logo=python&logoColor=FFE873)](https://pypi.org/project/prettytable/)
[![PyPI downloads](https://img.shields.io/pypi/dm/prettytable.svg)](https://pypistats.org/packages/prettytable)
-[![GitHub Actions status](https://github.com/jazzband/prettytable/workflows/Test/badge.svg)](https://github.com/jazzband/prettytable/actions)
-[![codecov](https://codecov.io/gh/jazzband/prettytable/branch/main/graph/badge.svg)](https://codecov.io/gh/jazzband/prettytable)
-[![Code style: Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
+[![GitHub Actions status](https://github.com/prettytable/prettytable/workflows/Test/badge.svg)](https://github.com/prettytable/prettytable/actions)
+[![codecov](https://codecov.io/gh/prettytable/prettytable/branch/main/graph/badge.svg)](https://codecov.io/gh/prettytable/prettytable)
+[![Code style: Black](https://img.shields.io/badge/code%20style-Black-000000.svg)](https://github.com/psf/black)
+[![Tidelift](https://tidelift.com/badges/package/pypi/prettytable)](https://tidelift.com/subscription/pkg/pypi-prettytable?utm_source=pypi-prettytable&utm_medium=badge)
PrettyTable lets you print tables in an attractive ASCII form:
@@ -64,11 +64,11 @@ Install via pip:
Install latest development version:
- python -m pip install -U git+https://github.com/jazzband/prettytable
+ python -m pip install -U git+https://github.com/prettytable/prettytable
Or from `requirements.txt`:
- -e git://github.com/jazzband/prettytable.git#egg=prettytable
+ -e git://github.com/prettytable/prettytable.git#egg=prettytable
## Tutorial on how to use the PrettyTable API
diff --git a/contrib/python/prettytable/py3/README.md b/contrib/python/prettytable/py3/README.md
index bb365317da..0c89cbefbc 100644
--- a/contrib/python/prettytable/py3/README.md
+++ b/contrib/python/prettytable/py3/README.md
@@ -1,12 +1,12 @@
# PrettyTable
-[![Jazzband](https://jazzband.co/static/img/badge.svg)](https://jazzband.co/)
[![PyPI version](https://img.shields.io/pypi/v/prettytable.svg?logo=pypi&logoColor=FFE873)](https://pypi.org/project/prettytable/)
[![Supported Python versions](https://img.shields.io/pypi/pyversions/prettytable.svg?logo=python&logoColor=FFE873)](https://pypi.org/project/prettytable/)
[![PyPI downloads](https://img.shields.io/pypi/dm/prettytable.svg)](https://pypistats.org/packages/prettytable)
-[![GitHub Actions status](https://github.com/jazzband/prettytable/workflows/Test/badge.svg)](https://github.com/jazzband/prettytable/actions)
-[![codecov](https://codecov.io/gh/jazzband/prettytable/branch/main/graph/badge.svg)](https://codecov.io/gh/jazzband/prettytable)
-[![Code style: Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
+[![GitHub Actions status](https://github.com/prettytable/prettytable/workflows/Test/badge.svg)](https://github.com/prettytable/prettytable/actions)
+[![codecov](https://codecov.io/gh/prettytable/prettytable/branch/main/graph/badge.svg)](https://codecov.io/gh/prettytable/prettytable)
+[![Code style: Black](https://img.shields.io/badge/code%20style-Black-000000.svg)](https://github.com/psf/black)
+[![Tidelift](https://tidelift.com/badges/package/pypi/prettytable)](https://tidelift.com/subscription/pkg/pypi-prettytable?utm_source=pypi-prettytable&utm_medium=badge)
PrettyTable lets you print tables in an attractive ASCII form:
@@ -32,11 +32,11 @@ Install via pip:
Install latest development version:
- python -m pip install -U git+https://github.com/jazzband/prettytable
+ python -m pip install -U git+https://github.com/prettytable/prettytable
Or from `requirements.txt`:
- -e git://github.com/jazzband/prettytable.git#egg=prettytable
+ -e git://github.com/prettytable/prettytable.git#egg=prettytable
## Tutorial on how to use the PrettyTable API
diff --git a/contrib/python/prettytable/py3/prettytable/__init__.py b/contrib/python/prettytable/py3/prettytable/__init__.py
index 7f9bbe27eb..29ffbe8d97 100644
--- a/contrib/python/prettytable/py3/prettytable/__init__.py
+++ b/contrib/python/prettytable/py3/prettytable/__init__.py
@@ -2,21 +2,27 @@ from __future__ import annotations
from typing import Any
-from .prettytable import (
- ALL,
- DEFAULT,
- DOUBLE_BORDER,
- FRAME,
- HEADER,
- MARKDOWN,
- MSWORD_FRIENDLY,
- NONE,
- ORGMODE,
- PLAIN_COLUMNS,
- RANDOM,
- SINGLE_BORDER,
+from ._version import __version__
+from .prettytable import ( # noqa: F401
+ _DEPRECATED_ALL,
+ _DEPRECATED_DEFAULT,
+ _DEPRECATED_DOUBLE_BORDER,
+ _DEPRECATED_FRAME,
+ _DEPRECATED_HEADER,
+ _DEPRECATED_MARKDOWN,
+ _DEPRECATED_MSWORD_FRIENDLY,
+ _DEPRECATED_NONE,
+ _DEPRECATED_ORGMODE,
+ _DEPRECATED_PLAIN_COLUMNS,
+ _DEPRECATED_RANDOM,
+ _DEPRECATED_SINGLE_BORDER,
+ HRuleStyle,
PrettyTable,
+ RowType,
TableHandler,
+ TableStyle,
+ VRuleStyle,
+ _warn_deprecation,
from_csv,
from_db_cursor,
from_html,
@@ -37,21 +43,20 @@ __all__ = [
"ORGMODE",
"PLAIN_COLUMNS",
"RANDOM",
+ "HRuleStyle",
"PrettyTable",
+ "RowType",
"TableHandler",
+ "TableStyle",
+ "VRuleStyle",
"from_csv",
"from_db_cursor",
"from_html",
"from_html_one",
"from_json",
+ "__version__",
]
def __getattr__(name: str) -> Any:
- if name == "__version__":
- import importlib.metadata
-
- return importlib.metadata.version(__name__)
-
- msg = f"module '{__name__}' has no attribute '{name}'"
- raise AttributeError(msg)
+ return _warn_deprecation(name, module_globals=globals())
diff --git a/contrib/python/prettytable/py3/prettytable/_version.py b/contrib/python/prettytable/py3/prettytable/_version.py
new file mode 100644
index 0000000000..9e1a89958d
--- /dev/null
+++ b/contrib/python/prettytable/py3/prettytable/_version.py
@@ -0,0 +1,16 @@
+# file generated by setuptools_scm
+# don't change, don't track in version control
+TYPE_CHECKING = False
+if TYPE_CHECKING:
+ from typing import Tuple, Union
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
+else:
+ VERSION_TUPLE = object
+
+version: str
+__version__: str
+__version_tuple__: VERSION_TUPLE
+version_tuple: VERSION_TUPLE
+
+__version__ = version = '3.12.0'
+__version_tuple__ = version_tuple = (3, 12, 0)
diff --git a/contrib/python/prettytable/py3/prettytable/colortable.py b/contrib/python/prettytable/py3/prettytable/colortable.py
index 3df50c63d8..52e1fa20a4 100644
--- a/contrib/python/prettytable/py3/prettytable/colortable.py
+++ b/contrib/python/prettytable/py3/prettytable/colortable.py
@@ -45,12 +45,54 @@ class Theme:
class Themes:
DEFAULT = Theme()
+ DYSLEXIA_FRIENDLY = Theme(
+ default_color="38;5;223",
+ vertical_color="38;5;22",
+ horizontal_color="38;5;22",
+ junction_color="38;5;58",
+ )
+ EARTH = Theme(
+ default_color="33",
+ vertical_color="38;5;94",
+ horizontal_color="38;5;22",
+ junction_color="38;5;130",
+ )
+ GLARE_REDUCTION = Theme(
+ default_color="38;5;252",
+ vertical_color="38;5;240",
+ horizontal_color="38;5;240",
+ junction_color="38;5;246",
+ )
+ HIGH_CONTRAST = Theme(
+ default_color="97",
+ vertical_color="91",
+ horizontal_color="94",
+ junction_color="93",
+ )
+ LAVENDER = Theme(
+ default_color="38;5;183",
+ vertical_color="35",
+ horizontal_color="38;5;147",
+ junction_color="38;5;219",
+ )
OCEAN = Theme(
default_color="96",
vertical_color="34",
horizontal_color="34",
junction_color="36",
)
+ OCEAN_DEEP = Theme(
+ default_color="96",
+ vertical_color="34",
+ horizontal_color="36",
+ junction_color="94",
+ )
+ PASTEL = Theme(
+ default_color="38;5;223",
+ vertical_color="38;5;152",
+ horizontal_color="38;5;187",
+ junction_color="38;5;157",
+ )
class ColorTable(PrettyTable):
diff --git a/contrib/python/prettytable/py3/prettytable/prettytable.py b/contrib/python/prettytable/py3/prettytable/prettytable.py
index 7f5dacb58a..818a5203bb 100644
--- a/contrib/python/prettytable/py3/prettytable/prettytable.py
+++ b/contrib/python/prettytable/py3/prettytable/prettytable.py
@@ -35,30 +35,120 @@ from __future__ import annotations
import io
import re
+import warnings
+from collections.abc import Callable, Iterable, Mapping, Sequence
+from enum import IntEnum
from html.parser import HTMLParser
-from typing import Any
-
-# hrule styles
-FRAME = 0
-ALL = 1
-NONE = 2
-HEADER = 3
-
-# Table styles
-DEFAULT = 10
-MSWORD_FRIENDLY = 11
-PLAIN_COLUMNS = 12
-MARKDOWN = 13
-ORGMODE = 14
-DOUBLE_BORDER = 15
-SINGLE_BORDER = 16
-RANDOM = 20
-BASE_ALIGN_VALUE = "base_align_value"
+from typing import TYPE_CHECKING, Any, Final, Literal, TypedDict, cast
+
+if TYPE_CHECKING:
+ from sqlite3 import Cursor
+
+ from _typeshed import SupportsRichComparison
+ from typing_extensions import Self, TypeAlias
+
+
+class HRuleStyle(IntEnum):
+ FRAME = 0
+ ALL = 1
+ NONE = 2
+ HEADER = 3
+
+
+class VRuleStyle(IntEnum):
+ FRAME = 0
+ ALL = 1
+ NONE = 2
+
+
+class TableStyle(IntEnum):
+ DEFAULT = 10
+ MSWORD_FRIENDLY = 11
+ PLAIN_COLUMNS = 12
+ MARKDOWN = 13
+ ORGMODE = 14
+ DOUBLE_BORDER = 15
+ SINGLE_BORDER = 16
+ RANDOM = 20
+
+
+# keep for backwards compatibility
+_DEPRECATED_FRAME: Final = 0
+_DEPRECATED_ALL: Final = 1
+_DEPRECATED_NONE: Final = 2
+_DEPRECATED_HEADER: Final = 3
+_DEPRECATED_DEFAULT: Final = TableStyle.DEFAULT
+_DEPRECATED_MSWORD_FRIENDLY: Final = TableStyle.MSWORD_FRIENDLY
+_DEPRECATED_PLAIN_COLUMNS: Final = TableStyle.PLAIN_COLUMNS
+_DEPRECATED_MARKDOWN: Final = TableStyle.MARKDOWN
+_DEPRECATED_ORGMODE: Final = TableStyle.ORGMODE
+_DEPRECATED_DOUBLE_BORDER: Final = TableStyle.DOUBLE_BORDER
+_DEPRECATED_SINGLE_BORDER: Final = TableStyle.SINGLE_BORDER
+_DEPRECATED_RANDOM: Final = TableStyle.RANDOM
+# --------------------------------
+
+BASE_ALIGN_VALUE: Final = "base_align_value"
+
+RowType: TypeAlias = list[Any]
+AlignType: TypeAlias = Literal["l", "c", "r"]
+VAlignType: TypeAlias = Literal["t", "m", "b"]
+HeaderStyleType: TypeAlias = Literal["cap", "title", "upper", "lower", None]
+
+
+class OptionsType(TypedDict):
+ title: str | None
+ start: int
+ end: int | None
+ fields: Sequence[str | None] | None
+ header: bool
+ border: bool
+ preserve_internal_border: bool
+ sortby: str | None
+ reversesort: bool
+ sort_key: Callable[[RowType], SupportsRichComparison]
+ attributes: dict[str, str]
+ format: bool
+ hrules: HRuleStyle
+ vrules: VRuleStyle
+ int_format: str | dict[str, str] | None
+ float_format: str | dict[str, str] | None
+ custom_format: (
+ Callable[[str, Any], str] | dict[str, Callable[[str, Any], str]] | None
+ )
+ min_table_width: int | None
+ max_table_width: int | None
+ padding_width: int
+ left_padding_width: int | None
+ right_padding_width: int | None
+ vertical_char: str
+ horizontal_char: str
+ horizontal_align_char: str
+ junction_char: str
+ header_style: HeaderStyleType
+ xhtml: bool
+ print_empty: bool
+ oldsortslice: bool
+ top_junction_char: str
+ bottom_junction_char: str
+ right_junction_char: str
+ left_junction_char: str
+ top_right_junction_char: str
+ top_left_junction_char: str
+ bottom_right_junction_char: str
+ bottom_left_junction_char: str
+ align: dict[str, AlignType]
+ valign: dict[str, VAlignType]
+ min_width: int | dict[str, int] | None
+ max_width: int | dict[str, int] | None
+ none_format: str | dict[str, str | None] | None
+ escape_header: bool
+ escape_data: bool
+
_re = re.compile(r"\033\[[0-9;]*m|\033\(B")
-def _get_size(text):
+def _get_size(text: str) -> tuple[int, int]:
lines = text.split("\n")
height = len(lines)
width = max(_str_block_width(line) for line in lines)
@@ -66,7 +156,56 @@ def _get_size(text):
class PrettyTable:
- def __init__(self, field_names=None, **kwargs) -> None:
+ _xhtml: bool
+ _align: dict[str, AlignType]
+ _valign: dict[str, VAlignType]
+ _min_width: dict[str, int]
+ _max_width: dict[str, int]
+ _min_table_width: int | None
+ _max_table_width: int | None
+ _fields: Sequence[str | None] | None
+ _title: str | None
+ _start: int
+ _end: int | None
+ _sortby: str | None
+ _reversesort: bool
+ _sort_key: Callable[[RowType], SupportsRichComparison]
+ _header: bool
+ _header_style: HeaderStyleType
+ _border: bool
+ _preserve_internal_border: bool
+ _hrules: HRuleStyle
+ _vrules: VRuleStyle
+ _int_format: dict[str, str]
+ _float_format: dict[str, str]
+ _custom_format: dict[str, Callable[[str, Any], str]]
+ _padding_width: int
+ _left_padding_width: int | None
+ _right_padding_width: int | None
+ _vertical_char: str
+ _horizontal_char: str
+ _horizontal_align_char: str | None
+ _junction_char: str
+ _top_junction_char: str | None
+ _bottom_junction_char: str | None
+ _right_junction_char: str | None
+ _left_junction_char: str | None
+ _top_right_junction_char: str | None
+ _top_left_junction_char: str | None
+ _bottom_right_junction_char: str | None
+ _bottom_left_junction_char: str | None
+ _format: bool
+ _print_empty: bool
+ _oldsortslice: bool
+ _attributes: dict[str, str]
+ _escape_header: bool
+ _escape_data: bool
+ _style: TableStyle | None
+ orgmode: bool
+ _widths: list[int]
+ _hrule: str
+
+ def __init__(self, field_names: Sequence[str] | None = None, **kwargs) -> None:
"""Return a new PrettyTable instance
Arguments:
@@ -84,9 +223,9 @@ class PrettyTable:
preserve_internal_border - print a border inside the table even if
border is disabled (True or False)
hrules - controls printing of horizontal rules after rows.
- Allowed values: FRAME, HEADER, ALL, NONE
+ Allowed values: HRuleStyle
vrules - controls printing of vertical rules between columns.
- Allowed values: FRAME, ALL, NONE
+ Allowed values: VRuleStyle
int_format - controls formatting of integer data
float_format - controls formatting of floating point data
custom_format - controls formatting of any column using callable
@@ -126,7 +265,7 @@ class PrettyTable:
# Data
self._field_names: list[str] = []
- self._rows: list[list] = []
+ self._rows: list[RowType] = []
self._dividers: list[bool] = []
self.align = {}
self.valign = {}
@@ -171,7 +310,6 @@ class PrettyTable:
"horizontal_align_char",
"junction_char",
"header_style",
- "valign",
"xhtml",
"print_empty",
"oldsortslice",
@@ -201,7 +339,7 @@ class PrettyTable:
self._start = kwargs["start"] or 0
self._end = kwargs["end"] or None
self._fields = kwargs["fields"] or None
- self._none_format: dict[None, None] = {}
+ self._none_format: dict[str, str | None] = {}
if kwargs["header"] in (True, False):
self._header = kwargs["header"]
@@ -216,8 +354,8 @@ class PrettyTable:
self._preserve_internal_border = kwargs["preserve_internal_border"]
else:
self._preserve_internal_border = False
- self._hrules = kwargs["hrules"] or FRAME
- self._vrules = kwargs["vrules"] or ALL
+ self._hrules = kwargs["hrules"] or HRuleStyle.FRAME
+ self._vrules = kwargs["vrules"] or VRuleStyle.ALL
self._sortby = kwargs["sortby"] or None
if kwargs["reversesort"] in (True, False):
@@ -278,7 +416,7 @@ class PrettyTable:
self._xhtml = kwargs["xhtml"] or False
self._attributes = kwargs["attributes"] or {}
- def _justify(self, text, width, align):
+ def _justify(self, text: str, width: int, align: AlignType) -> str:
excess = width - _str_block_width(text)
if align == "l":
return text + excess * " "
@@ -312,7 +450,7 @@ class PrettyTable:
else:
raise AttributeError(name)
- def __getitem__(self, index):
+ def __getitem__(self, index: int | slice) -> PrettyTable:
new = PrettyTable()
new.field_names = self.field_names
for attr in self._options:
@@ -334,7 +472,7 @@ class PrettyTable:
def __repr__(self) -> str:
return self.get_string()
- def _repr_html_(self):
+ def _repr_html_(self) -> str:
"""
Returns get_html_string value by default
as the repr call in Jupyter notebook environment
@@ -369,7 +507,6 @@ class PrettyTable:
"padding_width",
"left_padding_width",
"right_padding_width",
- "format",
):
self._validate_nonnegative_int(option, val)
elif option == "sortby":
@@ -388,6 +525,7 @@ class PrettyTable:
"preserve_internal_border",
"reversesort",
"xhtml",
+ "format",
"print_empty",
"oldsortslice",
"escape_header",
@@ -472,9 +610,9 @@ class PrettyTable:
def _validate_valign(self, val):
try:
- assert val in ["t", "m", "b", None]
+ assert val in ["t", "m", "b"]
except AssertionError:
- msg = f"Alignment {val} is invalid, use t, m, b or None"
+ msg = f"Alignment {val} is invalid, use t, m, b"
raise ValueError(msg)
def _validate_nonnegative_int(self, name, val):
@@ -528,16 +666,16 @@ class PrettyTable:
def _validate_hrules(self, name, val):
try:
- assert val in (ALL, FRAME, HEADER, NONE)
+ assert val in list(HRuleStyle)
except AssertionError:
- msg = f"Invalid value for {name}. Must be ALL, FRAME, HEADER or NONE."
+ msg = f"Invalid value for {name}. Must be HRuleStyle."
raise ValueError(msg)
def _validate_vrules(self, name, val):
try:
- assert val in (ALL, FRAME, NONE)
+ assert val in list(VRuleStyle)
except AssertionError:
- msg = f"Invalid value for {name}. Must be ALL, FRAME, or NONE."
+ msg = f"Invalid value for {name}. Must be VRuleStyle."
raise ValueError(msg)
def _validate_field_name(self, name, val):
@@ -573,7 +711,7 @@ class PrettyTable:
# ATTRIBUTE MANAGEMENT #
##############################
@property
- def rows(self) -> list[Any]:
+ def rows(self) -> list[RowType]:
return self._rows[:]
@property
@@ -586,7 +724,7 @@ class PrettyTable:
return self._xhtml
@xhtml.setter
- def xhtml(self, val) -> None:
+ def xhtml(self, val: bool) -> None:
self._validate_option("xhtml", val)
self._xhtml = val
@@ -722,35 +860,35 @@ class PrettyTable:
self._min_width[field] = val
@property
- def min_table_width(self):
+ def min_table_width(self) -> int | None:
return self._min_table_width
@min_table_width.setter
- def min_table_width(self, val) -> None:
+ def min_table_width(self, val: int) -> None:
self._validate_option("min_table_width", val)
self._min_table_width = val
@property
- def max_table_width(self):
+ def max_table_width(self) -> int | None:
return self._max_table_width
@max_table_width.setter
- def max_table_width(self, val) -> None:
+ def max_table_width(self, val: int) -> None:
self._validate_option("max_table_width", val)
self._max_table_width = val
@property
- def fields(self):
+ def fields(self) -> Sequence[str | None] | None:
"""List or tuple of field names to include in displays"""
return self._fields
@fields.setter
- def fields(self, val) -> None:
+ def fields(self, val: Sequence[str | None]) -> None:
self._validate_option("fields", val)
self._fields = val
@property
- def title(self):
+ def title(self) -> str | None:
"""Optional table title
Arguments:
@@ -759,11 +897,11 @@ class PrettyTable:
return self._title
@title.setter
- def title(self, val) -> None:
+ def title(self, val: str) -> None:
self._title = str(val)
@property
- def start(self):
+ def start(self) -> int:
"""Start index of the range of rows to print
Arguments:
@@ -772,12 +910,12 @@ class PrettyTable:
return self._start
@start.setter
- def start(self, val) -> None:
+ def start(self, val: int) -> None:
self._validate_option("start", val)
self._start = val
@property
- def end(self):
+ def end(self) -> int | None:
"""End index of the range of rows to print
Arguments:
@@ -786,12 +924,12 @@ class PrettyTable:
return self._end
@end.setter
- def end(self, val) -> None:
+ def end(self, val: int) -> None:
self._validate_option("end", val)
self._end = val
@property
- def sortby(self):
+ def sortby(self) -> str | None:
"""Name of field by which to sort rows
Arguments:
@@ -800,12 +938,12 @@ class PrettyTable:
return self._sortby
@sortby.setter
- def sortby(self, val) -> None:
+ def sortby(self, val: str | None) -> None:
self._validate_option("sortby", val)
self._sortby = val
@property
- def reversesort(self):
+ def reversesort(self) -> bool:
"""Controls direction of sorting (ascending vs descending)
Arguments:
@@ -815,12 +953,12 @@ class PrettyTable:
return self._reversesort
@reversesort.setter
- def reversesort(self, val) -> None:
+ def reversesort(self, val: bool) -> None:
self._validate_option("reversesort", val)
self._reversesort = val
@property
- def sort_key(self):
+ def sort_key(self) -> Callable[[RowType], SupportsRichComparison]:
"""Sorting key function, applied to data points before sorting
Arguments:
@@ -830,12 +968,12 @@ class PrettyTable:
return self._sort_key
@sort_key.setter
- def sort_key(self, val) -> None:
+ def sort_key(self, val: Callable[[RowType], SupportsRichComparison]) -> None:
self._validate_option("sort_key", val)
self._sort_key = val
@property
- def header(self):
+ def header(self) -> bool:
"""Controls printing of table header with field names
Arguments:
@@ -844,12 +982,12 @@ class PrettyTable:
return self._header
@header.setter
- def header(self, val) -> None:
+ def header(self, val: bool) -> None:
self._validate_option("header", val)
self._header = val
@property
- def header_style(self):
+ def header_style(self) -> HeaderStyleType:
"""Controls stylisation applied to field names in header
Arguments:
@@ -859,12 +997,12 @@ class PrettyTable:
return self._header_style
@header_style.setter
- def header_style(self, val) -> None:
+ def header_style(self, val: HeaderStyleType) -> None:
self._validate_header_style(val)
self._header_style = val
@property
- def border(self):
+ def border(self) -> bool:
"""Controls printing of border around table
Arguments:
@@ -873,12 +1011,12 @@ class PrettyTable:
return self._border
@border.setter
- def border(self, val) -> None:
+ def border(self, val: bool) -> None:
self._validate_option("border", val)
self._border = val
@property
- def preserve_internal_border(self):
+ def preserve_internal_border(self) -> bool:
"""Controls printing of border inside table
Arguments:
@@ -888,35 +1026,35 @@ class PrettyTable:
return self._preserve_internal_border
@preserve_internal_border.setter
- def preserve_internal_border(self, val) -> None:
+ def preserve_internal_border(self, val: bool) -> None:
self._validate_option("preserve_internal_border", val)
self._preserve_internal_border = val
@property
- def hrules(self):
+ def hrules(self) -> HRuleStyle:
"""Controls printing of horizontal rules after rows
Arguments:
- hrules - horizontal rules style. Allowed values: FRAME, ALL, HEADER, NONE"""
+ hrules - horizontal rules style. Allowed values: HRuleStyle"""
return self._hrules
@hrules.setter
- def hrules(self, val) -> None:
+ def hrules(self, val: HRuleStyle) -> None:
self._validate_option("hrules", val)
self._hrules = val
@property
- def vrules(self):
+ def vrules(self) -> VRuleStyle:
"""Controls printing of vertical rules between columns
Arguments:
- vrules - vertical rules style. Allowed values: FRAME, ALL, NONE"""
+ vrules - vertical rules style. Allowed values: VRuleStyle"""
return self._vrules
@vrules.setter
- def vrules(self, val) -> None:
+ def vrules(self, val: VRuleStyle) -> None:
self._validate_option("vrules", val)
self._vrules = val
@@ -979,7 +1117,7 @@ class PrettyTable:
raise TypeError(msg)
@property
- def padding_width(self):
+ def padding_width(self) -> int:
"""The number of empty spaces between a column's edge and its content
Arguments:
@@ -988,12 +1126,12 @@ class PrettyTable:
return self._padding_width
@padding_width.setter
- def padding_width(self, val) -> None:
+ def padding_width(self, val: int) -> None:
self._validate_option("padding_width", val)
self._padding_width = val
@property
- def left_padding_width(self):
+ def left_padding_width(self) -> int | None:
"""The number of empty spaces between a column's left edge and its content
Arguments:
@@ -1002,12 +1140,12 @@ class PrettyTable:
return self._left_padding_width
@left_padding_width.setter
- def left_padding_width(self, val) -> None:
+ def left_padding_width(self, val: int) -> None:
self._validate_option("left_padding_width", val)
self._left_padding_width = val
@property
- def right_padding_width(self):
+ def right_padding_width(self) -> int | None:
"""The number of empty spaces between a column's right edge and its content
Arguments:
@@ -1016,12 +1154,12 @@ class PrettyTable:
return self._right_padding_width
@right_padding_width.setter
- def right_padding_width(self, val) -> None:
+ def right_padding_width(self, val: int) -> None:
self._validate_option("right_padding_width", val)
self._right_padding_width = val
@property
- def vertical_char(self):
+ def vertical_char(self) -> str:
"""The character used when printing table borders to draw vertical lines
Arguments:
@@ -1030,13 +1168,13 @@ class PrettyTable:
return self._vertical_char
@vertical_char.setter
- def vertical_char(self, val) -> None:
+ def vertical_char(self, val: str) -> None:
val = str(val)
self._validate_option("vertical_char", val)
self._vertical_char = val
@property
- def horizontal_char(self):
+ def horizontal_char(self) -> str:
"""The character used when printing table borders to draw horizontal lines
Arguments:
@@ -1045,13 +1183,13 @@ class PrettyTable:
return self._horizontal_char
@horizontal_char.setter
- def horizontal_char(self, val) -> None:
+ def horizontal_char(self, val: str) -> None:
val = str(val)
self._validate_option("horizontal_char", val)
self._horizontal_char = val
@property
- def horizontal_align_char(self):
+ def horizontal_align_char(self) -> str:
"""The character used to indicate column alignment in horizontal lines
Arguments:
@@ -1060,13 +1198,13 @@ class PrettyTable:
return self._bottom_left_junction_char or self.junction_char
@horizontal_align_char.setter
- def horizontal_align_char(self, val) -> None:
+ def horizontal_align_char(self, val: str) -> None:
val = str(val)
self._validate_option("horizontal_align_char", val)
self._horizontal_align_char = val
@property
- def junction_char(self):
+ def junction_char(self) -> str:
"""The character used when printing table borders to draw line junctions
Arguments:
@@ -1075,13 +1213,13 @@ class PrettyTable:
return self._junction_char
@junction_char.setter
- def junction_char(self, val) -> None:
+ def junction_char(self, val: str) -> None:
val = str(val)
self._validate_option("junction_char", val)
self._junction_char = val
@property
- def top_junction_char(self):
+ def top_junction_char(self) -> str:
"""The character used when printing table borders to draw top line junctions
Arguments:
@@ -1090,13 +1228,13 @@ class PrettyTable:
return self._top_junction_char or self.junction_char
@top_junction_char.setter
- def top_junction_char(self, val) -> None:
+ def top_junction_char(self, val: str) -> None:
val = str(val)
self._validate_option("top_junction_char", val)
self._top_junction_char = val
@property
- def bottom_junction_char(self):
+ def bottom_junction_char(self) -> str:
"""The character used when printing table borders to draw bottom line junctions
Arguments:
@@ -1106,13 +1244,13 @@ class PrettyTable:
return self._bottom_junction_char or self.junction_char
@bottom_junction_char.setter
- def bottom_junction_char(self, val) -> None:
+ def bottom_junction_char(self, val: str) -> None:
val = str(val)
self._validate_option("bottom_junction_char", val)
self._bottom_junction_char = val
@property
- def right_junction_char(self):
+ def right_junction_char(self) -> str:
"""The character used when printing table borders to draw right line junctions
Arguments:
@@ -1122,13 +1260,13 @@ class PrettyTable:
return self._right_junction_char or self.junction_char
@right_junction_char.setter
- def right_junction_char(self, val) -> None:
+ def right_junction_char(self, val: str) -> None:
val = str(val)
self._validate_option("right_junction_char", val)
self._right_junction_char = val
@property
- def left_junction_char(self):
+ def left_junction_char(self) -> str:
"""The character used when printing table borders to draw left line junctions
Arguments:
@@ -1137,13 +1275,13 @@ class PrettyTable:
return self._left_junction_char or self.junction_char
@left_junction_char.setter
- def left_junction_char(self, val) -> None:
+ def left_junction_char(self, val: str) -> None:
val = str(val)
self._validate_option("left_junction_char", val)
self._left_junction_char = val
@property
- def top_right_junction_char(self):
+ def top_right_junction_char(self) -> str:
"""
The character used when printing table borders to draw top-right line junctions
@@ -1154,13 +1292,13 @@ class PrettyTable:
return self._top_right_junction_char or self.junction_char
@top_right_junction_char.setter
- def top_right_junction_char(self, val) -> None:
+ def top_right_junction_char(self, val: str) -> None:
val = str(val)
self._validate_option("top_right_junction_char", val)
self._top_right_junction_char = val
@property
- def top_left_junction_char(self):
+ def top_left_junction_char(self) -> str:
"""
The character used when printing table borders to draw top-left line junctions
@@ -1171,13 +1309,13 @@ class PrettyTable:
return self._top_left_junction_char or self.junction_char
@top_left_junction_char.setter
- def top_left_junction_char(self, val) -> None:
+ def top_left_junction_char(self, val: str) -> None:
val = str(val)
self._validate_option("top_left_junction_char", val)
self._top_left_junction_char = val
@property
- def bottom_right_junction_char(self):
+ def bottom_right_junction_char(self) -> str:
"""The character used when printing table borders
to draw bottom-right line junctions
@@ -1188,13 +1326,13 @@ class PrettyTable:
return self._bottom_right_junction_char or self.junction_char
@bottom_right_junction_char.setter
- def bottom_right_junction_char(self, val) -> None:
+ def bottom_right_junction_char(self, val: str) -> None:
val = str(val)
self._validate_option("bottom_right_junction_char", val)
self._bottom_right_junction_char = val
@property
- def bottom_left_junction_char(self):
+ def bottom_left_junction_char(self) -> str:
"""The character used when printing table borders
to draw bottom-left line junctions
@@ -1205,13 +1343,13 @@ class PrettyTable:
return self._bottom_left_junction_char or self.junction_char
@bottom_left_junction_char.setter
- def bottom_left_junction_char(self, val) -> None:
+ def bottom_left_junction_char(self, val: str) -> None:
val = str(val)
self._validate_option("bottom_left_junction_char", val)
self._bottom_left_junction_char = val
@property
- def format(self):
+ def format(self) -> bool:
"""Controls whether or not HTML tables are formatted to match styling options
Arguments:
@@ -1220,12 +1358,12 @@ class PrettyTable:
return self._format
@format.setter
- def format(self, val) -> None:
+ def format(self, val: bool) -> None:
self._validate_option("format", val)
self._format = val
@property
- def print_empty(self):
+ def print_empty(self) -> bool:
"""Controls whether or not empty tables produce a header and frame or just an
empty string
@@ -1235,12 +1373,12 @@ class PrettyTable:
return self._print_empty
@print_empty.setter
- def print_empty(self, val) -> None:
+ def print_empty(self, val: bool) -> None:
self._validate_option("print_empty", val)
self._print_empty = val
@property
- def attributes(self):
+ def attributes(self) -> dict[str, str]:
"""A dictionary of HTML attribute name/value pairs to be included in the
<table> tag when printing HTML
@@ -1250,37 +1388,37 @@ class PrettyTable:
return self._attributes
@attributes.setter
- def attributes(self, val) -> None:
+ def attributes(self, val: dict[str, str]) -> None:
self._validate_option("attributes", val)
self._attributes = val
@property
- def oldsortslice(self):
+ def oldsortslice(self) -> bool:
"""oldsortslice - Slice rows before sorting in the "old style" """
return self._oldsortslice
@oldsortslice.setter
- def oldsortslice(self, val) -> None:
+ def oldsortslice(self, val: bool) -> None:
self._validate_option("oldsortslice", val)
self._oldsortslice = val
@property
- def escape_header(self):
+ def escape_header(self) -> bool:
"""Escapes the text within a header (True or False)"""
return self._escape_header
@escape_header.setter
- def escape_header(self, val):
+ def escape_header(self, val: bool) -> None:
self._validate_option("escape_header", val)
self._escape_header = val
@property
- def escape_data(self):
+ def escape_data(self) -> bool:
"""Escapes the text within a data field (True or False)"""
return self._escape_data
@escape_data.setter
- def escape_data(self, val):
+ def escape_data(self, val: bool) -> None:
self._validate_option("escape_data", val)
self._escape_data = val
@@ -1288,37 +1426,37 @@ class PrettyTable:
# OPTION MIXER #
##############################
- def _get_options(self, kwargs):
- options = {}
+ def _get_options(self, kwargs: Mapping[str, Any]) -> OptionsType:
+ options: dict[str, Any] = {}
for option in self._options:
if option in kwargs:
self._validate_option(option, kwargs[option])
options[option] = kwargs[option]
else:
options[option] = getattr(self, option)
- return options
+ return cast(OptionsType, options)
##############################
# PRESET STYLE LOGIC #
##############################
- def set_style(self, style) -> None:
+ def set_style(self, style: TableStyle) -> None:
self._style = style
- if style == DEFAULT:
+ if style == TableStyle.DEFAULT:
self._set_default_style()
- elif style == MSWORD_FRIENDLY:
+ elif style == TableStyle.MSWORD_FRIENDLY:
self._set_msword_style()
- elif style == PLAIN_COLUMNS:
+ elif style == TableStyle.PLAIN_COLUMNS:
self._set_columns_style()
- elif style == MARKDOWN:
+ elif style == TableStyle.MARKDOWN:
self._set_markdown_style()
- elif style == ORGMODE:
+ elif style == TableStyle.ORGMODE:
self._set_orgmode_style()
- elif style == DOUBLE_BORDER:
+ elif style == TableStyle.DOUBLE_BORDER:
self._set_double_border_style()
- elif style == SINGLE_BORDER:
+ elif style == TableStyle.SINGLE_BORDER:
self._set_single_border_style()
- elif style == RANDOM:
+ elif style == TableStyle.RANDOM:
self._set_random_style()
else:
msg = "Invalid pre-set style"
@@ -1331,7 +1469,7 @@ class PrettyTable:
def _set_markdown_style(self) -> None:
self.header = True
self.border = True
- self._hrules = None
+ self._hrules = HRuleStyle.HEADER
self.padding_width = 1
self.left_padding_width = 1
self.right_padding_width = 1
@@ -1342,8 +1480,8 @@ class PrettyTable:
def _set_default_style(self) -> None:
self.header = True
self.border = True
- self._hrules = FRAME
- self._vrules = ALL
+ self._hrules = HRuleStyle.FRAME
+ self._vrules = VRuleStyle.ALL
self.padding_width = 1
self.left_padding_width = 1
self.right_padding_width = 1
@@ -1363,7 +1501,7 @@ class PrettyTable:
def _set_msword_style(self) -> None:
self.header = True
self.border = True
- self._hrules = NONE
+ self._hrules = HRuleStyle.NONE
self.padding_width = 1
self.left_padding_width = 1
self.right_padding_width = 1
@@ -1408,8 +1546,8 @@ class PrettyTable:
self.header = random.choice((True, False))
self.border = random.choice((True, False))
- self._hrules = random.choice((ALL, FRAME, HEADER, NONE))
- self._vrules = random.choice((ALL, FRAME, NONE))
+ self._hrules = random.choice(list(HRuleStyle))
+ self._vrules = random.choice(list(VRuleStyle))
self.left_padding_width = random.randint(0, 5)
self.right_padding_width = random.randint(0, 5)
self.vertical_char = random.choice(r"~!@#$%^&*()_+|-=\{}[];':\",./;<>?")
@@ -1421,7 +1559,7 @@ class PrettyTable:
# DATA INPUT METHODS #
##############################
- def add_rows(self, rows) -> None:
+ def add_rows(self, rows: Iterable[RowType]) -> None:
"""Add rows to the table
Arguments:
@@ -1431,7 +1569,7 @@ class PrettyTable:
for row in rows:
self.add_row(row)
- def add_row(self, row, *, divider: bool = False) -> None:
+ def add_row(self, row: RowType, *, divider: bool = False) -> None:
"""Add a row to the table
Arguments:
@@ -1450,7 +1588,7 @@ class PrettyTable:
self._rows.append(list(row))
self._dividers.append(divider)
- def del_row(self, row_index) -> None:
+ def del_row(self, row_index: int) -> None:
"""Delete a row from the table
Arguments:
@@ -1467,7 +1605,11 @@ class PrettyTable:
del self._dividers[row_index]
def add_column(
- self, fieldname, column, align: str = "c", valign: str = "t"
+ self,
+ fieldname: str,
+ column: Sequence[Any],
+ align: AlignType = "c",
+ valign: VAlignType = "t",
) -> None:
"""Add a column to the table.
@@ -1509,7 +1651,7 @@ class PrettyTable:
for i, row in enumerate(self._rows):
row.insert(0, i + 1)
- def del_column(self, fieldname) -> None:
+ def del_column(self, fieldname: str) -> None:
"""Delete a column from the table
Arguments:
@@ -1549,7 +1691,7 @@ class PrettyTable:
# MISC PUBLIC METHODS #
##############################
- def copy(self):
+ def copy(self) -> Self:
import copy
return copy.deepcopy(self)
@@ -1582,7 +1724,7 @@ class PrettyTable:
# MISC PRIVATE METHODS #
##############################
- def _format_value(self, field, value):
+ def _format_value(self, field: str, value: Any) -> str:
if isinstance(value, int) and field in self._int_format:
return (f"%{self._int_format[field]}d") % value
elif isinstance(value, float) and field in self._float_format:
@@ -1591,10 +1733,10 @@ class PrettyTable:
formatter = self._custom_format.get(field, (lambda f, v: str(v)))
return formatter(field, value)
- def _compute_table_width(self, options):
- if options["vrules"] == FRAME:
+ def _compute_table_width(self, options) -> int:
+ if options["vrules"] == VRuleStyle.FRAME:
table_width = 2
- if options["vrules"] == ALL:
+ if options["vrules"] == VRuleStyle.ALL:
table_width = 1
else:
table_width = 0
@@ -1606,7 +1748,7 @@ class PrettyTable:
table_width += self._widths[index] + per_col_padding + 1
return table_width
- def _compute_widths(self, rows, options) -> None:
+ def _compute_widths(self, rows: list[list[str]], options: OptionsType) -> None:
if options["header"]:
widths = [_get_size(field)[0] for field in self._field_names]
else:
@@ -1615,9 +1757,11 @@ class PrettyTable:
for row in rows:
for index, value in enumerate(row):
fieldname = self.field_names[index]
- if self.none_format.get(fieldname) is not None:
- if value == "None" or value is None:
- value = self.none_format.get(fieldname)
+ if (
+ value == "None"
+ and (none_val := self.none_format.get(fieldname)) is not None
+ ):
+ value = none_val
if fieldname in self.max_width:
widths[index] = max(
widths[index],
@@ -1628,7 +1772,7 @@ class PrettyTable:
if fieldname in self.min_width:
widths[index] = max(widths[index], self.min_width[fieldname])
- if self._style == MARKDOWN:
+ if self._style == TableStyle.MARKDOWN:
# Markdown needs at least one hyphen in the divider
if self._align[fieldname] in ("l", "r"):
min_width = 1
@@ -1654,7 +1798,7 @@ class PrettyTable:
if self._min_table_width or options["title"]:
if options["title"]:
title_width = len(options["title"]) + per_col_padding
- if options["vrules"] in (FRAME, ALL):
+ if options["vrules"] in (VRuleStyle.FRAME, VRuleStyle.ALL):
title_width += 2
else:
title_width = 0
@@ -1680,7 +1824,7 @@ class PrettyTable:
widths[-1] += min_width - sum(widths)
self._widths = widths
- def _get_padding_widths(self, options):
+ def _get_padding_widths(self, options: OptionsType) -> tuple[int, int]:
if options["left_padding_width"] is not None:
lpad = options["left_padding_width"]
else:
@@ -1691,7 +1835,7 @@ class PrettyTable:
rpad = options["padding_width"]
return lpad, rpad
- def _get_rows(self, options):
+ def _get_rows(self, options: OptionsType) -> list[RowType]:
"""Return only those data rows that should be printed, based on slicing and
sorting.
@@ -1721,7 +1865,7 @@ class PrettyTable:
return rows
- def _get_dividers(self, options):
+ def _get_dividers(self, options: OptionsType) -> list[bool]:
"""Return only those dividers that should be printed, based on slicing.
Arguments:
@@ -1739,13 +1883,13 @@ class PrettyTable:
return dividers
- def _format_row(self, row):
+ def _format_row(self, row: RowType) -> list[str]:
return [
self._format_value(field, value)
for (field, value) in zip(self._field_names, row)
]
- def _format_rows(self, rows):
+ def _format_rows(self, rows: list[RowType]) -> list[list[str]]:
return [self._format_row(row) for row in rows]
##############################
@@ -1766,9 +1910,9 @@ class PrettyTable:
preserve_internal_border - print a border inside the table even if
border is disabled (True or False)
hrules - controls printing of horizontal rules after rows.
- Allowed values: ALL, FRAME, HEADER, NONE
+ Allowed values: HRuleStyle
vrules - controls printing of vertical rules between columns.
- Allowed values: FRAME, ALL, NONE
+ Allowed values: VRuleStyle
int_format - controls formatting of integer data
float_format - controls formatting of floating point data
custom_format - controls formatting of any column using callable
@@ -1802,7 +1946,7 @@ class PrettyTable:
options = self._get_options(kwargs)
- lines = []
+ lines: list[str] = []
# Don't think too hard about an empty table
# Is this the desired behaviour? Maybe we should still print the header?
@@ -1828,11 +1972,18 @@ class PrettyTable:
# Add header or top of border
if options["header"]:
lines.append(self._stringify_header(options))
- elif options["border"] and options["hrules"] in (ALL, FRAME):
+ elif options["border"] and options["hrules"] in (
+ HRuleStyle.ALL,
+ HRuleStyle.FRAME,
+ ):
lines.append(self._stringify_hrule(options, where="top_"))
- if title and options["vrules"] in (ALL, FRAME):
+ if title and options["vrules"] in (VRuleStyle.ALL, VRuleStyle.FRAME):
+ left_j_len = len(self.left_junction_char)
+ right_j_len = len(self.right_junction_char)
lines[-1] = (
- self.left_junction_char + lines[-1][1:-1] + self.right_junction_char
+ self.left_junction_char
+ + lines[-1][left_j_len:-right_j_len]
+ + self.right_junction_char
)
# Add rows
@@ -1850,29 +2001,33 @@ class PrettyTable:
)
# Add bottom of border
- if options["border"] and options["hrules"] == FRAME:
+ if options["border"] and options["hrules"] == HRuleStyle.FRAME:
lines.append(self._stringify_hrule(options, where="bottom_"))
if "orgmode" in self.__dict__ and self.orgmode:
+ left_j_len = len(self.left_junction_char)
+ right_j_len = len(self.right_junction_char)
lines = [
- "|" + new_line[1:-1] + "|"
+ "|" + new_line[left_j_len:-right_j_len] + "|"
for old_line in lines
for new_line in old_line.split("\n")
]
return "\n".join(lines)
- def _stringify_hrule(self, options, where: str = ""):
+ def _stringify_hrule(
+ self, options: OptionsType, where: Literal["top_", "bottom_", ""] = ""
+ ) -> str:
if not options["border"] and not options["preserve_internal_border"]:
return ""
lpad, rpad = self._get_padding_widths(options)
- if options["vrules"] in (ALL, FRAME):
- bits = [options[where + "left_junction_char"]]
+ if options["vrules"] in (VRuleStyle.ALL, VRuleStyle.FRAME):
+ bits = [options[where + "left_junction_char"]] # type: ignore[literal-required]
else:
bits = [options["horizontal_char"]]
# For tables with no data or fieldnames
if not self._field_names:
- bits.append(options[where + "right_junction_char"])
+ bits.append(options[where + "right_junction_char"]) # type: ignore[literal-required]
return "".join(bits)
for field, width in zip(self._field_names, self._widths):
if options["fields"] and field not in options["fields"]:
@@ -1888,33 +2043,34 @@ class PrettyTable:
line = line[:-2] + self._horizontal_align_char + " "
bits.append(line)
- if options["vrules"] == ALL:
- bits.append(options[where + "junction_char"])
+ if options["vrules"] == VRuleStyle.ALL:
+ bits.append(options[where + "junction_char"]) # type: ignore[literal-required]
else:
bits.append(options["horizontal_char"])
- if options["vrules"] in (ALL, FRAME):
+ if options["vrules"] in (VRuleStyle.ALL, VRuleStyle.FRAME):
bits.pop()
- bits.append(options[where + "right_junction_char"])
+ bits.append(options[where + "right_junction_char"]) # type: ignore[literal-required]
if options["preserve_internal_border"] and not options["border"]:
bits = bits[1:-1]
return "".join(bits)
- def _stringify_title(self, title, options):
- lines = []
+ def _stringify_title(self, title: str, options: OptionsType) -> str:
+ lines: list[str] = []
lpad, rpad = self._get_padding_widths(options)
if options["border"]:
- if options["vrules"] == ALL:
- options["vrules"] = FRAME
+ if options["vrules"] == VRuleStyle.ALL:
+ options["vrules"] = VRuleStyle.FRAME
lines.append(self._stringify_hrule(options, "top_"))
- options["vrules"] = ALL
- elif options["vrules"] == FRAME:
+ options["vrules"] = VRuleStyle.ALL
+ elif options["vrules"] == VRuleStyle.FRAME:
lines.append(self._stringify_hrule(options, "top_"))
- bits = []
+ bits: list[str] = []
endpoint = (
options["vertical_char"]
- if options["vrules"] in (ALL, FRAME) and options["border"]
+ if options["vrules"] in (VRuleStyle.ALL, VRuleStyle.FRAME)
+ and options["border"]
else " "
)
bits.append(endpoint)
@@ -1927,13 +2083,16 @@ class PrettyTable:
lines.append("".join(bits))
return "\n".join(lines)
- def _stringify_header(self, options):
- bits = []
+ def _stringify_header(self, options: OptionsType) -> str:
+ bits: list[str] = []
lpad, rpad = self._get_padding_widths(options)
if options["border"]:
- if options["hrules"] in (ALL, FRAME):
+ if options["hrules"] in (HRuleStyle.ALL, HRuleStyle.FRAME):
bits.append(self._stringify_hrule(options, "top_"))
- if options["title"] and options["vrules"] in (ALL, FRAME):
+ if options["title"] and options["vrules"] in (
+ VRuleStyle.ALL,
+ VRuleStyle.FRAME,
+ ):
left_j_len = len(self.left_junction_char)
right_j_len = len(self.right_junction_char)
bits[-1] = (
@@ -1942,13 +2101,13 @@ class PrettyTable:
+ self.right_junction_char
)
bits.append("\n")
- if options["vrules"] in (ALL, FRAME):
+ if options["vrules"] in (VRuleStyle.ALL, VRuleStyle.FRAME):
bits.append(options["vertical_char"])
else:
bits.append(" ")
# For tables with no data or field names
if not self._field_names:
- if options["vrules"] in (ALL, FRAME):
+ if options["vrules"] in (VRuleStyle.ALL, VRuleStyle.FRAME):
bits.append(options["vertical_char"])
else:
bits.append(" ")
@@ -1973,7 +2132,7 @@ class PrettyTable:
+ " " * rpad
)
if options["border"] or options["preserve_internal_border"]:
- if options["vrules"] == ALL:
+ if options["vrules"] == VRuleStyle.ALL:
bits.append(options["vertical_char"])
else:
bits.append(" ")
@@ -1985,17 +2144,17 @@ class PrettyTable:
bits.append(" ")
# If vrules is FRAME, then we just appended a space at the end
# of the last field, when we really want a vertical character
- if options["border"] and options["vrules"] == FRAME:
+ if options["border"] and options["vrules"] == VRuleStyle.FRAME:
bits.pop()
bits.append(options["vertical_char"])
if (options["border"] or options["preserve_internal_border"]) and options[
"hrules"
- ] != NONE:
+ ] != HRuleStyle.NONE:
bits.append("\n")
bits.append(self._hrule)
return "".join(bits)
- def _stringify_row(self, row, options, hrule):
+ def _stringify_row(self, row: list[str], options: OptionsType, hrule: str) -> str:
import textwrap
for index, field, value, width in zip(
@@ -2003,10 +2162,13 @@ class PrettyTable:
):
# Enforce max widths
lines = value.split("\n")
- new_lines = []
+ new_lines: list[str] = []
for line in lines:
- if line == "None" and self.none_format.get(field) is not None:
- line = self.none_format[field]
+ if (
+ line == "None"
+ and (none_val := self.none_format.get(field)) is not None
+ ):
+ line = none_val
if _str_block_width(line) > width:
line = textwrap.fill(line, width)
new_lines.append(line)
@@ -2020,12 +2182,12 @@ class PrettyTable:
if h > row_height:
row_height = h
- bits = []
+ bits: list[list[str]] = []
lpad, rpad = self._get_padding_widths(options)
for y in range(0, row_height):
bits.append([])
if options["border"]:
- if options["vrules"] in (ALL, FRAME):
+ if options["vrules"] in (VRuleStyle.ALL, VRuleStyle.FRAME):
bits[y].append(self.vertical_char)
else:
bits[y].append(" ")
@@ -2046,8 +2208,7 @@ class PrettyTable:
else:
lines = lines + [""] * d_height
- y = 0
- for line in lines:
+ for y, line in enumerate(lines):
if options["fields"] and field not in options["fields"]:
continue
@@ -2057,11 +2218,10 @@ class PrettyTable:
+ " " * rpad
)
if options["border"] or options["preserve_internal_border"]:
- if options["vrules"] == ALL:
+ if options["vrules"] == VRuleStyle.ALL:
bits[y].append(self.vertical_char)
else:
bits[y].append(" ")
- y += 1
# If only preserve_internal_border is true, then we just appended
# a vertical character at the end when we wanted a space
@@ -2072,21 +2232,19 @@ class PrettyTable:
# If vrules is FRAME, then we just appended a space at the end
# of the last field, when we really want a vertical character
for y in range(0, row_height):
- if options["border"] and options["vrules"] == FRAME:
+ if options["border"] and options["vrules"] == VRuleStyle.FRAME:
bits[y].pop()
bits[y].append(options["vertical_char"])
- if options["border"] and options["hrules"] == ALL:
+ if options["border"] and options["hrules"] == HRuleStyle.ALL:
bits[row_height - 1].append("\n")
bits[row_height - 1].append(hrule)
- for y in range(0, row_height):
- bits[y] = "".join(bits[y])
-
- return "\n".join(bits)
+ bits_str = ["".join(bits_y) for bits_y in bits]
+ return "\n".join(bits_str)
- def paginate(self, page_length: int = 58, line_break: str = "\f", **kwargs):
- pages = []
+ def paginate(self, page_length: int = 58, line_break: str = "\f", **kwargs) -> str:
+ pages: list[str] = []
kwargs["start"] = kwargs.get("start", 0)
true_end = kwargs.get("end", self.rowcount)
while True:
@@ -2152,7 +2310,11 @@ class PrettyTable:
import json
options = self._get_options(kwargs)
- json_options: Any = {"indent": 4, "separators": (",", ": "), "sort_keys": True}
+ json_options: dict[str, Any] = {
+ "indent": 4,
+ "separators": (",", ": "),
+ "sort_keys": True,
+ }
json_options.update(
{key: value for key, value in kwargs.items() if key not in options}
)
@@ -2199,9 +2361,9 @@ class PrettyTable:
preserve_internal_border - print a border inside the table even if
border is disabled (True or False)
hrules - controls printing of horizontal rules after rows.
- Allowed values: ALL, FRAME, HEADER, NONE
+ Allowed values: HRuleStyle
vrules - controls printing of vertical rules between columns.
- Allowed values: FRAME, ALL, NONE
+ Allowed values: VRuleStyle
int_format - controls formatting of integer data
float_format - controls formatting of floating point data
custom_format - controls formatting of any column using callable
@@ -2227,10 +2389,10 @@ class PrettyTable:
return string
- def _get_simple_html_string(self, options):
+ def _get_simple_html_string(self, options: OptionsType) -> str:
from html import escape
- lines = []
+ lines: list[str] = []
if options["xhtml"]:
linebreak = "<br/>"
else:
@@ -2238,10 +2400,8 @@ class PrettyTable:
open_tag = ["<table"]
if options["attributes"]:
- for attr_name in options["attributes"]:
- open_tag.append(
- f' {escape(attr_name)}="{escape(options["attributes"][attr_name])}"'
- )
+ for attr_name, attr_value in options["attributes"].items():
+ open_tag.append(f' {escape(attr_name)}="{escape(attr_value)}"')
open_tag.append(">")
lines.append("".join(open_tag))
@@ -2288,10 +2448,10 @@ class PrettyTable:
return "\n".join(lines)
- def _get_formatted_html_string(self, options):
+ def _get_formatted_html_string(self, options: OptionsType) -> str:
from html import escape
- lines = []
+ lines: list[str] = []
lpad, rpad = self._get_padding_widths(options)
if options["xhtml"]:
linebreak = "<br/>"
@@ -2300,27 +2460,34 @@ class PrettyTable:
open_tag = ["<table"]
if options["border"]:
- if options["hrules"] == ALL and options["vrules"] == ALL:
+ if (
+ options["hrules"] == HRuleStyle.ALL
+ and options["vrules"] == VRuleStyle.ALL
+ ):
open_tag.append(' frame="box" rules="all"')
- elif options["hrules"] == FRAME and options["vrules"] == FRAME:
+ elif (
+ options["hrules"] == HRuleStyle.FRAME
+ and options["vrules"] == VRuleStyle.FRAME
+ ):
open_tag.append(' frame="box"')
- elif options["hrules"] == FRAME and options["vrules"] == ALL:
+ elif (
+ options["hrules"] == HRuleStyle.FRAME
+ and options["vrules"] == VRuleStyle.ALL
+ ):
open_tag.append(' frame="box" rules="cols"')
- elif options["hrules"] == FRAME:
+ elif options["hrules"] == HRuleStyle.FRAME:
open_tag.append(' frame="hsides"')
- elif options["hrules"] == ALL:
+ elif options["hrules"] == HRuleStyle.ALL:
open_tag.append(' frame="hsides" rules="rows"')
- elif options["vrules"] == FRAME:
+ elif options["vrules"] == VRuleStyle.FRAME:
open_tag.append(' frame="vsides"')
- elif options["vrules"] == ALL:
+ elif options["vrules"] == VRuleStyle.ALL:
open_tag.append(' frame="vsides" rules="cols"')
if not options["border"] and options["preserve_internal_border"]:
open_tag.append(' rules="cols"')
if options["attributes"]:
- for attr_name in options["attributes"]:
- open_tag.append(
- f' {escape(attr_name)}="{escape(options["attributes"][attr_name])}"'
- )
+ for attr_name, attr_value in options["attributes"].items():
+ open_tag.append(f' {escape(attr_name)}="{escape(attr_value)}"')
open_tag.append(">")
lines.append("".join(open_tag))
@@ -2350,8 +2517,8 @@ class PrettyTable:
lines.append(" <tbody>")
rows = self._get_rows(options)
formatted_rows = self._format_rows(rows)
- aligns = []
- valigns = []
+ aligns: list[str] = []
+ valigns: list[str] = []
for field in self._field_names:
aligns.append(
{"l": "left", "r": "right", "c": "center"}[self._align[field]]
@@ -2403,9 +2570,9 @@ class PrettyTable:
preserve_internal_border - print a border inside the table even if
border is disabled (True or False)
hrules - controls printing of horizontal rules after rows.
- Allowed values: ALL, FRAME, HEADER, NONE
+ Allowed values: HRuleStyle
vrules - controls printing of vertical rules between columns.
- Allowed values: FRAME, ALL, NONE
+ Allowed values: VRuleStyle
int_format - controls formatting of integer data
float_format - controls formatting of floating point data
sortby - name of field to sort rows by
@@ -2421,8 +2588,8 @@ class PrettyTable:
string = self._get_simple_latex_string(options)
return string
- def _get_simple_latex_string(self, options):
- lines = []
+ def _get_simple_latex_string(self, options: OptionsType) -> str:
+ lines: list[str] = []
wanted_fields = []
if options["fields"]:
@@ -2454,10 +2621,10 @@ class PrettyTable:
return "\r\n".join(lines)
- def _get_formatted_latex_string(self, options):
- lines = []
+ def _get_formatted_latex_string(self, options: OptionsType) -> str:
+ lines: list[str] = []
- wanted_fields = []
+ wanted_fields: list[str] = []
if options["fields"]:
wanted_fields = [
field for field in self._field_names if field in options["fields"]
@@ -2466,19 +2633,25 @@ class PrettyTable:
wanted_fields = self._field_names
wanted_alignments = [self._align[field] for field in wanted_fields]
- if options["border"] and options["vrules"] == ALL:
+ if options["border"] and options["vrules"] == VRuleStyle.ALL:
alignment_str = "|".join(wanted_alignments)
elif not options["border"] and options["preserve_internal_border"]:
alignment_str = "|".join(wanted_alignments)
else:
alignment_str = "".join(wanted_alignments)
- if options["border"] and options["vrules"] in [ALL, FRAME]:
+ if options["border"] and options["vrules"] in [
+ VRuleStyle.ALL,
+ VRuleStyle.FRAME,
+ ]:
alignment_str = "|" + alignment_str + "|"
begin_cmd = f"\\begin{{tabular}}{{{alignment_str}}}"
lines.append(begin_cmd)
- if options["border"] and options["hrules"] in [ALL, FRAME]:
+ if options["border"] and options["hrules"] in [
+ HRuleStyle.ALL,
+ HRuleStyle.FRAME,
+ ]:
lines.append("\\hline")
# Headers
@@ -2486,7 +2659,7 @@ class PrettyTable:
lines.append(" & ".join(wanted_fields) + " \\\\")
if (options["border"] or options["preserve_internal_border"]) and options[
"hrules"
- ] in [ALL, HEADER]:
+ ] in [HRuleStyle.ALL, HRuleStyle.HEADER]:
lines.append("\\hline")
# Data
@@ -2498,10 +2671,10 @@ class PrettyTable:
d for f, d in zip(self._field_names, row) if f in wanted_fields
]
lines.append(" & ".join(wanted_data) + " \\\\")
- if options["border"] and options["hrules"] == ALL:
+ if options["border"] and options["hrules"] == HRuleStyle.ALL:
lines.append("\\hline")
- if options["border"] and options["hrules"] == FRAME:
+ if options["border"] and options["hrules"] == HRuleStyle.FRAME:
lines.append("\\hline")
lines.append("\\end{tabular}")
@@ -2514,8 +2687,8 @@ class PrettyTable:
##############################
-def _str_block_width(val):
- import wcwidth # type: ignore[import-not-found]
+def _str_block_width(val: str) -> int:
+ import wcwidth # type: ignore[import-untyped]
return wcwidth.wcswidth(_re.sub("", val))
@@ -2525,7 +2698,7 @@ def _str_block_width(val):
##############################
-def from_csv(fp, field_names: Any | None = None, **kwargs):
+def from_csv(fp, field_names: Sequence[str] | None = None, **kwargs) -> PrettyTable:
import csv
fmtparams = {}
@@ -2560,16 +2733,17 @@ def from_csv(fp, field_names: Any | None = None, **kwargs):
return table
-def from_db_cursor(cursor, **kwargs):
+def from_db_cursor(cursor: Cursor, **kwargs) -> PrettyTable | None:
if cursor.description:
table = PrettyTable(**kwargs)
table.field_names = [col[0] for col in cursor.description]
for row in cursor.fetchall():
table.add_row(row)
return table
+ return None
-def from_json(json_string, **kwargs):
+def from_json(json_string: str | bytes, **kwargs) -> PrettyTable:
import json
table = PrettyTable(**kwargs)
@@ -2585,29 +2759,29 @@ class TableHandler(HTMLParser):
def __init__(self, **kwargs) -> None:
HTMLParser.__init__(self)
self.kwargs = kwargs
- self.tables: list[list] = []
+ self.tables: list[PrettyTable] = []
self.last_row: list[str] = []
- self.rows: list[Any] = []
+ self.rows: list[tuple[list[str], bool]] = []
self.max_row_width = 0
- self.active = None
+ self.active: str | None = None
self.last_content = ""
self.is_last_row_header = False
self.colspan = 0
- def handle_starttag(self, tag, attrs) -> None:
+ def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
self.active = tag
if tag == "th":
self.is_last_row_header = True
for key, value in attrs:
if key == "colspan":
- self.colspan = int(value)
+ self.colspan = int(value) # type: ignore[arg-type]
- def handle_endtag(self, tag) -> None:
+ def handle_endtag(self, tag: str) -> None:
if tag in ["th", "td"]:
stripped_content = self.last_content.strip()
self.last_row.append(stripped_content)
if self.colspan:
- for i in range(1, self.colspan):
+ for _ in range(1, self.colspan):
self.last_row.append("")
self.colspan = 0
@@ -2623,10 +2797,10 @@ class TableHandler(HTMLParser):
self.last_content = " "
self.active = None
- def handle_data(self, data) -> None:
+ def handle_data(self, data: str) -> None:
self.last_content += data
- def generate_table(self, rows):
+ def generate_table(self, rows: list[tuple[list[str], bool]]) -> PrettyTable:
"""
Generates from a list of rows a PrettyTable object.
"""
@@ -2644,7 +2818,7 @@ class TableHandler(HTMLParser):
table.add_row(row[0])
return table
- def make_fields_unique(self, fields) -> None:
+ def make_fields_unique(self, fields: list[str]) -> None:
"""
iterates over the row and make each field unique
"""
@@ -2654,7 +2828,7 @@ class TableHandler(HTMLParser):
fields[j] += "'"
-def from_html(html_code, **kwargs):
+def from_html(html_code: str, **kwargs) -> list[PrettyTable]:
"""
Generates a list of PrettyTables from a string of HTML code. Each <table> in
the HTML becomes one PrettyTable object.
@@ -2665,9 +2839,9 @@ def from_html(html_code, **kwargs):
return parser.tables
-def from_html_one(html_code, **kwargs):
+def from_html_one(html_code: str, **kwargs) -> PrettyTable:
"""
- Generates a PrettyTables from a string of HTML code which contains only a
+ Generates a PrettyTable from a string of HTML code which contains only a
single <table>
"""
@@ -2678,3 +2852,23 @@ def from_html_one(html_code, **kwargs):
msg = "More than one <table> in provided HTML code. Use from_html instead."
raise ValueError(msg)
return tables[0]
+
+
+def _warn_deprecation(name: str, module_globals: dict[str, Any]) -> Any:
+ if (val := module_globals.get(f"_DEPRECATED_{name}")) is None:
+ msg = f"module '{__name__}' has no attribute '{name}"
+ raise AttributeError(msg)
+ module_globals[name] = val
+ if name in {"FRAME", "ALL", "NONE", "HEADER"}:
+ msg = (
+ f"the '{name}' constant is deprecated, "
+ "use the 'HRuleStyle' and 'VRuleStyle' enums instead"
+ )
+ else:
+ msg = f"the '{name}' constant is deprecated, use the 'TableStyle' enum instead"
+ warnings.warn(msg, DeprecationWarning, stacklevel=3)
+ return val
+
+
+def __getattr__(name: str) -> Any:
+ return _warn_deprecation(name, module_globals=globals())
diff --git a/contrib/python/prettytable/py3/tests/test_colortable.py b/contrib/python/prettytable/py3/tests/test_colortable.py
index 4668ed54dd..5055638438 100644
--- a/contrib/python/prettytable/py3/tests/test_colortable.py
+++ b/contrib/python/prettytable/py3/tests/test_colortable.py
@@ -105,7 +105,16 @@ class TestColorTableRendering:
Tests the color table rendering using the default alignment (`'c'`)
"""
- def test_color_table_rendering(self) -> None:
+ @pytest.mark.parametrize(
+ ["with_title", "with_header"],
+ [
+ (False, True), # the default
+ (True, True), # titled
+ (True, False), # titled, no header
+ (True, True), # both title and header
+ ],
+ )
+ def test_color_table_rendering(self, with_title: bool, with_header: bool) -> None:
"""Tests the color table rendering using the default alignment (`'c'`)"""
chars = {
"+": "\x1b[36m+\x1b[0m\x1b[96m",
@@ -140,18 +149,40 @@ class TestColorTableRendering:
(plus + minus * 3) * 6 + plus,
)
- header_str = str("\n".join(header))
- body_str = str("\n".join(body))
+ if with_title:
+ header_str = str("\n".join(header))
+ else:
+ header_str = str(header[2])
+ if with_header:
+ body_str = str("\n".join(body))
+ else:
+ body_str = str("\n".join(body[2:]))
table = ColorTable(
("A", "B", "C", "D", "E", "F"),
theme=Themes.OCEAN,
)
- table.title = "Efforts"
+ if with_title:
+ table.title = "Efforts"
+ table.header = with_header
table.add_row([1, 2, 3, 4, 5, 6])
expected = header_str + "\n" + body_str + "\x1b[0m"
result = str(table)
assert expected == result
+
+ def test_all_themes(self) -> None:
+ """Tests rendering with all available themes"""
+ table = ColorTable(
+ ("A", "B", "C", "D", "E", "F"),
+ )
+ table.title = "Theme Test"
+ table.add_row([1, 2, 3, 4, 5, 6])
+
+ for theme_name, theme in vars(Themes).items():
+ if isinstance(theme, Theme):
+ table.theme = theme
+ result = str(table)
+ assert result # Simple check to ensure rendering doesn't fail
diff --git a/contrib/python/prettytable/py3/tests/test_prettytable.py b/contrib/python/prettytable/py3/tests/test_prettytable.py
index 5cebb89521..75254ca89a 100644
--- a/contrib/python/prettytable/py3/tests/test_prettytable.py
+++ b/contrib/python/prettytable/py3/tests/test_prettytable.py
@@ -12,19 +12,10 @@ from pytest_lazy_fixtures import lf
import prettytable
from prettytable import (
- ALL,
- DEFAULT,
- DOUBLE_BORDER,
- FRAME,
- HEADER,
- MARKDOWN,
- MSWORD_FRIENDLY,
- NONE,
- ORGMODE,
- PLAIN_COLUMNS,
- RANDOM,
- SINGLE_BORDER,
+ HRuleStyle,
PrettyTable,
+ TableStyle,
+ VRuleStyle,
from_csv,
from_db_cursor,
from_html,
@@ -314,22 +305,22 @@ def field_name_less_table() -> PrettyTable:
class TestFieldNameLessTable:
"""Make sure that building and stringing a table with no fieldnames works fine"""
- def test_can_string_ascii(self, field_name_less_table: prettytable) -> None:
+ def test_can_string_ascii(self, field_name_less_table: PrettyTable) -> None:
output = field_name_less_table.get_string()
assert "| Field 1 | Field 2 | Field 3 | Field 4 |" in output
assert "| Adelaide | 1295 | 1158259 | 600.5 |" in output
- def test_can_string_html(self, field_name_less_table: prettytable) -> None:
+ def test_can_string_html(self, field_name_less_table: PrettyTable) -> None:
output = field_name_less_table.get_html_string()
assert "<th>Field 1</th>" in output
assert "<td>Adelaide</td>" in output
- def test_can_string_latex(self, field_name_less_table: prettytable) -> None:
+ def test_can_string_latex(self, field_name_less_table: PrettyTable) -> None:
output = field_name_less_table.get_latex_string()
assert "Field 1 & Field 2 & Field 3 & Field 4 \\\\" in output
assert "Adelaide & 1295 & 1158259 & 600.5 \\\\" in output
- def test_add_field_names_later(self, field_name_less_table: prettytable) -> None:
+ def test_add_field_names_later(self, field_name_less_table: PrettyTable) -> None:
field_name_less_table.field_names = [
"City name",
"Area",
@@ -376,21 +367,21 @@ class TestAlignment:
"""Make sure alignment works regardless of when it was set"""
def test_aligned_ascii(
- self, aligned_before_table: prettytable, aligned_after_table: prettytable
+ self, aligned_before_table: PrettyTable, aligned_after_table: PrettyTable
) -> None:
before = aligned_before_table.get_string()
after = aligned_after_table.get_string()
assert before == after
def test_aligned_html(
- self, aligned_before_table: prettytable, aligned_after_table: prettytable
+ self, aligned_before_table: PrettyTable, aligned_after_table: PrettyTable
) -> None:
before = aligned_before_table.get_html_string()
after = aligned_after_table.get_html_string()
assert before == after
def test_aligned_latex(
- self, aligned_before_table: prettytable, aligned_after_table: prettytable
+ self, aligned_before_table: PrettyTable, aligned_after_table: PrettyTable
) -> None:
before = aligned_before_table.get_latex_string()
after = aligned_after_table.get_latex_string()
@@ -428,7 +419,7 @@ def city_data_from_csv() -> PrettyTable:
class TestOptionOverride:
"""Make sure all options are properly overwritten by get_string."""
- def test_border(self, city_data_prettytable: prettytable) -> None:
+ def test_border(self, city_data_prettytable: PrettyTable) -> None:
default = city_data_prettytable.get_string()
override = city_data_prettytable.get_string(border=False)
assert default != override
@@ -440,12 +431,12 @@ class TestOptionOverride:
def test_hrules_all(self, city_data_prettytable) -> None:
default = city_data_prettytable.get_string()
- override = city_data_prettytable.get_string(hrules=ALL)
+ override = city_data_prettytable.get_string(hrules=HRuleStyle.ALL)
assert default != override
def test_hrules_none(self, city_data_prettytable) -> None:
default = city_data_prettytable.get_string()
- override = city_data_prettytable.get_string(hrules=NONE)
+ override = city_data_prettytable.get_string(hrules=HRuleStyle.NONE)
assert default != override
@@ -535,12 +526,12 @@ class TestBasic:
assert len(rows) == 7
assert rows[0] == ["Adelaide", 1295, 1158259, 600.5]
- def _test_no_blank_lines(self, table: prettytable) -> None:
+ def _test_no_blank_lines(self, table: PrettyTable) -> None:
string = table.get_string()
lines = string.split("\n")
assert "" not in lines
- def _test_all_length_equal(self, table: prettytable) -> None:
+ def _test_all_length_equal(self, table: PrettyTable) -> None:
string = table.get_string()
lines = string.split("\n")
lengths = [len(line) for line in lines]
@@ -608,42 +599,42 @@ class TestBasic:
self, city_data_prettytable: PrettyTable
) -> None:
"""No table should ever have blank lines in it."""
- city_data_prettytable.hrules = NONE
+ city_data_prettytable.hrules = HRuleStyle.NONE
self._test_no_blank_lines(city_data_prettytable)
def test_all_lengths_equal_with_hrules_none(
self, city_data_prettytable: PrettyTable
) -> None:
"""All lines in a table should be of the same length."""
- city_data_prettytable.hrules = NONE
+ city_data_prettytable.hrules = HRuleStyle.NONE
self._test_all_length_equal(city_data_prettytable)
def test_no_blank_lines_with_hrules_all(
self, city_data_prettytable: PrettyTable
) -> None:
"""No table should ever have blank lines in it."""
- city_data_prettytable.hrules = ALL
+ city_data_prettytable.hrules = HRuleStyle.ALL
self._test_no_blank_lines(city_data_prettytable)
def test_all_lengths_equal_with_hrules_all(
self, city_data_prettytable: PrettyTable
) -> None:
"""All lines in a table should be of the same length."""
- city_data_prettytable.hrules = ALL
+ city_data_prettytable.hrules = HRuleStyle.ALL
self._test_all_length_equal(city_data_prettytable)
def test_no_blank_lines_with_style_msword(
self, city_data_prettytable: PrettyTable
) -> None:
"""No table should ever have blank lines in it."""
- city_data_prettytable.set_style(MSWORD_FRIENDLY)
+ city_data_prettytable.set_style(TableStyle.MSWORD_FRIENDLY)
self._test_no_blank_lines(city_data_prettytable)
def test_all_lengths_equal_with_style_msword(
self, city_data_prettytable: PrettyTable
) -> None:
"""All lines in a table should be of the same length."""
- city_data_prettytable.set_style(MSWORD_FRIENDLY)
+ city_data_prettytable.set_style(TableStyle.MSWORD_FRIENDLY)
self._test_all_length_equal(city_data_prettytable)
def test_no_blank_lines_with_int_format(
@@ -850,7 +841,7 @@ class TestBreakLine:
[
(
[["value 1", "value2\nsecond line"], ["value 3", "value4"]],
- ALL,
+ HRuleStyle.ALL,
"""
+---------+-------------+
| Field 1 | Field 2 |
@@ -867,7 +858,7 @@ class TestBreakLine:
["value 1", "value2\nsecond line"],
["value 3\n\nother line", "value4\n\n\nvalue5"],
],
- ALL,
+ HRuleStyle.ALL,
"""
+------------+-------------+
| Field 1 | Field 2 |
@@ -887,7 +878,7 @@ class TestBreakLine:
["value 1", "value2\nsecond line"],
["value 3\n\nother line", "value4\n\n\nvalue5"],
],
- FRAME,
+ HRuleStyle.FRAME,
"""
+------------+-------------+
| Field 1 | Field 2 |
@@ -916,7 +907,7 @@ class TestBreakLine:
table = PrettyTable(["Field 1", "Field 2"])
table.add_row(["value 1", "value2\nsecond line"])
table.add_row(["value 3", "value4"])
- result = table.get_html_string(hrules=ALL)
+ result = table.get_html_string(hrules=HRuleStyle.ALL)
assert (
result.strip()
== """
@@ -1455,7 +1446,7 @@ class TestPositionalJunctions:
"""Verify different cases for positional-junction characters"""
def test_default(self, city_data_prettytable: PrettyTable) -> None:
- city_data_prettytable.set_style(DOUBLE_BORDER)
+ city_data_prettytable.set_style(TableStyle.DOUBLE_BORDER)
assert (
city_data_prettytable.get_string().strip()
@@ -1474,7 +1465,7 @@ class TestPositionalJunctions:
)
def test_no_header(self, city_data_prettytable: PrettyTable) -> None:
- city_data_prettytable.set_style(DOUBLE_BORDER)
+ city_data_prettytable.set_style(TableStyle.DOUBLE_BORDER)
city_data_prettytable.header = False
assert (
@@ -1492,7 +1483,7 @@ class TestPositionalJunctions:
)
def test_with_title(self, city_data_prettytable: PrettyTable) -> None:
- city_data_prettytable.set_style(DOUBLE_BORDER)
+ city_data_prettytable.set_style(TableStyle.DOUBLE_BORDER)
city_data_prettytable.title = "Title"
assert (
@@ -1514,7 +1505,7 @@ class TestPositionalJunctions:
)
def test_with_title_no_header(self, city_data_prettytable: PrettyTable) -> None:
- city_data_prettytable.set_style(DOUBLE_BORDER)
+ city_data_prettytable.set_style(TableStyle.DOUBLE_BORDER)
city_data_prettytable.title = "Title"
city_data_prettytable.header = False
assert (
@@ -1534,9 +1525,9 @@ class TestPositionalJunctions:
)
def test_hrule_all(self, city_data_prettytable: PrettyTable) -> None:
- city_data_prettytable.set_style(DOUBLE_BORDER)
+ city_data_prettytable.set_style(TableStyle.DOUBLE_BORDER)
city_data_prettytable.title = "Title"
- city_data_prettytable.hrules = ALL
+ city_data_prettytable.hrules = HRuleStyle.ALL
assert (
city_data_prettytable.get_string().strip()
== """
@@ -1562,8 +1553,8 @@ class TestPositionalJunctions:
)
def test_vrules_none(self, city_data_prettytable: PrettyTable) -> None:
- city_data_prettytable.set_style(DOUBLE_BORDER)
- city_data_prettytable.vrules = NONE
+ city_data_prettytable.set_style(TableStyle.DOUBLE_BORDER)
+ city_data_prettytable.vrules = VRuleStyle.NONE
assert (
city_data_prettytable.get_string().strip()
== "═══════════════════════════════════════════════════\n"
@@ -1580,8 +1571,8 @@ class TestPositionalJunctions:
)
def test_vrules_frame_with_title(self, city_data_prettytable: PrettyTable) -> None:
- city_data_prettytable.set_style(DOUBLE_BORDER)
- city_data_prettytable.vrules = FRAME
+ city_data_prettytable.set_style(TableStyle.DOUBLE_BORDER)
+ city_data_prettytable.vrules = VRuleStyle.FRAME
city_data_prettytable.title = "Title"
assert (
city_data_prettytable.get_string().strip()
@@ -1607,7 +1598,7 @@ class TestStyle:
"style, expected",
[
pytest.param(
- DEFAULT,
+ TableStyle.DEFAULT,
"""
+---+---------+---------+---------+
| | Field 1 | Field 2 | Field 3 |
@@ -1620,7 +1611,7 @@ class TestStyle:
id="DEFAULT",
),
pytest.param(
- MARKDOWN, # TODO fix
+ TableStyle.MARKDOWN, # TODO fix
"""
| | Field 1 | Field 2 | Field 3 |
| :-: | :-----: | :-----: | :-----: |
@@ -1631,7 +1622,7 @@ class TestStyle:
id="MARKDOWN",
),
pytest.param(
- MSWORD_FRIENDLY,
+ TableStyle.MSWORD_FRIENDLY,
"""
| | Field 1 | Field 2 | Field 3 |
| 1 | value 1 | value2 | value3 |
@@ -1641,7 +1632,7 @@ class TestStyle:
id="MSWORD_FRIENDLY",
),
pytest.param(
- ORGMODE,
+ TableStyle.ORGMODE,
"""
|---+---------+---------+---------|
| | Field 1 | Field 2 | Field 3 |
@@ -1654,7 +1645,7 @@ class TestStyle:
id="ORGMODE",
),
pytest.param(
- PLAIN_COLUMNS,
+ TableStyle.PLAIN_COLUMNS,
"""
Field 1 Field 2 Field 3
1 value 1 value2 value3
@@ -1664,20 +1655,18 @@ class TestStyle:
id="PLAIN_COLUMNS",
),
pytest.param(
- RANDOM,
+ TableStyle.RANDOM,
"""
-'^^^^^'^^^^^^^^^^^'^^^^^^^^^^'^^^^^^^^^^'
-% 1% value 1% value2% value3%
-'^^^^^'^^^^^^^^^^^'^^^^^^^^^^'^^^^^^^^^^'
-% 4% value 4% value5% value6%
-'^^^^^'^^^^^^^^^^^'^^^^^^^^^^'^^^^^^^^^^'
-% 7% value 7% value8% value9%
-'^^^^^'^^^^^^^^^^^'^^^^^^^^^^'^^^^^^^^^^'
+'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'
+% 1 value 1 value2 value3%
+% 4 value 4 value5 value6%
+% 7 value 7 value8 value9%
+'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'
""",
id="RANDOM",
),
pytest.param(
- DOUBLE_BORDER,
+ TableStyle.DOUBLE_BORDER,
"""
╔═══╦═════════╦═════════╦═════════╗
║ ║ Field 1 ║ Field 2 ║ Field 3 ║
@@ -1689,7 +1678,7 @@ class TestStyle:
""",
),
pytest.param(
- SINGLE_BORDER,
+ TableStyle.SINGLE_BORDER,
"""
┌───┬─────────┬─────────┬─────────┐
│ │ Field 1 │ Field 2 │ Field 3 │
@@ -1721,13 +1710,13 @@ class TestStyle:
# Act / Assert
# This is an hrule style, not a table style
with pytest.raises(ValueError):
- t.set_style(ALL)
+ t.set_style(HRuleStyle.ALL) # type: ignore[arg-type]
@pytest.mark.parametrize(
"style, expected",
[
pytest.param(
- MARKDOWN,
+ TableStyle.MARKDOWN,
"""
| l | c | r | Align left | Align centre | Align right |
| :-| :-: |-: | :----------| :----------: |-----------: |
@@ -1829,7 +1818,7 @@ class TestLatexOutput:
"\\end{tabular}"
)
- options = {"vrules": FRAME}
+ options = {"vrules": VRuleStyle.FRAME}
assert t.get_latex_string(format=True, **options) == (
"\\begin{tabular}{|cccc|}\r\n"
"\\hline\r\n"
@@ -1841,7 +1830,7 @@ class TestLatexOutput:
"\\end{tabular}"
)
- options = {"hrules": ALL}
+ options = {"hrules": HRuleStyle.ALL}
assert t.get_latex_string(format=True, **options) == (
"\\begin{tabular}{|c|c|c|c|}\r\n"
"\\hline\r\n"
@@ -1858,7 +1847,7 @@ class TestLatexOutput:
def test_latex_output_header(self) -> None:
t = helper_table()
- assert t.get_latex_string(format=True, hrules=HEADER) == (
+ assert t.get_latex_string(format=True, hrules=HRuleStyle.HEADER) == (
"\\begin{tabular}{|c|c|c|c|}\r\n"
" & Field 1 & Field 2 & Field 3 \\\\\r\n"
"\\hline\r\n"
@@ -2368,7 +2357,7 @@ class TestMaxTableWidth:
def test_max_table_width_wide_vrules_frame(self) -> None:
table = PrettyTable()
table.max_table_width = 52
- table.vrules = FRAME
+ table.vrules = VRuleStyle.FRAME
table.add_row(
[
0,
@@ -2400,7 +2389,7 @@ class TestMaxTableWidth:
def test_max_table_width_wide_vrules_none(self) -> None:
table = PrettyTable()
table.max_table_width = 52
- table.vrules = NONE
+ table.vrules = VRuleStyle.NONE
table.add_row(
[
0,
@@ -2608,3 +2597,51 @@ class TestGeneralOutput:
t = helper_table()
with pytest.raises(ValueError):
t.get_formatted_string("pdf")
+
+
+class TestDeprecations:
+ @pytest.mark.parametrize(
+ "module_name",
+ [
+ "prettytable",
+ "prettytable.prettytable",
+ ],
+ )
+ @pytest.mark.parametrize(
+ "name",
+ [
+ "FRAME",
+ "ALL",
+ "NONE",
+ "HEADER",
+ ],
+ )
+ def test_hrule_constant_deprecations(self, module_name: str, name: str) -> None:
+ with pytest.deprecated_call(match=f"the '{name}' constant is deprecated"):
+ exec(f"from {module_name} import {name}")
+
+ @pytest.mark.parametrize(
+ "module_name",
+ [
+ "prettytable",
+ "prettytable.prettytable",
+ ],
+ )
+ @pytest.mark.parametrize(
+ "name",
+ [
+ "DEFAULT",
+ "MSWORD_FRIENDLY",
+ "PLAIN_COLUMNS",
+ "MARKDOWN",
+ "ORGMODE",
+ "DOUBLE_BORDER",
+ "SINGLE_BORDER",
+ "RANDOM",
+ ],
+ )
+ def test_table_style_constant_deprecations(
+ self, module_name: str, name: str
+ ) -> None:
+ with pytest.deprecated_call(match=f"the '{name}' constant is deprecated"):
+ exec(f"from {module_name} import {name}")
diff --git a/contrib/python/prettytable/py3/ya.make b/contrib/python/prettytable/py3/ya.make
index 108de3e08a..6f495203a6 100644
--- a/contrib/python/prettytable/py3/ya.make
+++ b/contrib/python/prettytable/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(3.11.0)
+VERSION(3.12.0)
LICENSE(BSD-3-Clause)
@@ -15,6 +15,7 @@ NO_LINT()
PY_SRCS(
TOP_LEVEL
prettytable/__init__.py
+ prettytable/_version.py
prettytable/colortable.py
prettytable/prettytable.py
)