Skip to content
Snippets Groups Projects
Verified Commit a38782fa authored by Daniel Hornung's avatar Daniel Hornung
Browse files

MAINT: Refactored for Py3.9 and later.

parent f71ea5fc
No related branches found
No related tags found
2 merge requests!107Release v0.11.0,!102ENH: XLSX reader
Pipeline #50433 failed
...@@ -20,11 +20,13 @@ ...@@ -20,11 +20,13 @@
"""Convert XLSX files to JSON dictionaries.""" """Convert XLSX files to JSON dictionaries."""
from __future__ import annotations
from collections import OrderedDict from collections import OrderedDict
from functools import reduce from functools import reduce
from operator import getitem from operator import getitem
from types import SimpleNamespace 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 import caosadvancedtools.table_json_conversion.xlsx_utils as xlsx_utils
......
#!/usr/bin/env python3
# encoding: utf-8 # encoding: utf-8
# #
# This file is a part of the LinkAhead Project. # This file is a part of the LinkAhead Project.
...@@ -19,12 +18,13 @@ ...@@ -19,12 +18,13 @@
# #
# You should have received a copy of the GNU Affero General Public License # 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/>. # 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 from __future__ import annotations
import pathlib import pathlib
from types import SimpleNamespace 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 warnings import warn
from jsonschema import FormatChecker, validate from jsonschema import FormatChecker, validate
...@@ -74,7 +74,7 @@ class TemplateFiller: ...@@ -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._current_path = current_path if current_path is not None else []
self._props = props if props is not None else {} # this is flat self._props = props if props is not None else {} # this is flat
...@@ -90,7 +90,7 @@ class TemplateFiller: ...@@ -90,7 +90,7 @@ class TemplateFiller:
result._current_path.append(next_level) # pylint: disable=protected-access result._current_path.append(next_level) # pylint: disable=protected-access
return result 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): if isinstance(path, list):
path = p2s(path) path = p2s(path)
return self._props[path] return self._props[path]
...@@ -99,7 +99,7 @@ class TemplateFiller: ...@@ -99,7 +99,7 @@ class TemplateFiller:
fullpath = p2s(self._current_path + [propname]) fullpath = p2s(self._current_path + [propname])
self._props[fullpath] = value 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? # TODO recursive for dicts and list?
"""Fill current level with all scalar elements of ``data``.""" """Fill current level with all scalar elements of ``data``."""
for name, value in data.items(): for name, value in data.items():
...@@ -152,10 +152,10 @@ class TemplateFiller: ...@@ -152,10 +152,10 @@ class TemplateFiller:
sheetname=sheetname, sheet=sheet, col_index=col_idx, sheetname=sheetname, sheet=sheet, col_index=col_idx,
col_type=col[coltype_idx].value) 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, context: TemplateFiller.Context = None,
only_collect_insertables: bool = False, only_collect_insertables: bool = False,
) -> Optional[Dict[str, Any]]: ) -> Optional[dict[str, Any]]:
"""Handle the data and write it into ``workbook``. """Handle the data and write it into ``workbook``.
Parameters Parameters
...@@ -190,7 +190,7 @@ out: union[dict, None] ...@@ -190,7 +190,7 @@ out: union[dict, None]
context = TemplateFiller.Context() context = TemplateFiller.Context()
context.fill_from_data(data) context.fill_from_data(data)
insertables: Dict[str, Any] = {} insertables: dict[str, Any] = {}
for name, content in data.items(): for name, content in data.items():
# TODO is this the best way to do it???? # TODO is this the best way to do it????
if name == "file": if name == "file":
......
...@@ -24,10 +24,12 @@ ...@@ -24,10 +24,12 @@
This module allows to generate template tables from JSON schemas. This module allows to generate template tables from JSON schemas.
""" """
from __future__ import annotations
import pathlib import pathlib
import re import re
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Dict, List, Optional, Tuple from typing import Optional
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.styles import PatternFill from openpyxl.styles import PatternFill
...@@ -72,8 +74,8 @@ class TableTemplateGenerator(ABC): ...@@ -72,8 +74,8 @@ class TableTemplateGenerator(ABC):
""" """
def _generate_sheets_from_schema(self, schema: dict, foreign_keys: Optional[dict] = None def _generate_sheets_from_schema(self, schema: dict, foreign_keys: Optional[dict] = None
) -> Dict[str, Dict[str, ) -> dict[str, dict[str,
Tuple[ColumnType, Optional[str], list]]]: tuple[ColumnType, Optional[str], list]]]:
"""Generate a sheet definition from a given JSON schema. """Generate a sheet definition from a given JSON schema.
Parameters Parameters
...@@ -112,7 +114,7 @@ class TableTemplateGenerator(ABC): ...@@ -112,7 +114,7 @@ class TableTemplateGenerator(ABC):
foreign_keys = {} foreign_keys = {}
# here, we treat the top level # here, we treat the top level
# sheets[sheetname][colname]= (COL_TYPE, description, [path]) # 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(): for rt_name, rt_def in schema["properties"].items():
sheets[rt_name] = self._treat_schema_element(schema=rt_def, sheets=sheets, sheets[rt_name] = self._treat_schema_element(schema=rt_def, sheets=sheets,
path=[rt_name], foreign_keys=foreign_keys) path=[rt_name], foreign_keys=foreign_keys)
...@@ -132,10 +134,10 @@ class TableTemplateGenerator(ABC): ...@@ -132,10 +134,10 @@ class TableTemplateGenerator(ABC):
return keys return keys
raise ValueError(msg) 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, foreign_keys: Optional[dict] = None, level_in_sheet_name: int = 1,
array_paths: Optional[list] = None 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. """Recursively transform elements from the schema into column definitions.
``sheets`` is modified in place. ``sheets`` is modified in place.
...@@ -319,7 +321,7 @@ class XLSXTemplateGenerator(TableTemplateGenerator): ...@@ -319,7 +321,7 @@ class XLSXTemplateGenerator(TableTemplateGenerator):
return ordered_cols return ordered_cols
def _create_workbook_from_sheets_def( 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.""" """Create and return a nice workbook for the given sheets."""
wb = Workbook() wb = Workbook()
yellowfill = PatternFill(fill_type="solid", fgColor='00FFFFAA') yellowfill = PatternFill(fill_type="solid", fgColor='00FFFFAA')
......
...@@ -39,7 +39,7 @@ from collections import OrderedDict ...@@ -39,7 +39,7 @@ from collections import OrderedDict
from copy import deepcopy from copy import deepcopy
from enum import Enum from enum import Enum
from types import SimpleNamespace from types import SimpleNamespace
from typing import Dict, List, TextIO, Union from typing import TextIO, Union
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.worksheet.worksheet import Worksheet from openpyxl.worksheet.worksheet import Worksheet
...@@ -133,7 +133,7 @@ out: dict[str, list[list[str]] ...@@ -133,7 +133,7 @@ out: dict[str, list[list[str]]
return result 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. """Return the data paths of the worksheet.
Returns Returns
...@@ -164,7 +164,7 @@ out: dict[str, SimpleNamespace] ...@@ -164,7 +164,7 @@ out: dict[str, SimpleNamespace]
return result 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. """Return the foreign keys of the worksheet.
Returns Returns
...@@ -214,7 +214,7 @@ proper_name: str ...@@ -214,7 +214,7 @@ proper_name: str
# longest common path in data colums # longest common path in data colums
data_paths = [el.path for el in get_data_columns(sheet).values()] 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} components_at_index = {path[ii] for path in data_paths}
if len(components_at_index) > 1: if len(components_at_index) > 1:
break break
...@@ -282,7 +282,7 @@ def next_row_index(sheet: Worksheet) -> int: ...@@ -282,7 +282,7 @@ def next_row_index(sheet: Worksheet) -> int:
return sheet.max_row return sheet.max_row
def p2s(path: List[str]) -> str: def p2s(path: list[str]) -> str:
"""Path to string: dot-separated. """Path to string: dot-separated.
""" """
return ".".join(path) return ".".join(path)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment