diff --git a/src/caosadvancedtools/table_json_conversion/convert.py b/src/caosadvancedtools/table_json_conversion/convert.py index 807519b5a3ddf02a464e741e799aa3a402c0db95..0d7be9ef9486a4ab2a5b202130ff47ec0f6f1547 100644 --- a/src/caosadvancedtools/table_json_conversion/convert.py +++ b/src/caosadvancedtools/table_json_conversion/convert.py @@ -20,11 +20,13 @@ """Convert XLSX files to JSON dictionaries.""" +from __future__ import annotations + from collections import OrderedDict from functools import reduce from operator import getitem from types import SimpleNamespace -from typing import Any, BinaryIO, Dict, List, Optional, TextIO, Union +from typing import Any, BinaryIO, Optional, TextIO, Union import caosadvancedtools.table_json_conversion.xlsx_utils as xlsx_utils diff --git a/src/caosadvancedtools/table_json_conversion/fill_xlsx.py b/src/caosadvancedtools/table_json_conversion/fill_xlsx.py index 8019fb4440b361a5ac8623322df0e388375c4ece..66495584f611d76a2c2e7a661e046dee68681d2d 100644 --- a/src/caosadvancedtools/table_json_conversion/fill_xlsx.py +++ b/src/caosadvancedtools/table_json_conversion/fill_xlsx.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # encoding: utf-8 # # This file is a part of the LinkAhead Project. @@ -19,12 +18,13 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. +"""Class and function to fill an XLSX template from actual data.""" from __future__ import annotations import pathlib from types import SimpleNamespace -from typing import Any, Dict, List, Optional, TextIO, Union +from typing import Any, Optional, TextIO, Union from warnings import warn from jsonschema import FormatChecker, validate @@ -74,7 +74,7 @@ class TemplateFiller: """ - def __init__(self, current_path: List[str] = None, props: Dict[str, Any] = None): + def __init__(self, current_path: list[str] = None, props: dict[str, Any] = None): self._current_path = current_path if current_path is not None else [] self._props = props if props is not None else {} # this is flat @@ -90,7 +90,7 @@ class TemplateFiller: result._current_path.append(next_level) # pylint: disable=protected-access return result - def __getitem__(self, path: Union[List[str], str], owner=None) -> Any: + def __getitem__(self, path: Union[list[str], str], owner=None) -> Any: if isinstance(path, list): path = p2s(path) return self._props[path] @@ -99,7 +99,7 @@ class TemplateFiller: fullpath = p2s(self._current_path + [propname]) self._props[fullpath] = value - def fill_from_data(self, data: Dict[str, Any]): + def fill_from_data(self, data: dict[str, Any]): # TODO recursive for dicts and list? """Fill current level with all scalar elements of ``data``.""" for name, value in data.items(): @@ -152,10 +152,10 @@ class TemplateFiller: sheetname=sheetname, sheet=sheet, col_index=col_idx, col_type=col[coltype_idx].value) - def _handle_data(self, data: dict, current_path: List[str] = None, + def _handle_data(self, data: dict, current_path: list[str] = None, context: TemplateFiller.Context = None, only_collect_insertables: bool = False, - ) -> Optional[Dict[str, Any]]: + ) -> Optional[dict[str, Any]]: """Handle the data and write it into ``workbook``. Parameters @@ -190,7 +190,7 @@ out: union[dict, None] context = TemplateFiller.Context() context.fill_from_data(data) - insertables: Dict[str, Any] = {} + insertables: dict[str, Any] = {} for name, content in data.items(): # TODO is this the best way to do it???? if name == "file": diff --git a/src/caosadvancedtools/table_json_conversion/table_generator.py b/src/caosadvancedtools/table_json_conversion/table_generator.py index 851173e2d51acec0da1e7a5f1f776bcef8db0f97..39aa62508a386e59091323086fd088ad28f3bddb 100644 --- a/src/caosadvancedtools/table_json_conversion/table_generator.py +++ b/src/caosadvancedtools/table_json_conversion/table_generator.py @@ -24,10 +24,12 @@ This module allows to generate template tables from JSON schemas. """ +from __future__ import annotations + import pathlib import re from abc import ABC, abstractmethod -from typing import Dict, List, Optional, Tuple +from typing import Optional from openpyxl import Workbook from openpyxl.styles import PatternFill @@ -72,8 +74,8 @@ class TableTemplateGenerator(ABC): """ def _generate_sheets_from_schema(self, schema: dict, foreign_keys: Optional[dict] = None - ) -> Dict[str, Dict[str, - Tuple[ColumnType, Optional[str], list]]]: + ) -> dict[str, dict[str, + tuple[ColumnType, Optional[str], list]]]: """Generate a sheet definition from a given JSON schema. Parameters @@ -112,7 +114,7 @@ class TableTemplateGenerator(ABC): foreign_keys = {} # here, we treat the top level # sheets[sheetname][colname]= (COL_TYPE, description, [path]) - sheets: Dict[str, Dict[str, Tuple[ColumnType, Optional[str], list]]] = {} + sheets: dict[str, dict[str, tuple[ColumnType, Optional[str], list]]] = {} for rt_name, rt_def in schema["properties"].items(): sheets[rt_name] = self._treat_schema_element(schema=rt_def, sheets=sheets, path=[rt_name], foreign_keys=foreign_keys) @@ -132,10 +134,10 @@ class TableTemplateGenerator(ABC): return keys raise ValueError(msg) - def _treat_schema_element(self, schema: dict, sheets: dict, path: List[str], + def _treat_schema_element(self, schema: dict, sheets: dict, path: list[str], foreign_keys: Optional[dict] = None, level_in_sheet_name: int = 1, array_paths: Optional[list] = None - ) -> Dict[str, Tuple[ColumnType, Optional[str], list]]: + ) -> dict[str, tuple[ColumnType, Optional[str], list]]: """Recursively transform elements from the schema into column definitions. ``sheets`` is modified in place. @@ -319,7 +321,7 @@ class XLSXTemplateGenerator(TableTemplateGenerator): return ordered_cols def _create_workbook_from_sheets_def( - self, sheets: Dict[str, Dict[str, Tuple[ColumnType, Optional[str], list]]]): + self, sheets: dict[str, dict[str, tuple[ColumnType, Optional[str], list]]]): """Create and return a nice workbook for the given sheets.""" wb = Workbook() yellowfill = PatternFill(fill_type="solid", fgColor='00FFFFAA') diff --git a/src/caosadvancedtools/table_json_conversion/xlsx_utils.py b/src/caosadvancedtools/table_json_conversion/xlsx_utils.py index 374cdefb70737907839ba0a3339fefad28949340..465e7c9052f2edc873da4b3d3b99ef073938faa8 100644 --- a/src/caosadvancedtools/table_json_conversion/xlsx_utils.py +++ b/src/caosadvancedtools/table_json_conversion/xlsx_utils.py @@ -39,7 +39,7 @@ from collections import OrderedDict from copy import deepcopy from enum import Enum from types import SimpleNamespace -from typing import Dict, List, TextIO, Union +from typing import TextIO, Union from openpyxl import Workbook from openpyxl.worksheet.worksheet import Worksheet @@ -133,7 +133,7 @@ out: dict[str, list[list[str]] return result -def get_data_columns(sheet: Worksheet) -> Dict[str, SimpleNamespace]: +def get_data_columns(sheet: Worksheet) -> dict[str, SimpleNamespace]: """Return the data paths of the worksheet. Returns @@ -164,7 +164,7 @@ out: dict[str, SimpleNamespace] return result -def get_foreign_key_columns(sheet: Worksheet) -> Dict[str, SimpleNamespace]: +def get_foreign_key_columns(sheet: Worksheet) -> dict[str, SimpleNamespace]: """Return the foreign keys of the worksheet. Returns @@ -214,7 +214,7 @@ proper_name: str # longest common path in data colums data_paths = [el.path for el in get_data_columns(sheet).values()] - for ii in range(min([len(path) for path in data_paths])): + for ii in range(min(len(path) for path in data_paths)): components_at_index = {path[ii] for path in data_paths} if len(components_at_index) > 1: break @@ -282,7 +282,7 @@ def next_row_index(sheet: Worksheet) -> int: return sheet.max_row -def p2s(path: List[str]) -> str: +def p2s(path: list[str]) -> str: """Path to string: dot-separated. """ return ".".join(path)