diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fb81f7d9..0a80deed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,13 +67,13 @@ jobs: fail-fast: false matrix: python-version: - ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "pypy-3.8"] + ["pypy3.10", "3.9", "3.10", "3.11", "3.12", "3.13"] os: [ubuntu-latest, macos-latest, windows-latest] exclude: - os: macos-latest - python-version: "pypy-3.8" + python-version: "pypy3.10" - os: windows-latest - python-version: "pypy-3.8" + python-version: "pypy3.10" steps: - uses: actions/checkout@v4 diff --git a/README.rst b/README.rst index 9bab153b..baa31c59 100644 --- a/README.rst +++ b/README.rst @@ -752,7 +752,7 @@ https://pytablewriter.rtfd.io/en/latest/pages/examples/index.html Dependencies ============ -- Python 3.7+ +- Python 3.9+ - `Python package dependencies (automatically installed) `__ diff --git a/docs/pages/introduction/dependencies.rst b/docs/pages/introduction/dependencies.rst index 17b6004f..dfa2699f 100644 --- a/docs/pages/introduction/dependencies.rst +++ b/docs/pages/introduction/dependencies.rst @@ -1,6 +1,6 @@ Dependencies ============ -- Python 3.7+ +- Python 3.9+ - `Python package dependencies (automatically installed) `__ diff --git a/pyproject.toml b/pyproject.toml index 8c667c8d..ca32678a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ exclude = ''' | setup.py ''' line-length = 100 -target-version = ['py37', 'py38', 'py39', 'py310', 'py311', 'py312'] +target-version = ['py39', 'py310', 'py311', 'py312', 'py313'] [tool.isort] include_trailing_comma = true @@ -72,7 +72,7 @@ show_missing = true [tool.mypy] ignore_missing_imports = true -python_version = 3.7 +python_version = 3.9 pretty = true diff --git a/pytablewriter/_factory.py b/pytablewriter/_factory.py index 1b404bc0..8f574d53 100644 --- a/pytablewriter/_factory.py +++ b/pytablewriter/_factory.py @@ -4,7 +4,7 @@ import os from itertools import chain -from typing import Any, List +from typing import Any import typepy @@ -167,7 +167,7 @@ def create_from_format_name(cls, format_name: str, **kwargs: Any) -> AbstractTab ) @classmethod - def get_format_names(cls) -> List[str]: + def get_format_names(cls) -> list[str]: """ :return: Available format names. :rtype: list @@ -228,7 +228,7 @@ def get_format_names(cls) -> List[str]: return sorted(list(set(chain(*(table_format.names for table_format in TableFormat))))) @classmethod - def get_extensions(cls) -> List[str]: + def get_extensions(cls) -> list[str]: """ :return: Available file extensions. :rtype: list diff --git a/pytablewriter/_function.py b/pytablewriter/_function.py index b8e2bfca..0e116a1a 100644 --- a/pytablewriter/_function.py +++ b/pytablewriter/_function.py @@ -4,7 +4,7 @@ from datetime import datetime from enum import Enum -from typing import Any, Optional, Type +from typing import Any, Optional import dataproperty from pathvalidate import replace_symbol @@ -60,7 +60,7 @@ def dumps_tabledata(value: TableData, format_name: str = "rst_grid_table", **kwa def normalize_enum( - value: Any, enum_class: Type[Enum], validate: bool = True, default: Optional[Enum] = None + value: Any, enum_class: type[Enum], validate: bool = True, default: Optional[Enum] = None ) -> Any: if value is None: return default diff --git a/pytablewriter/_logger/_logger.py b/pytablewriter/_logger/_logger.py index 2d213966..81e62580 100644 --- a/pytablewriter/_logger/_logger.py +++ b/pytablewriter/_logger/_logger.py @@ -2,7 +2,7 @@ .. codeauthor:: Tsuyoshi Hombashi """ -from typing import TYPE_CHECKING, List +from typing import TYPE_CHECKING import dataproperty from mbstrdecoder import MultiByteStrDecoder @@ -102,7 +102,7 @@ def __get_table_name_message(self) -> str: return f"table-name='{table_name}'" - def __get_extra_log_entry_list(self) -> List[str]: + def __get_extra_log_entry_list(self) -> list[str]: if self.__writer._iter_count is None: return [] diff --git a/pytablewriter/_table_format.py b/pytablewriter/_table_format.py index 785a3b4a..f1c5391a 100644 --- a/pytablewriter/_table_format.py +++ b/pytablewriter/_table_format.py @@ -3,7 +3,8 @@ """ import enum -from typing import List, Optional, Sequence +from collections.abc import Sequence +from typing import Optional from .writer import ( AbstractTableWriter, @@ -252,7 +253,7 @@ class TableFormat(enum.Enum): ) @property - def names(self) -> List[str]: + def names(self) -> list[str]: """ List[str]: Names associated with the table format. """ @@ -276,7 +277,7 @@ def format_attribute(self) -> int: return self.__format_attribute @property - def file_extensions(self) -> List[str]: + def file_extensions(self) -> list[str]: """ List[str]: File extensions associated with the table format. """ @@ -296,7 +297,7 @@ def __init__( self.__file_extensions = list(file_extensions) @classmethod - def find_all_attr(cls, format_attribute: int) -> List["TableFormat"]: + def find_all_attr(cls, format_attribute: int) -> list["TableFormat"]: """Searching table formats that have specific attributes. Args: diff --git a/pytablewriter/sanitizer/_base.py b/pytablewriter/sanitizer/_base.py index 459df620..b8ac7d01 100644 --- a/pytablewriter/sanitizer/_base.py +++ b/pytablewriter/sanitizer/_base.py @@ -4,7 +4,7 @@ import abc import re -from typing import Pattern +from re import Pattern from pathvalidate.error import ErrorReason, ValidationError from typepy import is_null_string diff --git a/pytablewriter/sanitizer/_elasticsearch.py b/pytablewriter/sanitizer/_elasticsearch.py index d722e317..9a29d9cc 100644 --- a/pytablewriter/sanitizer/_elasticsearch.py +++ b/pytablewriter/sanitizer/_elasticsearch.py @@ -3,7 +3,8 @@ """ import re -from typing import ClassVar, List, Pattern +from re import Pattern +from typing import ClassVar from ._base import VarNameSanitizer @@ -15,7 +16,7 @@ class ElasticsearchIndexNameSanitizer(VarNameSanitizer): __RE_INVALID_INDEX_NAME_HEAD: ClassVar[Pattern[str]] = re.compile("^[_]+") @property - def reserved_keywords(self) -> List[str]: + def reserved_keywords(self) -> list[str]: return [] @property diff --git a/pytablewriter/sanitizer/_interface.py b/pytablewriter/sanitizer/_interface.py index fefb5612..d8f29b32 100644 --- a/pytablewriter/sanitizer/_interface.py +++ b/pytablewriter/sanitizer/_interface.py @@ -3,14 +3,13 @@ """ import abc -from typing import List from pathvalidate import validate_pathtype class NameSanitizer(metaclass=abc.ABCMeta): @abc.abstractproperty - def reserved_keywords(self) -> List[str]: # pragma: no cover + def reserved_keywords(self) -> list[str]: # pragma: no cover pass @abc.abstractmethod diff --git a/pytablewriter/sanitizer/_javascript.py b/pytablewriter/sanitizer/_javascript.py index 8fe67a65..2877b501 100644 --- a/pytablewriter/sanitizer/_javascript.py +++ b/pytablewriter/sanitizer/_javascript.py @@ -3,7 +3,7 @@ """ import re -from typing import List, Pattern +from re import Pattern from ._base import VarNameSanitizer @@ -78,7 +78,7 @@ class JavaScriptVarNameSanitizer(VarNameSanitizer): __RE_INVALID_VAR_NAME_HEAD = re.compile("^[^a-zA-Z$]+") @property - def reserved_keywords(self) -> List[str]: + def reserved_keywords(self) -> list[str]: return ( self.__JS_RESERVED_KEYWORDS_ES6 + self.__JS_RESERVED_KEYWORDS_FUTURE diff --git a/pytablewriter/sanitizer/_python.py b/pytablewriter/sanitizer/_python.py index 956567ca..659e79a0 100644 --- a/pytablewriter/sanitizer/_python.py +++ b/pytablewriter/sanitizer/_python.py @@ -3,7 +3,7 @@ """ import re -from typing import List, Pattern +from re import Pattern from ._base import VarNameSanitizer @@ -55,7 +55,7 @@ class PythonVarNameSanitizer(VarNameSanitizer): __RE_INVALID_VAR_NAME_HEAD = re.compile("^[^a-zA-Z]+") @property - def reserved_keywords(self) -> List[str]: + def reserved_keywords(self) -> list[str]: return self.__PYTHON_RESERVED_KEYWORDS + self.__PYTHON_BUILTIN_CONSTANTS @property diff --git a/pytablewriter/style/_style.py b/pytablewriter/style/_style.py index d360c5a7..96308a9d 100644 --- a/pytablewriter/style/_style.py +++ b/pytablewriter/style/_style.py @@ -1,6 +1,6 @@ import warnings from enum import Enum, unique -from typing import Any, Dict, Optional, Union +from typing import Any, Optional, Union from dataproperty import Align from tcolorpy import Color @@ -45,7 +45,7 @@ def __init__(self, code: int, string: str) -> None: self.__align_string = string -_s_to_ts: Dict[str, ThousandSeparator] = { +_s_to_ts: dict[str, ThousandSeparator] = { "": ThousandSeparator.NONE, ",": ThousandSeparator.COMMA, " ": ThousandSeparator.SPACE, diff --git a/pytablewriter/style/_styler.py b/pytablewriter/style/_styler.py index 3f8ff5b0..b753850e 100644 --- a/pytablewriter/style/_styler.py +++ b/pytablewriter/style/_styler.py @@ -1,5 +1,5 @@ import re -from typing import TYPE_CHECKING, Any, Dict, Optional +from typing import TYPE_CHECKING, Any, Optional from dataproperty import Align from tcolorpy import Color, tcolor @@ -13,7 +13,7 @@ from ..writer._table_writer import AbstractTableWriter -_align_char_mapping: Dict[Align, str] = { +_align_char_mapping: dict[Align, str] = { Align.AUTO: "<", Align.LEFT: "<", Align.RIGHT: ">", @@ -49,7 +49,7 @@ def apply_align(self, value: str, style: Style) -> str: def apply_terminal_style(self, value: str, style: Style) -> str: return value - def _get_font_size_map(self) -> Dict[FontSize, str]: + def _get_font_size_map(self) -> dict[FontSize, str]: return {} @@ -101,7 +101,7 @@ def apply(self, value: str, style: Style) -> str: class HtmlStyler(TextStyler): - def _get_font_size_map(self) -> Dict[FontSize, str]: + def _get_font_size_map(self) -> dict[FontSize, str]: return { FontSize.TINY: "font-size:x-small", FontSize.SMALL: "font-size:small", @@ -163,7 +163,7 @@ def __apply_color(self, value: str, style: Style) -> str: return value - def _get_font_size_map(self) -> Dict[FontSize, str]: + def _get_font_size_map(self) -> dict[FontSize, str]: return { FontSize.TINY: r"\tiny", FontSize.SMALL: r"\small", diff --git a/pytablewriter/style/_theme.py b/pytablewriter/style/_theme.py index a44ddb00..f8f235e8 100644 --- a/pytablewriter/style/_theme.py +++ b/pytablewriter/style/_theme.py @@ -1,7 +1,8 @@ import importlib import pkgutil import re -from typing import Any, Dict, NamedTuple, Optional, Sequence +from collections.abc import Sequence +from typing import Any, NamedTuple, Optional from .._logger import logger from ..style import Cell, Style @@ -45,7 +46,7 @@ def list_themes() -> Sequence[str]: return list(load_ptw_plugins()) -def load_ptw_plugins() -> Dict[str, Theme]: +def load_ptw_plugins() -> dict[str, Theme]: plugin_regexp = re.compile( rf"^{PLUGIN_NAME_PEFIX}[_-].+[_-]{PLUGIN_NAME_SUFFIX}", re.IGNORECASE ) @@ -58,7 +59,7 @@ def load_ptw_plugins() -> Dict[str, Theme]: logger.debug(f"discovered_plugins: {list(discovered_plugins)}") - themes: Dict[str, Theme] = {} + themes: dict[str, Theme] = {} for theme, plugin in discovered_plugins.items(): style_filter = plugin.style_filter if hasattr(plugin, "style_filter") else None col_sep_style_filter = ( diff --git a/pytablewriter/writer/_elasticsearch.py b/pytablewriter/writer/_elasticsearch.py index b19b97e8..51a7011f 100644 --- a/pytablewriter/writer/_elasticsearch.py +++ b/pytablewriter/writer/_elasticsearch.py @@ -3,7 +3,8 @@ """ import copy -from typing import Any, Dict, Generator +from collections.abc import Generator +from typing import Any import dataproperty from dataproperty import ColumnDataProperty @@ -14,8 +15,8 @@ from ._table_writer import AbstractTableWriter -DataType = Dict[str, str] -Properties = Dict[str, DataType] +DataType = dict[str, str] +Properties = dict[str, DataType] def _get_es_datatype(column_dp: ColumnDataProperty) -> DataType: @@ -148,7 +149,7 @@ def __init__(self, **kwargs: Any) -> None: def write_null_line(self) -> None: pass - def _get_mappings(self) -> Dict[str, Dict[str, Dict[str, Properties]]]: + def _get_mappings(self) -> dict[str, dict[str, dict[str, Properties]]]: properties: Properties = {} for header, column_dp in zip(self.headers, self._column_dp_list): diff --git a/pytablewriter/writer/_table_writer.py b/pytablewriter/writer/_table_writer.py index 7c6ed20b..62770722 100644 --- a/pytablewriter/writer/_table_writer.py +++ b/pytablewriter/writer/_table_writer.py @@ -6,7 +6,8 @@ import copy import math import warnings -from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Sequence, Union, cast +from collections.abc import Mapping, Sequence +from typing import TYPE_CHECKING, Any, Optional, Union, cast import typepy from dataproperty import ( @@ -46,7 +47,7 @@ from .._table_format import TableFormat -_ts_to_flag: Dict[ThousandSeparator, int] = { +_ts_to_flag: dict[ThousandSeparator, int] = { ThousandSeparator.NONE: Format.NONE, ThousandSeparator.COMMA: Format.THOUSAND_SEPARATOR, ThousandSeparator.SPACE: Format.THOUSAND_SEPARATOR, @@ -61,7 +62,7 @@ def header_style_filter(cell: Cell, **kwargs: Any) -> Optional[Style]: return None -DEFAULT_STYLE_FILTERS: List[StyleFilterFunc] = [header_style_filter] +DEFAULT_STYLE_FILTERS: list[StyleFilterFunc] = [header_style_filter] class AbstractTableWriter(TableWriterInterface, metaclass=abc.ABCMeta): @@ -235,14 +236,14 @@ def __init__(self, **kwargs: Any) -> None: self.__default_style: Style self.default_style = kwargs.get("default_style", Style()) - self.__col_style_list: List[Optional[Style]] = [] + self.__col_style_list: list[Optional[Style]] = [] self.column_styles = kwargs.get("column_styles", []) - self._style_filters: List[StyleFilterFunc] = copy.deepcopy(DEFAULT_STYLE_FILTERS) + self._style_filters: list[StyleFilterFunc] = copy.deepcopy(DEFAULT_STYLE_FILTERS) self._enable_style_filter = True self._styler = self._create_styler(self) - self.style_filter_kwargs: Dict[str, Any] = kwargs.get("style_filter_kwargs", {}) - self._check_style_filter_kwargs_funcs: List[CheckStyleFilterKeywordArgsFunc] = [] + self.style_filter_kwargs: dict[str, Any] = kwargs.get("style_filter_kwargs", {}) + self._check_style_filter_kwargs_funcs: list[CheckStyleFilterKeywordArgsFunc] = [] self.__colorize_terminal = kwargs.get("colorize_terminal", True) self.__enable_ansi_escape = kwargs.get("enable_ansi_escape", True) @@ -279,9 +280,9 @@ def __clear_preprocess_status(self) -> None: self._is_complete_value_matrix_preprocess = False def __clear_preprocess_data(self) -> None: - self._column_dp_list: List[ColumnDataProperty] = [] - self._table_headers: List[str] = [] - self._table_value_matrix: List[Union[List[str], Dict]] = [] + self._column_dp_list: list[ColumnDataProperty] = [] + self._table_headers: list[str] = [] + self._table_value_matrix: list[Union[list[str], dict]] = [] self._table_value_dp_matrix: Sequence[Sequence[DataProperty]] = [] @property @@ -337,7 +338,7 @@ def table_name(self, value: str) -> None: self._table_name = value @property - def type_hints(self) -> List[TypeHint]: + def type_hints(self) -> list[TypeHint]: """ Type hints for each column of the tabular data. Writers convert data for each column using the type hints information @@ -414,7 +415,7 @@ def default_style(self, style: Optional[Style]) -> None: self.__clear_preprocess() @property - def column_styles(self) -> List[Optional[Style]]: + def column_styles(self) -> list[Optional[Style]]: """List[Optional[Style]]: |Style| for each column.""" return self.__col_style_list @@ -461,7 +462,7 @@ def enable_ansi_escape(self, value: bool) -> None: self.__clear_preprocess() @property - def _quoting_flags(self) -> Dict[Typecode, bool]: + def _quoting_flags(self) -> dict[Typecode, bool]: return self._dp_extractor.quoting_flags @_quoting_flags.setter diff --git a/pytablewriter/writer/binary/_excel.py b/pytablewriter/writer/binary/_excel.py index 22fedc16..4c19293b 100644 --- a/pytablewriter/writer/binary/_excel.py +++ b/pytablewriter/writer/binary/_excel.py @@ -1,7 +1,7 @@ import abc import copy import warnings -from typing import IO, TYPE_CHECKING, Any, ClassVar, Dict, Optional, Union, cast +from typing import IO, TYPE_CHECKING, Any, ClassVar, Optional, Union, cast import dataproperty import typepy @@ -256,7 +256,7 @@ class ExcelXlsTableWriter(ExcelTableWriter): def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) - self.__col_style_table: Dict[int, Any] = {} + self.__col_style_table: dict[int, Any] = {} def _open(self, workbook_path: str) -> None: self._workbook = ExcelWorkbookXls(workbook_path) @@ -349,7 +349,7 @@ class Default: FONT_NAME: ClassVar[str] = "MS Gothic" FONT_SIZE: ClassVar[int] = 9 - CELL_FORMAT: Dict[str, Union[int, str, bool]] = { + CELL_FORMAT: dict[str, Union[int, str, bool]] = { "font_name": FONT_NAME, "font_size": FONT_SIZE, "align": "top", @@ -359,7 +359,7 @@ class Default: "bottom": 1, "right": 1, } - HEADER_FORMAT: Dict[str, Union[int, str, bool]] = { + HEADER_FORMAT: dict[str, Union[int, str, bool]] = { "font_name": FONT_NAME, "font_size": FONT_SIZE, "bg_color": "#DFDFFF", @@ -367,7 +367,7 @@ class Default: "left": 1, "right": 1, } - NAN_FORMAT: Dict[str, Union[int, str, bool]] = { + NAN_FORMAT: dict[str, Union[int, str, bool]] = { "font_name": FONT_NAME, "font_size": FONT_SIZE, "font_color": "silver", @@ -378,11 +378,11 @@ class Default: } @property - def __nan_format_property(self) -> Dict[str, Union[int, str, bool]]: + def __nan_format_property(self) -> dict[str, Union[int, str, bool]]: return self.format_table.get(self.TableFormat.NAN, self.default_format) @property - def __cell_format_property(self) -> Dict[str, Union[int, str, bool]]: + def __cell_format_property(self) -> dict[str, Union[int, str, bool]]: return self.format_table.get(self.TableFormat.CELL, self.default_format) def __init__(self, **kwargs: Any) -> None: @@ -395,8 +395,8 @@ def __init__(self, **kwargs: Any) -> None: self.TableFormat.NAN: self.Default.NAN_FORMAT, } - self.__col_cell_format_cache: Dict[int, Any] = {} - self.__col_numprops_table: Dict[int, Dict[str, str]] = {} + self.__col_cell_format_cache: dict[int, Any] = {} + self.__col_numprops_table: dict[int, dict[str, str]] = {} def _open(self, workbook_path: str) -> None: self._workbook = ExcelWorkbookXlsx(workbook_path) @@ -437,7 +437,7 @@ def _write_cell(self, row: int, col: int, value_dp: DataProperty) -> None: cell_format = self.__get_cell_format(format_key, base_props) self.stream.write(row, col, value_dp.data, cell_format) - def __get_number_property(self, col: int) -> Dict[str, str]: + def __get_number_property(self, col: int) -> dict[str, str]: if col in self.__col_numprops_table: return self.__col_numprops_table[col] @@ -459,7 +459,7 @@ def __get_number_property(self, col: int) -> Dict[str, str]: return num_props - def __get_cell_format(self, format_key, cell_props) -> Dict: # type: ignore + def __get_cell_format(self, format_key, cell_props) -> dict: # type: ignore cell_format = self.__col_cell_format_cache.get(format_key) if cell_format is not None: return cell_format diff --git a/pytablewriter/writer/binary/_excel_workbook.py b/pytablewriter/writer/binary/_excel_workbook.py index 6da2a86a..f1a25b83 100644 --- a/pytablewriter/writer/binary/_excel_workbook.py +++ b/pytablewriter/writer/binary/_excel_workbook.py @@ -1,6 +1,6 @@ import abc import warnings -from typing import Any, Dict, Optional +from typing import Any, Optional import typepy @@ -44,7 +44,7 @@ def file_path(self) -> Optional[str]: def _clear(self) -> None: self._workbook = None self._file_path: Optional[str] = None - self._worksheet_table: Dict[str, Any] = {} + self._worksheet_table: dict[str, Any] = {} def __init__(self, file_path: str) -> None: self._clear() diff --git a/pytablewriter/writer/text/_asciidoc.py b/pytablewriter/writer/text/_asciidoc.py index 1294da3d..f893b35f 100644 --- a/pytablewriter/writer/text/_asciidoc.py +++ b/pytablewriter/writer/text/_asciidoc.py @@ -1,5 +1,6 @@ import copy -from typing import Any, List, Sequence +from collections.abc import Sequence +from typing import Any import dataproperty as dp import typepy @@ -95,7 +96,7 @@ def _write_value_row( ], ) - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: cols = ", ".join( f"{get_align_char(col_dp.align)}{col_dp.ascii_char_width}" for col_dp in self._column_dp_list @@ -109,13 +110,13 @@ def _get_opening_row_items(self) -> List[str]: return ["\n".join(rows)] - def _get_header_row_separator_items(self) -> List[str]: + def _get_header_row_separator_items(self) -> list[str]: return [""] - def _get_value_row_separator_items(self) -> List[str]: + def _get_value_row_separator_items(self) -> list[str]: return self._get_header_row_separator_items() - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: return ["|==="] def __apply_align(self, value: str, style: Style) -> str: diff --git a/pytablewriter/writer/text/_css.py b/pytablewriter/writer/text/_css.py index 6d9b4931..0044cd1f 100644 --- a/pytablewriter/writer/text/_css.py +++ b/pytablewriter/writer/text/_css.py @@ -1,5 +1,5 @@ import copy -from typing import Any, List, cast +from typing import Any, cast from dataproperty import NOT_QUOTING_FLAGS, DataProperty from pathvalidate import replace_symbol @@ -54,8 +54,8 @@ def write_table(self, **kwargs: Any) -> None: write_style_tag=kwargs.get("write_style_tag", False), ) - def __extract_css_tags(self, value_dp: DataProperty, style: Style) -> List[str]: - css_tags: List[str] = [] + def __extract_css_tags(self, value_dp: DataProperty, style: Style) -> list[str]: + css_tags: list[str] = [] if self._styler.get_font_size(style): css_tags.append(cast(str, self._styler.get_font_size(style))) diff --git a/pytablewriter/writer/text/_csv.py b/pytablewriter/writer/text/_csv.py index 01154946..0013b794 100644 --- a/pytablewriter/writer/text/_csv.py +++ b/pytablewriter/writer/text/_csv.py @@ -1,4 +1,4 @@ -from typing import Any, List +from typing import Any import typepy @@ -53,11 +53,11 @@ def _write_header(self) -> None: super()._write_header() - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: return [] - def _get_value_row_separator_items(self) -> List[str]: + def _get_value_row_separator_items(self) -> list[str]: return [] - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: return [] diff --git a/pytablewriter/writer/text/_html.py b/pytablewriter/writer/text/_html.py index 748989d3..761c3b27 100644 --- a/pytablewriter/writer/text/_html.py +++ b/pytablewriter/writer/text/_html.py @@ -1,6 +1,6 @@ import copy import warnings -from typing import Any, List, Optional, Tuple, cast +from typing import Any, Optional, cast import dataproperty import typepy @@ -16,7 +16,7 @@ from ._text_writer import TextTableWriter -def _get_tags_module() -> Tuple: +def _get_tags_module() -> tuple: try: from dominate import tags from dominate.util import raw @@ -176,7 +176,7 @@ def _write_body(self, write_attr: bool) -> None: self._write_line(self._table_tag.render(indent=self.indent_string)) def __make_style_tag(self, style: Style) -> Optional[str]: - styles: List[str] = [] + styles: list[str] = [] if self._styler.get_font_size(style): styles.append(cast(str, self._styler.get_font_size(style))) diff --git a/pytablewriter/writer/text/_json.py b/pytablewriter/writer/text/_json.py index ccb1e687..ea708794 100644 --- a/pytablewriter/writer/text/_json.py +++ b/pytablewriter/writer/text/_json.py @@ -1,6 +1,6 @@ import copy from textwrap import indent -from typing import Any, List +from typing import Any import dataproperty import typepy @@ -154,13 +154,13 @@ def _preprocess_value_matrix(self) -> None: self._is_complete_value_matrix_preprocess = True - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: if typepy.is_not_null_string(self.table_name): return [f'{{ "{MultiByteStrDecoder(self.table_name).unicode_str:s}" : ['] return ["["] - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: if typepy.is_not_null_string(self.table_name): return ["\n]}"] diff --git a/pytablewriter/writer/text/_latex.py b/pytablewriter/writer/text/_latex.py index 884c8b6b..cce1c4a2 100644 --- a/pytablewriter/writer/text/_latex.py +++ b/pytablewriter/writer/text/_latex.py @@ -1,6 +1,6 @@ import copy import re -from typing import Any, List +from typing import Any import dataproperty as dp import typepy @@ -50,7 +50,7 @@ def _is_math_parts(self, value_dp: DataProperty) -> bool: return False - def _get_col_align_char_list(self) -> List[str]: + def _get_col_align_char_list(self) -> list[str]: col_align_list = [] for col_dp in self._column_dp_list: @@ -127,10 +127,10 @@ def _to_row_item(self, row_idx: int, col_dp: ColumnDataProperty, value_dp: DataP return row_item - def _get_header_row_separator_items(self) -> List[str]: + def _get_header_row_separator_items(self) -> list[str]: return [] - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: row_item_list = [] if typepy.is_not_null_string(self.table_name): @@ -144,7 +144,7 @@ def _get_opening_row_items(self) -> List[str]: return ["".join(row_item_list)] - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: return [r"\end{array} \right)"] def _write_opening_row(self) -> None: @@ -185,7 +185,7 @@ def __init__(self, **kwargs: Any) -> None: self.char_right_side_row = r" \\ \hline" self._dp_extractor.type_value_map[Typecode.INFINITY] = r"\infty" - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: return [ "".join( [ @@ -219,8 +219,8 @@ def _to_row_item(self, row_idx: int, col_dp: ColumnDataProperty, value_dp: DataP return row_item - def _get_header_row_separator_items(self) -> List[str]: + def _get_header_row_separator_items(self) -> list[str]: return [r"\hline"] - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: return [r"\end{array}"] diff --git a/pytablewriter/writer/text/_markdown.py b/pytablewriter/writer/text/_markdown.py index d87963b9..3aa2d2ac 100644 --- a/pytablewriter/writer/text/_markdown.py +++ b/pytablewriter/writer/text/_markdown.py @@ -1,6 +1,6 @@ import copy from enum import Enum, unique -from typing import Any, List, Union +from typing import Any, Union import dataproperty as dp import typepy @@ -89,10 +89,10 @@ def _to_header_item(self, col_dp: ColumnDataProperty, value_dp: DataProperty) -> def _to_row_item(self, row_idx: int, col_dp: ColumnDataProperty, value_dp: DataProperty) -> str: return self.__escape_vertical_bar_char(super()._to_row_item(row_idx, col_dp, value_dp)) - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: return [] - def _get_header_row_separator_items(self) -> List[str]: + def _get_header_row_separator_items(self) -> list[str]: header_separator_list = [] margin = " " * self.margin @@ -113,10 +113,10 @@ def _get_header_row_separator_items(self) -> List[str]: return header_separator_list - def _get_value_row_separator_items(self) -> List[str]: + def _get_value_row_separator_items(self) -> list[str]: return [] - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: return [] def _write_header(self) -> None: diff --git a/pytablewriter/writer/text/_mediawiki.py b/pytablewriter/writer/text/_mediawiki.py index 95c622e7..a2ced25b 100644 --- a/pytablewriter/writer/text/_mediawiki.py +++ b/pytablewriter/writer/text/_mediawiki.py @@ -1,6 +1,7 @@ import copy import re -from typing import Any, List, Sequence +from collections.abc import Sequence +from typing import Any import dataproperty as dp import typepy @@ -68,20 +69,20 @@ def _write_value_row( ], ) - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: item = '{| class="wikitable"' if self.table_style: item += f' style="{self.table_style}"' return [item] - def _get_header_row_separator_items(self) -> List[str]: + def _get_header_row_separator_items(self) -> list[str]: return ["|-"] - def _get_value_row_separator_items(self) -> List[str]: + def _get_value_row_separator_items(self) -> list[str]: return self._get_header_row_separator_items() - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: return ["|}"] def _apply_style_to_header_item( diff --git a/pytablewriter/writer/text/_rst.py b/pytablewriter/writer/text/_rst.py index 5409d09c..92f19a69 100644 --- a/pytablewriter/writer/text/_rst.py +++ b/pytablewriter/writer/text/_rst.py @@ -1,5 +1,5 @@ import copy -from typing import Any, List +from typing import Any import dataproperty import typepy @@ -118,7 +118,7 @@ def write_table(self, **kwargs: Any) -> None: IndentationTextTableWriter.write_table(self, **kwargs) - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: directive = ".. csv-table::" if typepy.is_null_string(self.table_name): @@ -147,10 +147,10 @@ def _write_header(self) -> None: ) self._write_line() - def _get_value_row_separator_items(self) -> List[str]: + def _get_value_row_separator_items(self) -> list[str]: return [] - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: return [] diff --git a/pytablewriter/writer/text/_text_writer.py b/pytablewriter/writer/text/_text_writer.py index 88f90921..65bda5c5 100644 --- a/pytablewriter/writer/text/_text_writer.py +++ b/pytablewriter/writer/text/_text_writer.py @@ -1,8 +1,9 @@ import enum import io import sys +from collections.abc import Sequence from itertools import chain -from typing import IO, Any, List, Optional, Sequence, Union, cast +from typing import IO, Any, Optional, Union, cast import typepy from dataproperty import ColumnDataProperty, DataProperty, LineBreakHandling @@ -144,7 +145,7 @@ def __init__(self, **kwargs: Any) -> None: self._init_cross_point_maps() - self._col_separator_style_filters: List[ColSeparatorStyleFilterFunc] = [] + self._col_separator_style_filters: list[ColSeparatorStyleFilterFunc] = [] if "theme" in kwargs: self.set_theme(kwargs["theme"]) @@ -366,29 +367,29 @@ def _write_table(self, **kwargs: Any) -> None: if self.is_write_value_separator_row: self._write_value_row_separator() - self._write_value_row(row, cast(List[str], values), value_dp_list) + self._write_value_row(row, cast(list[str], values), value_dp_list) except TypeError: continue self._write_closing_row() - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: return self.__get_row_separator_items(self.__opening_row_cell_format, self.char_opening_row) - def _get_header_row_separator_items(self) -> List[str]: + def _get_header_row_separator_items(self) -> list[str]: return self.__get_row_separator_items( self._header_row_separator_cell_format, self.char_header_row_separator ) - def _get_value_row_separator_items(self) -> List[str]: + def _get_value_row_separator_items(self) -> list[str]: return self.__get_row_separator_items( self.__value_row_separator_cell_format, self.char_value_row_separator ) - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: return self.__get_row_separator_items(self.__closing_row_cell_format, self.char_closing_row) - def __get_row_separator_items(self, margin_format: str, separator_char: str) -> List[str]: + def __get_row_separator_items(self, margin_format: str, separator_char: str) -> list[str]: return [ margin_format.format(separator_char * self._get_padding_len(col_dp)) for col_dp in self._column_dp_list diff --git a/pytablewriter/writer/text/_yaml.py b/pytablewriter/writer/text/_yaml.py index 6d814505..03027d18 100644 --- a/pytablewriter/writer/text/_yaml.py +++ b/pytablewriter/writer/text/_yaml.py @@ -1,6 +1,6 @@ import copy import warnings -from typing import Any, Dict, List, Union +from typing import Any, Union import dataproperty @@ -55,7 +55,7 @@ def write_table(self, **kwargs: Any) -> None: self._preprocess() if self.headers: - matrix: List[Union[Dict[str, Any], List[Any]]] = [ + matrix: list[Union[dict[str, Any], list[Any]]] = [ dict(zip(self.headers, [serialize_dp(value_dp) for value_dp in value_dp_list])) for value_dp_list in self._table_value_dp_matrix ] diff --git a/pytablewriter/writer/text/sourcecode/_javascript.py b/pytablewriter/writer/text/sourcecode/_javascript.py index ffc90ccd..6f355251 100644 --- a/pytablewriter/writer/text/sourcecode/_javascript.py +++ b/pytablewriter/writer/text/sourcecode/_javascript.py @@ -1,6 +1,6 @@ import io from datetime import datetime -from typing import Any, List +from typing import Any from dataproperty import ColumnDataProperty, DataProperty, DefaultValue from typepy import StrictLevel, Typecode @@ -124,10 +124,10 @@ def _write_table(self, **kwargs: Any) -> None: self._write_line(js_matrix_var_def_text) self.inc_indent_level() - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: return [f"{self.variable_declaration:s} {self.variable_name:s} = ["] - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: return ["];"] def _to_row_item(self, row_idx: int, col_dp: ColumnDataProperty, value_dp: DataProperty) -> str: diff --git a/pytablewriter/writer/text/sourcecode/_numpy.py b/pytablewriter/writer/text/sourcecode/_numpy.py index 4a4741bc..20c237b1 100644 --- a/pytablewriter/writer/text/sourcecode/_numpy.py +++ b/pytablewriter/writer/text/sourcecode/_numpy.py @@ -1,4 +1,4 @@ -from typing import Any, List +from typing import Any import typepy @@ -54,7 +54,7 @@ def __init__(self, **kwargs: Any) -> None: self.import_numpy_as ) - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: array_def = f"{self.import_numpy_as:s}.array([" if typepy.is_not_null_string(self.table_name): @@ -62,5 +62,5 @@ def _get_opening_row_items(self) -> List[str]: return [array_def] - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: return ["])"] diff --git a/pytablewriter/writer/text/sourcecode/_pandas.py b/pytablewriter/writer/text/sourcecode/_pandas.py index bfddee73..efea8f4e 100644 --- a/pytablewriter/writer/text/sourcecode/_pandas.py +++ b/pytablewriter/writer/text/sourcecode/_pandas.py @@ -1,4 +1,4 @@ -from typing import Any, List +from typing import Any import typepy from mbstrdecoder import MultiByteStrDecoder @@ -64,10 +64,10 @@ def __init__(self, **kwargs: Any) -> None: self.import_pandas_as = "pd" self.is_write_header = False - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: return [f"{self.variable_name} = {self.import_pandas_as}.DataFrame(["] - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: if typepy.is_not_empty_sequence(self.headers): return [ "], columns=[{}])".format( diff --git a/pytablewriter/writer/text/sourcecode/_python.py b/pytablewriter/writer/text/sourcecode/_python.py index aa1e25ee..ad729621 100644 --- a/pytablewriter/writer/text/sourcecode/_python.py +++ b/pytablewriter/writer/text/sourcecode/_python.py @@ -1,4 +1,4 @@ -from typing import Any, List +from typing import Any import typepy @@ -71,11 +71,11 @@ def _write_table(self, **kwargs: Any) -> None: super()._write_table(**kwargs) self.dec_indent_level() - def _get_opening_row_items(self) -> List[str]: + def _get_opening_row_items(self) -> list[str]: if typepy.is_not_null_string(self.table_name): return [self.variable_name + " = ["] return ["["] - def _get_closing_row_items(self) -> List[str]: + def _get_closing_row_items(self) -> list[str]: return ["]"] diff --git a/pytablewriter/writer/text/sourcecode/_sourcecode.py b/pytablewriter/writer/text/sourcecode/_sourcecode.py index 721a656a..0a5cb2d0 100644 --- a/pytablewriter/writer/text/sourcecode/_sourcecode.py +++ b/pytablewriter/writer/text/sourcecode/_sourcecode.py @@ -1,5 +1,5 @@ import abc -from typing import Any, List +from typing import Any import typepy @@ -65,7 +65,7 @@ def __init__(self, **kwargs: Any) -> None: self._init_cross_point_maps() - def _get_value_row_separator_items(self) -> List[str]: + def _get_value_row_separator_items(self) -> list[str]: return [] def _write_opening_row(self) -> None: diff --git a/setup.py b/setup.py index 2259bec6..ca79762e 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,6 @@ """ import os.path -from typing import Dict, Type import setuptools @@ -13,10 +12,10 @@ REQUIREMENT_DIR = "requirements" ENCODING = "utf8" -pkg_info: Dict[str, str] = {} +pkg_info: dict[str, str] = {} -def get_release_command_class() -> Dict[str, Type[setuptools.Command]]: +def get_release_command_class() -> dict[str, type[setuptools.Command]]: try: from releasecmd import ReleaseCommand except ImportError: @@ -112,7 +111,7 @@ def get_release_command_class() -> Dict[str, Type[setuptools.Command]]: "Source": REPOSITORY_URL, "Tracker": f"{REPOSITORY_URL:s}/issues", }, - python_requires=">=3.7", + python_requires=">=3.9", install_requires=setuptools_require + install_requires, setup_requires=setuptools_require, extras_require={ @@ -138,12 +137,11 @@ def get_release_command_class() -> Dict[str, Type[setuptools.Command]]: "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", diff --git a/test/writer/text/test_json_writer.py b/test/writer/text/test_json_writer.py index 03f5764c..27d8be20 100644 --- a/test/writer/text/test_json_writer.py +++ b/test/writer/text/test_json_writer.py @@ -4,8 +4,6 @@ import collections import json -import platform as m_platform -import sys from textwrap import dedent import pytest @@ -253,9 +251,6 @@ def test_normal(self, capsys, table, header, value, expected): print_test_result(expected=out, actual=dumps_out) assert dumps_out == out - @pytest.mark.skipif( - m_platform.system() == "Windows" and sys.version_info < (3, 6), reason="env dependent tests" - ) def test_normal_sort_keys(self): writer = table_writer_class() writer.headers = ["z", "i"] diff --git a/tox.ini b/tox.ini index de1fa8a0..2077ca4e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] skip_missing_interpreters = true envlist = - py{37,38,39,310,311,312} + py{39,310,311,312,313} pypy3 build cov