Repository: deepdoctection/deepdoctection (language: python)

Issue:
No attribute 'legacyVersion' and name 'context' is not defined.
On a fresh install using python3.10 on docker pytorch:2.0.1-cuda11.7-cudnn8-devel i'm encountering two errors... Simply by removing these types and unused variables it resolved it for me.

AttributeError: module 'packaging.version' has no attribute 'legacyVersion'
![image](https://github.com/deepdoctection/deepdoctection/assets/6997299/c1f0ff28-a652-4955-8f2b-8d4fa0ac554b)

NameError: name 'context' is not defined
![image](https://github.com/deepdoctection/deepdoctection/assets/6997299/cc06e1d9-3434-48ee-9e67-56b4d35efd89)

I've created a pull request here: https://github.com/deepdoctection/deepdoctection/pull/177#issue-1795525409


Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 4f0cdcb7..d72d009d 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@ pipelines. Its core function does not depend on any specific deep learning libra
  - There is a small dataset for token classification [available](https://huggingface.co/datasets/deepdoctection/FRFPE)
    and a lot of new [tutorials](https://github.com/deepdoctection/notebooks/blob/main/Layoutlm_v2_on_custom_token_classification.ipynb) 
    to show, how to train and evaluate this dataset using LayoutLMv1, LayoutLMv2, LayoutXLM and LayoutLMv3.
- - [**new!**] Comprehensive configuration of **analyzer** like choosing different models, output parsing, OCR selection.
+ - Comprehensive configuration of **analyzer** like choosing different models, output parsing, OCR selection.
    Check this [notebook](https://github.com/deepdoctection/notebooks/blob/main/Analyzer_Configuration.ipynb) or the 
    [docs](https://deepdoctection.readthedocs.io/en/latest/tutorials/analyzer_configuration_notebook/) for more infos.
    
@@ -133,7 +133,7 @@ separately.
 
 - Linux or macOS. (Windows is not supported but there is a [Dockerfile](./docker/pytorch-cpu-jupyter/Dockerfile) available)
 - Python >= 3.8
-- PyTorch >= 1.8 **or** Tensorflow >= 2.9 and CUDA. If you want to run the models provided by Tensorpack a GPU is
+- 1.8 <= PyTorch < 2.0 **or** Tensorflow >= 2.9 and CUDA. If you want to run the models provided by Tensorpack a GPU is
   required. You can run on PyTorch with a CPU only.
 - **deep**doctection uses Python wrappers for [Poppler](https://poppler.freedesktop.org/) to convert PDF documents into 
 images. 
diff --git a/configs/conf_dd_one.yaml b/configs/conf_dd_one.yaml
index 307ad6eb..7b716ee8 100644
--- a/configs/conf_dd_one.yaml
+++ b/configs/conf_dd_one.yaml
@@ -18,7 +18,7 @@ PT:
         TOP: 60
         RIGHT: 60
         BOTTOM: 60
-        LEFT": 60
+        LEFT: 60
    ITEM:
      WEIGHTS: item/d2_model_1639999_item_inf_only.pt
      FILTER:
@@ -26,7 +26,7 @@ PT:
         TOP: 60
         RIGHT: 60
         BOTTOM: 60
-        LEFT": 60
+        LEFT: 60
    CELL:
       WEIGHTS: cell/d2_model_1849999_cell_inf_only.pt
       FILTER:
diff --git a/deepdoctection/analyzer/dd.py b/deepdoctection/analyzer/dd.py
index 61b307f3..233d5d38 100644
--- a/deepdoctection/analyzer/dd.py
+++ b/deepdoctection/analyzer/dd.py
@@ -111,6 +111,11 @@ def _maybe_copy_config_to_cache(file_name: str, force_copy: bool = True) -> str:
 def _config_sanity_checks(cfg: AttrDict) -> None:
     if cfg.USE_PDF_MINER and cfg.USE_OCR and cfg.OCR.USE_DOCTR:
         raise ValueError("Configuration USE_PDF_MINER= True and USE_OCR=True and USE_DOCTR=True is not allowed")
+    if cfg.OCR.USE_TESSERACT and (cfg.OCR.USE_DOCTR or cfg.OCR.USE_TEXTRACT):
+        raise ValueError(
+            "Configuration OCR.USE_TESSERACT=True and OCR.USE_DOCTR=True or OCR.USE_TEXTRACT=True is not "
+            "allowed. Only one OCR system can be activated."
+        )
 
 
 def _build_detector(cfg: AttrDict, mode: str) -> Union["D2FrcnnDetector", "TPFrcnnDetector", "HFDetrDerivedDetector"]:
diff --git a/deepdoctection/configs/conf_dd_one.yaml b/deepdoctection/configs/conf_dd_one.yaml
index 307ad6eb..7b716ee8 100644
--- a/deepdoctection/configs/conf_dd_one.yaml
+++ b/deepdoctection/configs/conf_dd_one.yaml
@@ -18,7 +18,7 @@ PT:
         TOP: 60
         RIGHT: 60
         BOTTOM: 60
-        LEFT": 60
+        LEFT: 60
    ITEM:
      WEIGHTS: item/d2_model_1639999_item_inf_only.pt
      FILTER:
@@ -26,7 +26,7 @@ PT:
         TOP: 60
         RIGHT: 60
         BOTTOM: 60
-        LEFT": 60
+        LEFT: 60
    CELL:
       WEIGHTS: cell/d2_model_1849999_cell_inf_only.pt
       FILTER:
diff --git a/deepdoctection/dataflow/common.py b/deepdoctection/dataflow/common.py
index b691d94e..78f469ce 100644
--- a/deepdoctection/dataflow/common.py
+++ b/deepdoctection/dataflow/common.py
@@ -49,14 +49,14 @@ def start(self) -> None:
         """
         if not self._reset_called:
             self.df.reset_state()
-        itr = self.df.__iter__()
+        itr = iter(self.df)
         if self.warmup:
             for _ in tqdm.trange(self.warmup, **get_tqdm_default_kwargs()):  # type: ignore
                 next(itr)
         # add smoothing for speed benchmark
         with get_tqdm(total=self.test_size, leave=True, smoothing=0.2) as pbar:
             for idx, _ in enumerate(itr):
-                pbar.update()  # type: ignore
+                pbar.update()
                 if idx == self.test_size - 1:
                     break
 
diff --git a/deepdoctection/dataflow/custom.py b/deepdoctection/dataflow/custom.py
index ab6fc0ef..bf10fb9c 100644
--- a/deepdoctection/dataflow/custom.py
+++ b/deepdoctection/dataflow/custom.py
@@ -86,7 +86,7 @@ def get_cache(self) -> List[Any]:
         self.reset_state()
         with get_tqdm() as status_bar:
             for _ in self:
-                status_bar.update()  # type: ignore
+                status_bar.update()
             if self.shuffle:
                 self.rng.shuffle(self.buffer)
             return self.buffer
diff --git a/deepdoctection/dataflow/custom_serialize.py b/deepdoctection/dataflow/custom_serialize.py
index 0dbf45ad..a12311ea 100644
--- a/deepdoctection/dataflow/custom_serialize.py
+++ b/deepdoctection/dataflow/custom_serialize.py
@@ -229,7 +229,6 @@ class CocoParser:
     """
 
     def __init__(self, annotation_file: Optional[Pathlike] = None) -> None:
-
         self.dataset: JsonDict = {}
         self.anns: Dict[int, JsonDict] = {}
         self.cats: Dict[int, JsonDict] = {}
@@ -484,7 +483,7 @@ def load(path: Pathlike, max_datapoints: Optional[int] = None) -> DataFlow:
             with get_tqdm(total=len(imgs)) as status_bar:
                 for img in imgs:
                     img["annotations"] = coco.img_to_anns[img["id"]]
-                    status_bar.update()  # type: ignore
+                    status_bar.update()
 
         df = CustomDataFromList(imgs, max_datapoints=max_datapoints)
         return df
diff --git a/deepdoctection/dataflow/parallel_map.py b/deepdoctection/dataflow/parallel_map.py
index 56c1206b..f564e57d 100644
--- a/deepdoctection/dataflow/parallel_map.py
+++ b/deepdoctection/dataflow/parallel_map.py
@@ -39,7 +39,7 @@ def del_weakref(x):
     """delete weakref"""
     instance = x()
     if instance is not None:
-        instance.__del__()
+        del instance
 
 
 @no_type_check
@@ -90,7 +90,7 @@ def reset_state(self) -> None:
             df = RepeatedData(self.df, -1)
         else:
             df = self.df  # type: ignore
-        self._iter = df.__iter__()
+        self._iter = iter(df)
 
     @no_type_check
     @abstractmethod
@@ -137,7 +137,7 @@ def get_data_strict(self) -> Any:
         for dp in self._iter:
             self._send(dp)
             yield self._recv_filter_none()
-        self._iter = self.df.__iter__()  # refresh
+        self._iter = iter(self.df)  # refresh
 
         # first clear the buffer, then fill
         for k in range(self._buffer_size):
diff --git a/deepdoctection/dataflow/stats.py b/deepdoctection/dataflow/stats.py
index cf4106eb..3eb47a4a 100644
--- a/deepdoctection/dataflow/stats.py
+++ b/deepdoctection/dataflow/stats.py
@@ -93,7 +93,7 @@ def start(self) -> npt.NDArray[Any]:
 
         if not self._reset_called:
             self.df.reset_state()
-        itr = self.df.__iter__()
+        itr = iter(self.df)
 
         logger.info("Calculating mean")
 
@@ -108,7 +108,6 @@ def start(self) -> npt.NDArray[Any]:
         with get_tqdm(total=len_df) as status_bar:
             n = None
             for n, dp in enumerate(itr, 1):
-
                 if isinstance(dp, dict):
                     assert isinstance(self.key, str), self.key
                     val = dp[self.key]
@@ -135,7 +134,7 @@ def start(self) -> npt.NDArray[Any]:
                     x = np.mean(val, axis=self.axis if inner_axis is None else inner_axis)
                     self.mean += (x - self.mean) / n
 
-                status_bar.update()  # type: ignore
+                status_bar.update()
                 if self.max_datapoints is not None:
                     if n == self.max_datapoints:
                         break
@@ -215,7 +214,7 @@ def start(self) -> npt.NDArray[Any]:
 
         if not self._reset_called:
             self.df.reset_state()
-        itr = self.df.__iter__()
+        itr = iter(self.df)
 
         logger.info("Calculating standard deviation")
         try:
@@ -227,7 +226,6 @@ def start(self) -> npt.NDArray[Any]:
         n = None
         with get_tqdm(total=len_df) as status_bar:
             for n, dp in enumerate(itr, 1):
-
                 if isinstance(dp, dict):
                     assert isinstance(self.key, str), self.key
                     val = dp[self.key]
@@ -260,7 +258,7 @@ def start(self) -> npt.NDArray[Any]:
                     ex += x - k
                     ex2 += (x - k) * (x - k)
 
-                status_bar.update()  # type: ignore
+                status_bar.update()
                 if self.max_datapoints is not None:
                     if n == self.max_datapoints:
                         break
diff --git a/deepdoctection/datapoint/annotation.py b/deepdoctection/datapoint/annotation.py
index 0cc24185..7674ca15 100644
--- a/deepdoctection/datapoint/annotation.py
+++ b/deepdoctection/datapoint/annotation.py
@@ -52,7 +52,7 @@ def ann_from_dict(cls, **kwargs):
     return ann
 
 
-@dataclass  # type: ignore
+@dataclass
 class Annotation(ABC):
     """
     Abstract base class for all types of annotations. This abstract base class only implements general methods for
diff --git a/deepdoctection/datapoint/convert.py b/deepdoctection/datapoint/convert.py
index e1d97a2e..a8cd7e77 100644
--- a/deepdoctection/datapoint/convert.py
+++ b/deepdoctection/datapoint/convert.py
@@ -136,7 +136,6 @@ def convert_pdf_bytes_to_np_array(pdf_bytes: bytes, dpi: Optional[int] = None) -
     buffered = BytesIO()
 
     if dpi is None:
-
         image = convert_from_bytes(pdf_bytes, size=(width, height))[0]
     else:
         image = convert_from_bytes(pdf_bytes, dpi=dpi)[0]
diff --git a/deepdoctection/datapoint/image.py b/deepdoctection/datapoint/image.py
index f6eb871a..48493296 100644
--- a/deepdoctection/datapoint/image.py
+++ b/deepdoctection/datapoint/image.py
@@ -487,7 +487,7 @@ def maybe_ann_to_sub_image(self, annotation_id: str, category_names: Union[str,
         for sub_image in sub_images:
             if sub_image.image is None:
                 raise ValueError(
-                    "When setting an embedding to ImageAnnotation then ImageAnnotation.image must not " "be None"
+                    "When setting an embedding to ImageAnnotation then ImageAnnotation.image must not be None"
                 )
             sub_image.image.set_embedding(
                 annotation_id,
diff --git a/deepdoctection/datapoint/view.py b/deepdoctection/datapoint/view.py
index c21def1c..9025b476 100644
--- a/deepdoctection/datapoint/view.py
+++ b/deepdoctection/datapoint/view.py
@@ -115,7 +115,7 @@ def __getattr__(self, item: str) -> Optional[Union[str, int, List[str]]]:
                     return int(sub_cat.category_id)
         return None
 
-    def get_attribute_names(self) -> Set[str]:  # pylint: disable=R0201
+    def get_attribute_names(self) -> Set[str]:
         """
         :return: A set of registered attributes. When sub classing modify this method accordingly.
         """
diff --git a/deepdoctection/datasets/adapter.py b/deepdoctection/datasets/adapter.py
index d3e6e724..6a72c650 100644
--- a/deepdoctection/datasets/adapter.py
+++ b/deepdoctection/datasets/adapter.py
@@ -137,7 +137,7 @@ def __init__(
                         summarizer.dump(cat_ids)
 
                     datapoints.append(dp)
-                    status_bar.update()  # type: ignore
+                    status_bar.update()
 
             if _data_statistics:
                 summarizer.print_summary_histogram()
diff --git a/deepdoctection/eval/accmetric.py b/deepdoctection/eval/accmetric.py
index 978b7bca..57ed16e1 100644
--- a/deepdoctection/eval/accmetric.py
+++ b/deepdoctection/eval/accmetric.py
@@ -218,7 +218,6 @@ class ClassificationMetric(MetricBase):
     def dump(
         cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
     ) -> Tuple[Any, Any]:
-
         dataflow_gt.reset_state()
         dataflow_predictions.reset_state()
 
@@ -234,9 +233,9 @@ def dump(
         labels_per_image_gt = {}
         labels_per_image_predictions = {}
         for dp_gt, dp_pd in zip(dataflow_gt, dataflow_predictions):
-            dp_labels_gt, image_id_gt = mapper_with_setting(dp_gt)
+            dp_labels_gt, image_id_gt = mapper_with_setting(dp_gt)  # pylint: disable=E1102
             labels_per_image_gt[image_id_gt] = dp_labels_gt
-            dp_labels_predictions, image_id_pr = mapper_with_setting(dp_pd)
+            dp_labels_predictions, image_id_pr = mapper_with_setting(dp_pd)  # pylint: disable=E1102
             labels_per_image_predictions[image_id_pr] = dp_labels_predictions
 
         for image_id, dp_labels_gt in labels_per_image_gt.items():
@@ -255,7 +254,6 @@ def dump(
     def get_distance(
         cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
     ) -> List[JsonDict]:
-
         labels_gt, labels_pr = cls.dump(dataflow_gt, dataflow_predictions, categories)
 
         results = []
@@ -396,7 +394,6 @@ class ConfusionMetric(ClassificationMetric):
     def get_distance(
         cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
     ) -> List[JsonDict]:
-
         labels_gt, labels_pr = cls.dump(dataflow_gt, dataflow_predictions, categories)
 
         results = []
@@ -444,7 +441,6 @@ class PrecisionMetric(ClassificationMetric):
     def get_distance(
         cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
     ) -> List[JsonDict]:
-
         labels_gt, labels_pr = cls.dump(dataflow_gt, dataflow_predictions, categories)
 
         results = []
@@ -497,7 +493,6 @@ class PrecisionMetricMicro(ClassificationMetric):
     def get_distance(
         cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
     ) -> List[JsonDict]:
-
         labels_gt, labels_pr = cls.dump(dataflow_gt, dataflow_predictions, categories)
 
         results = []
diff --git a/deepdoctection/eval/base.py b/deepdoctection/eval/base.py
index 333f881e..ded9ff0b 100644
--- a/deepdoctection/eval/base.py
+++ b/deepdoctection/eval/base.py
@@ -111,7 +111,6 @@ def result_list_to_dict(cls, results: List[JsonDict]) -> JsonDict:
             new_key = ""
             new_val = 0.0
             for k, val in res.items():
-
                 if str(val) != "":
                     if k != "val":
                         if k != "key":
diff --git a/deepdoctection/eval/eval.py b/deepdoctection/eval/eval.py
index e2db8af0..208bd72a 100644
--- a/deepdoctection/eval/eval.py
+++ b/deepdoctection/eval/eval.py
@@ -147,7 +147,7 @@ def __init__(
                 )
             elif self.dataset.dataset_info.type == DatasetType.token_classification:
                 if hasattr(self.metric, "sub_cats"):
-                    sub_cat_key, sub_cat_val_list = list(self.metric.sub_cats.items())[0]  # type: ignore
+                    sub_cat_key, sub_cat_val_list = list(self.metric.sub_cats.items())[0]
                     sub_cat_val = sub_cat_val_list[0]
                     sub_cats = {sub_cat_key: sub_cat_val}
                     self.wandb_table_agent = WandbTableAgent(
@@ -166,7 +166,7 @@ def __init__(
                     )
                 else:
                     raise AttributeError(
-                        "metric has no attribute sub_cats and cannot be used for token classification " "datasets"
+                        "metric has no attribute sub_cats and cannot be used for token classification datasets"
                     )
             else:
                 raise NotImplementedError
diff --git a/deepdoctection/eval/tedsmetric.py b/deepdoctection/eval/tedsmetric.py
index aa19e746..f9ccbb54 100644
--- a/deepdoctection/eval/tedsmetric.py
+++ b/deepdoctection/eval/tedsmetric.py
@@ -218,7 +218,6 @@ class TedsMetric(MetricBase):
     def dump(
         cls, dataflow_gt: DataFlow, dataflow_predictions: DataFlow, categories: DatasetCategories
     ) -> Tuple[List[str], List[str]]:
-
         dataflow_gt.reset_state()
         dataflow_predictions.reset_state()
 
diff --git a/deepdoctection/extern/doctrocr.py b/deepdoctection/extern/doctrocr.py
index 93fea72d..46c7e2f7 100644
--- a/deepdoctection/extern/doctrocr.py
+++ b/deepdoctection/extern/doctrocr.py
@@ -253,7 +253,6 @@ class DoctrTextRecognizer(TextRecognizer):
     """
 
     def __init__(self, architecture: str, path_weights: str, device: Optional[Literal["cpu", "cuda"]] = None) -> None:
-
         self.name = "doctr_text_recognizer"
         self.architecture = architecture
         self.path_weights = path_weights
diff --git a/deepdoctection/extern/hflayoutlm.py b/deepdoctection/extern/hflayoutlm.py
index cb7749fe..c75bc6fb 100644
--- a/deepdoctection/extern/hflayoutlm.py
+++ b/deepdoctection/extern/hflayoutlm.py
@@ -619,7 +619,6 @@ def __init__(
         self.model.to(self.device)
 
     def predict(self, **encodings: Union[List[List[str]], "torch.Tensor"]) -> SequenceClassResult:
-
         input_ids = encodings.get("input_ids")
         attention_mask = encodings.get("attention_mask")
         token_type_ids = encodings.get("token_type_ids")
@@ -664,7 +663,6 @@ def clone(self) -> "HFLayoutLmSequenceClassifierBase":
     def _validate_encodings(
         self, **encodings: Union[List[List[str]], "torch.Tensor"]
     ) -> Tuple["torch.Tensor", "torch.Tensor", "torch.Tensor", "torch.Tensor"]:
-
         input_ids = encodings.get("input_ids")
         attention_mask = encodings.get("attention_mask")
         token_type_ids = encodings.get("token_type_ids")
@@ -732,7 +730,6 @@ def __init__(
         categories: Mapping[str, TypeOrStr],
         device: Optional[Literal["cpu", "cuda"]] = None,
     ):
-
         config = PretrainedConfig.from_pretrained(pretrained_model_name_or_path=path_config_json)
         self.model = LayoutLMForSequenceClassification.from_pretrained(
             pretrained_model_name_or_path=path_weights, config=config
@@ -793,7 +790,6 @@ def __init__(
         categories: Mapping[str, TypeOrStr],
         device: Optional[Literal["cpu", "cuda"]] = None,
     ):
-
         config = LayoutLMv2Config.from_pretrained(pretrained_model_name_or_path=path_config_json)
         self.model = LayoutLMv2ForSequenceClassification.from_pretrained(
             pretrained_model_name_or_path=path_weights, config=config
@@ -861,7 +857,6 @@ def __init__(
         categories: Mapping[str, TypeOrStr],
         device: Optional[Literal["cpu", "cuda"]] = None,
     ):
-
         config = LayoutLMv3Config.from_pretrained(pretrained_model_name_or_path=path_config_json)
         self.model = LayoutLMv3ForSequenceClassification.from_pretrained(
             pretrained_model_name_or_path=path_weights, config=config
diff --git a/deepdoctection/mapper/cocostruct.py b/deepdoctection/mapper/cocostruct.py
index 916f7b02..dcfa3880 100644
--- a/deepdoctection/mapper/cocostruct.py
+++ b/deepdoctection/mapper/cocostruct.py
@@ -41,7 +41,6 @@ def coco_to_image(
     coarse_mapping: Optional[Mapping[int, int]] = None,
     coarse_sub_cat_name: Optional[ObjectTypes] = None,
 ) -> Optional[Image]:
-
     """
     Map a dataset in coco format that has been serialized to image format. This serialized input requirements hold
     when a coco style sheet is loaded via `SerializerCoco.load`.
diff --git a/deepdoctection/mapper/pubstruct.py b/deepdoctection/mapper/pubstruct.py
index a9caa9e2..a3e8256b 100644
--- a/deepdoctection/mapper/pubstruct.py
+++ b/deepdoctection/mapper/pubstruct.py
@@ -38,7 +38,6 @@
 
 
 def _convert_boxes(dp: JsonDict, height: int) -> JsonDict:
-
     if "bbox" in dp:
         table_box_3 = height - dp["bbox"][1]
         dp["bbox"][1] = height - dp["bbox"][3]
@@ -54,7 +53,6 @@ def _convert_boxes(dp: JsonDict, height: int) -> JsonDict:
 
 
 def _get_table_annotation(dp: JsonDict, category_id: str) -> ImageAnnotation:
-
     ulx, uly, lrx, lry = list(map(float, dp["bbox"]))
     bbox = BoundingBox(absolute_coords=True, ulx=ulx, uly=uly, lrx=lrx, lry=lry)
     annotation = ImageAnnotation(category_name=LayoutType.table, bounding_box=bbox, category_id=category_id)
@@ -62,7 +60,6 @@ def _get_table_annotation(dp: JsonDict, category_id: str) -> ImageAnnotation:
 
 
 def _cell_token(html: Sequence[str]) -> List[List[int]]:
-
     index_rows = [i for i, tag in enumerate(html) if tag == "<tr>"]
     index_cells = [i for i, tag in enumerate(html) if tag in ("<td>", ">")]
     index_rows_tmp = [(index_rows[i], index_rows[i + 1]) for i in range(len(index_rows) - 1)]
@@ -76,7 +73,6 @@ def _cell_token(html: Sequence[str]) -> List[List[int]]:
 
 
 def _item_spans(html: Sequence[str], index_cells: Sequence[Sequence[int]], item: str) -> List[List[int]]:
-
     item_spans = [
         [
             int(html[index_cell - 1].replace(item + "=", "").replace('"', ""))
@@ -121,7 +117,6 @@ def tile_table(row_spans: Sequence[Sequence[int]], col_spans: Sequence[Sequence[
     for row in col_spans:
         cell_id_per_row = []
         for idx, k in enumerate(itertools.count(i)):
-
             if idx < len(row):
                 i += 1
                 cell_id_per_row.append(k)
@@ -157,7 +152,6 @@ def tile_table(row_spans: Sequence[Sequence[int]], col_spans: Sequence[Sequence[
 
 
 def _add_items(image: Image, item_type: str, categories_name_as_key: Dict[str, str], pubtables_like: bool) -> Image:
-
     item_number = CellType.row_number if item_type == LayoutType.row else CellType.column_number
     item_span = CellType.row_span if item_type == LayoutType.row else CellType.column_span
 
@@ -180,13 +174,13 @@ def _add_items(image: Image, item_type: str, categories_name_as_key: Dict[str, s
         )
         cell_item = list(filter(lambda x: x.get_sub_category(item_span).category_id == "1", cell_item))
         if cell_item:
-            ulx = min([cell.bounding_box.ulx for cell in cell_item if isinstance(cell.bounding_box, BoundingBox)])
+            ulx = min(cell.bounding_box.ulx for cell in cell_item if isinstance(cell.bounding_box, BoundingBox))
 
-            uly = min([cell.bounding_box.uly for cell in cell_item if isinstance(cell.bounding_box, BoundingBox)])
+            uly = min(cell.bounding_box.uly for cell in cell_item if isinstance(cell.bounding_box, BoundingBox))
 
-            lrx = max([cell.bounding_box.lrx for cell in cell_item if isinstance(cell.bounding_box, BoundingBox)])
+            lrx = max(cell.bounding_box.lrx for cell in cell_item if isinstance(cell.bounding_box, BoundingBox))
 
-            lry = max([cell.bounding_box.lry for cell in cell_item if isinstance(cell.bounding_box, BoundingBox)])
+            lry = max(cell.bounding_box.lry for cell in cell_item if isinstance(cell.bounding_box, BoundingBox))
 
             if pubtables_like:
                 tables = image.get_annotation(category_names=LayoutType.table)
@@ -228,7 +222,6 @@ def _add_items(image: Image, item_type: str, categories_name_as_key: Dict[str, s
                 filter_level="bounding box",
                 image_annotation={"category_name": item.category_name, "annotation_id": item.annotation_id},
             ):
-
                 box = item.bounding_box
                 if box:
                     tmp_next_item_xy = 0.0
@@ -394,7 +387,6 @@ def pub_to_image_uncur(  # pylint: disable=R0914
         return None
 
     with MappingContextManager(str(idx)) as mapping_context:
-
         max_rs, max_cs = 0, 0
         if idx is None:
             raise ValueError("No valid datapoint external id")
diff --git a/deepdoctection/mapper/xfundstruct.py b/deepdoctection/mapper/xfundstruct.py
index f9c40451..ec0fee86 100644
--- a/deepdoctection/mapper/xfundstruct.py
+++ b/deepdoctection/mapper/xfundstruct.py
@@ -80,7 +80,6 @@ def xfund_to_image(
     token_tag_to_id_mapping = ner_token_to_id_mapping[LayoutType.word][WordType.token_tag]
 
     with MappingContextManager(file_name) as mapping_context:
-
         image = Image(file_name=file_name, location=full_path, external_id=external_id)
 
         image.image = load_image_from_file(full_path)
diff --git a/deepdoctection/pipe/common.py b/deepdoctection/pipe/common.py
index deb921da..2c6a8a12 100644
--- a/deepdoctection/pipe/common.py
+++ b/deepdoctection/pipe/common.py
@@ -148,7 +148,6 @@ def clone(self) -> PipelineComponent:
         return self.__class__(self.parent_categories, self.child_categories, self.matching_rule, self.threshold)
 
     def get_meta_annotation(self) -> JsonDict:
-
         return dict(
             [
                 ("image_annotations", []),
diff --git a/deepdoctection/pipe/concurrency.py b/deepdoctection/pipe/concurrency.py
index 00abcb7d..e3d0fdde 100644
--- a/deepdoctection/pipe/concurrency.py
+++ b/deepdoctection/pipe/concurrency.py
@@ -104,7 +104,6 @@ def __init__(
         post_proc_func: Optional[Callable[[Image], Image]] = None,
         max_datapoints: Optional[int] = None,
     ) -> None:
-
         """
         :param pipeline_components: list of identical pipeline component. Number of threads created is determined by
                                     `len`
@@ -161,12 +160,11 @@ def start(self) -> List[Image]:
     @staticmethod
     def _thread_predict_on_queue(
         input_queue: QueueType,
-        component: PipelineComponent,
+        component: Union[PipelineComponent, PageParsingService, ImageParsingService],
         tqdm_bar: Optional[TqdmType] = None,
         pre_proc_func: Optional[Callable[[Image], Image]] = None,
         post_proc_func: Optional[Callable[[Image], Image]] = None,
     ) -> List[Image]:
-
         outputs = []
 
         with ExitStack() as stack:
@@ -178,9 +176,10 @@ def _thread_predict_on_queue(
                 if pre_proc_func is not None:
                     inp = pre_proc_func(inp)
                 out = component.pass_datapoint(inp)
-                if post_proc_func is not None:
+                if post_proc_func is not None and out is not None:
                     out = post_proc_func(out)
-                outputs.append(out)
+                if out is not None:
+                    outputs.append(out)
                 tqdm_bar.update(1)
         return outputs
 
diff --git a/deepdoctection/pipe/order.py b/deepdoctection/pipe/order.py
index bdee7aa9..aaf56682 100644
--- a/deepdoctection/pipe/order.py
+++ b/deepdoctection/pipe/order.py
@@ -357,7 +357,7 @@ def create_detection_result(
         # every list now non-empty
         word_anns_dict = {ann.annotation_id: ann for ann in word_anns}
         word_order_list = OrderGenerator.group_words_into_lines(word_anns, image_id)
-        number_rows = max([word[1] for word in word_order_list])
+        number_rows = max(word[1] for word in word_order_list)
         detection_result_list = []
         for row in range(1, number_rows + 1):
             ann_meta_per_row = [ann_meta for ann_meta in word_order_list if ann_meta[1] == row]
diff --git a/deepdoctection/pipe/refine.py b/deepdoctection/pipe/refine.py
index 7a785c35..296f7791 100644
--- a/deepdoctection/pipe/refine.py
+++ b/deepdoctection/pipe/refine.py
@@ -460,10 +460,10 @@ def serve(self, dp: Image) -> None:
                             cell.deactivate()
 
             cells = table.image.get_annotation(category_names=self._cell_names)
-            number_of_rows = max([int(cell.get_sub_category(CellType.row_number).category_id) for cell in cells])
-            number_of_cols = max([int(cell.get_sub_category(CellType.column_number).category_id) for cell in cells])
-            max_row_span = max([int(cell.get_sub_category(CellType.row_span).category_id) for cell in cells])
-            max_col_span = max([int(cell.get_sub_category(CellType.column_span).category_id) for cell in cells])
+            number_of_rows = max(int(cell.get_sub_category(CellType.row_number).category_id) for cell in cells)
+            number_of_cols = max(int(cell.get_sub_category(CellType.column_number).category_id) for cell in cells)
+            max_row_span = max(int(cell.get_sub_category(CellType.row_span).category_id) for cell in cells)
+            max_col_span = max(int(cell.get_sub_category(CellType.column_span).category_id) for cell in cells)
             # TODO: the summaries should be sub categories of the underlying ann
             if TableType.number_of_rows in table.sub_categories:
                 table.remove_sub_category(TableType.number_of_rows)
diff --git a/deepdoctection/pipe/segment.py b/deepdoctection/pipe/segment.py
index c07119fd..95e4ec04 100644
--- a/deepdoctection/pipe/segment.py
+++ b/deepdoctection/pipe/segment.py
@@ -471,7 +471,7 @@ def segment_table(
             rows_of_cell = [rows[k] for k in row_index[cell_positions_rows]]
             rs = np.count_nonzero(cell_index_rows == idx)
             if len(rows_of_cell):
-                row_number = min([int(row.get_sub_category(CellType.row_number).category_id) for row in rows_of_cell])
+                row_number = min(int(row.get_sub_category(CellType.row_number).category_id) for row in rows_of_cell)
             else:
                 row_number = 0
 
@@ -479,9 +479,7 @@ def segment_table(
             cols_of_cell = [columns[k] for k in col_index[cell_positions_cols]]
             cs = np.count_nonzero(cell_index_cols == idx)
             if len(cols_of_cell):
-                col_number = min(
-                    [int(col.get_sub_category(CellType.column_number).category_id) for col in cols_of_cell]
-                )
+                col_number = min(int(col.get_sub_category(CellType.column_number).category_id) for col in cols_of_cell)
             else:
                 col_number = 0
 
@@ -612,27 +610,25 @@ def segment_pubtables(
             cell_positions_rows = cell_index_rows == idx
             rows_of_cell = [rows[k] for k in row_index[cell_positions_rows]]
             rs = (
-                max([int(row.get_sub_category(CellType.row_number).category_id) for row in rows_of_cell])
-                - min([int(row.get_sub_category(CellType.row_number).category_id) for row in rows_of_cell])
+                max(int(row.get_sub_category(CellType.row_number).category_id) for row in rows_of_cell)
+                - min(int(row.get_sub_category(CellType.row_number).category_id) for row in rows_of_cell)
                 + 1
             )
             if len(rows_of_cell):
-                row_number = min([int(row.get_sub_category(CellType.row_number).category_id) for row in rows_of_cell])
+                row_number = min(int(row.get_sub_category(CellType.row_number).category_id) for row in rows_of_cell)
             else:
                 row_number = 0
 
             cell_positions_cols = cell_index_cols == idx
             cols_of_cell = [columns[k] for k in col_index[cell_positions_cols]]
             cs = (
-                max([int(col.get_sub_category(CellType.column_number).category_id) for col in cols_of_cell])
-                - min([int(col.get_sub_category(CellType.column_number).category_id) for col in cols_of_cell])
+                max(int(col.get_sub_category(CellType.column_number).category_id) for col in cols_of_cell)
+                - min(int(col.get_sub_category(CellType.column_number).category_id) for col in cols_of_cell)
                 + 1
             )
 
             if len(cols_of_cell):
-                col_number = min(
-                    [int(col.get_sub_category(CellType.column_number).category_id) for col in cols_of_cell]
-                )
+                col_number = min(int(col.get_sub_category(CellType.column_number).category_id) for col in cols_of_cell)
             else:
                 col_number = 0
 
@@ -782,10 +778,10 @@ def serve(self, dp: Image) -> None:
 
             if table.image:
                 cells = table.image.get_annotation(category_names=self._cell_names)
-                number_of_rows = max([int(cell.get_sub_category(CellType.row_number).category_id) for cell in cells])
-                number_of_cols = max([int(cell.get_sub_category(CellType.column_number).category_id) for cell in cells])
-                max_row_span = max([int(cell.get_sub_category(CellType.row_span).category_id) for cell in cells])
-                max_col_span = max([int(cell.get_sub_category(CellType.column_span).category_id) for cell in cells])
+                number_of_rows = max(int(cell.get_sub_category(CellType.row_number).category_id) for cell in cells)
+                number_of_cols = max(int(cell.get_sub_category(CellType.column_number).category_id) for cell in cells)
+                max_row_span = max(int(cell.get_sub_category(CellType.row_span).category_id) for cell in cells)
+                max_col_span = max(int(cell.get_sub_category(CellType.column_span).category_id) for cell in cells)
                 # TODO: the summaries should be sub categories of the underlying ann
                 self.dp_manager.set_summary_annotation(
                     TableType.number_of_rows,
@@ -1022,10 +1018,10 @@ def serve(self, dp: Image) -> None:
             cells = []
             if table.image:
                 cells = table.image.get_annotation(category_names=self._cell_names)
-            number_of_rows = max([int(cell.get_sub_category(CellType.row_number).category_id) for cell in cells])
-            number_of_cols = max([int(cell.get_sub_category(CellType.column_number).category_id) for cell in cells])
-            max_row_span = max([int(cell.get_sub_category(CellType.row_span).category_id) for cell in cells])
-            max_col_span = max([int(cell.get_sub_category(CellType.column_span).category_id) for cell in cells])
+            number_of_rows = max(int(cell.get_sub_category(CellType.row_number).category_id) for cell in cells)
+            number_of_cols = max(int(cell.get_sub_category(CellType.column_number).category_id) for cell in cells)
+            max_row_span = max(int(cell.get_sub_category(CellType.row_span).category_id) for cell in cells)
+            max_col_span = max(int(cell.get_sub_category(CellType.column_span).category_id) for cell in cells)
             # TODO: the summaries should be sub categories of the underlying ann
             self.dp_manager.set_summary_annotation(
                 TableType.number_of_rows, TableType.number_of_rows, number_of_rows, annotation_id=table.annotation_id
diff --git a/deepdoctection/pipe/text.py b/deepdoctection/pipe/text.py
index d0d81528..5925cea4 100644
--- a/deepdoctection/pipe/text.py
+++ b/deepdoctection/pipe/text.py
@@ -99,7 +99,7 @@ def __init__(
         self.skip_if_text_extracted = skip_if_text_extracted
         if self.skip_if_text_extracted and isinstance(self.predictor, TextRecognizer):
             raise ValueError(
-                "skip_if_text_extracted=True and TextRecognizer in TextExtractionService is not " "compatible"
+                "skip_if_text_extracted=True and TextRecognizer in TextExtractionService is not compatible"
             )
 
     def serve(self, dp: Image) -> None:
diff --git a/deepdoctection/train/hf_layoutlm_train.py b/deepdoctection/train/hf_layoutlm_train.py
index 10352ac8..e2549c5e 100644
--- a/deepdoctection/train/hf_layoutlm_train.py
+++ b/deepdoctection/train/hf_layoutlm_train.py
@@ -353,7 +353,7 @@ def train_hf_layoutlm(
     )
     image_to_raw_layoutlm_kwargs = {"dataset_type": dataset_type, "use_token_tag": use_token_tag}
     if segment_positions:
-        image_to_raw_layoutlm_kwargs["segment_positions"] = segment_positions
+        image_to_raw_layoutlm_kwargs["segment_positions"] = segment_positions  # type: ignore
     image_to_raw_layoutlm_kwargs.update(model_wrapper_cls.default_kwargs_for_input_mapping())
     dataset = DatasetAdapter(
         dataset_train,
diff --git a/deepdoctection/train/tp_frcnn_train.py b/deepdoctection/train/tp_frcnn_train.py
index 9512da8a..b1abd5e4 100644
--- a/deepdoctection/train/tp_frcnn_train.py
+++ b/deepdoctection/train/tp_frcnn_train.py
@@ -159,7 +159,7 @@ def get_train_dataflow(
                 )
             summarizer.dump(dp["gt_labels"])
             datapoints.append(dp)
-            status_bar.update()  # type: ignore
+            status_bar.update()
     summarizer.print_summary_histogram(dd_logic=False)
     num_datapoints = len(datapoints)
     logger.info("Total #images for training: %i", num_datapoints)
diff --git a/deepdoctection/utils/concurrency.py b/deepdoctection/utils/concurrency.py
index bac440d3..37703f61 100644
--- a/deepdoctection/utils/concurrency.py
+++ b/deepdoctection/utils/concurrency.py
@@ -55,7 +55,7 @@ def stopped(self) -> bool:
         """
         :param bool: whether the thread is stopped or not
         """
-        return self._stop_evt.isSet()
+        return self._stop_evt.is_set()
 
     def queue_put_stoppable(self, q: QueueType, obj: Any) -> None:
         """Put obj to queue, but will give up when the thread is stopped"""
@@ -105,12 +105,11 @@ def enable_death_signal(_warn: bool = True) -> None:
                 '"import prctl" failed! Install python-prctl so that processes can be cleaned with guarantee.', "warn"
             )
         return
-    else:
-        assert hasattr(
-            prctl, "set_pdeathsig"
-        ), "prctl.set_pdeathsig does not exist! Note that you need to install 'python-prctl' instead of 'prctl'."
-        # is SIGHUP a good choice?
-        prctl.set_pdeathsig(signal.SIGHUP)
+    assert hasattr(
+        prctl, "set_pdeathsig"
+    ), "prctl.set_pdeathsig does not exist! Note that you need to install 'python-prctl' instead of 'prctl'."
+    # is SIGHUP a good choice?
+    prctl.set_pdeathsig(signal.SIGHUP)
 
 
 # taken from https://github.com/tensorpack/dataflow/blob/master/dataflow/utils/concurrency.py
diff --git a/deepdoctection/utils/file_utils.py b/deepdoctection/utils/file_utils.py
index edd10f6e..f82c177e 100644
--- a/deepdoctection/utils/file_utils.py
+++ b/deepdoctection/utils/file_utils.py
@@ -292,7 +292,7 @@ class TesseractNotFound(BaseException):
     """
 
 
-def get_tesseract_version() -> Union[int, version.Version, version.LegacyVersion]:
+def get_tesseract_version() -> Union[int, version.Version]:
     """
     Returns Version object of the Tesseract version. We need at least Tesseract 3.05
     """
@@ -352,7 +352,7 @@ class PopplerNotFound(BaseException):
     """
 
 
-def get_poppler_version() -> Union[int, version.Version, version.LegacyVersion]:
+def get_poppler_version() -> Union[int, version.Version]:
     """
     Returns Version object of the Poppler version. We need at least Tesseract 3.05
     """
diff --git a/deepdoctection/utils/logger.py b/deepdoctection/utils/logger.py
index b653df55..b861ae61 100644
--- a/deepdoctection/utils/logger.py
+++ b/deepdoctection/utils/logger.py
@@ -185,7 +185,7 @@ def dir_nonempty(directory: str) -> int:
         if not action:
             logger.warning("Log directory %s exists! Use 'd' to delete it. ", dir_name)
             logger.warning(
-                "If you're resuming from a previous run, you can choose to keep it." "Press any other key to exit. "
+                "If you're resuming from a previous run, you can choose to keep it. Press any other key to exit. "
             )
         while not action:
             action = input("Select Action: k (keep) / d (delete) / q (quit):").lower().strip()
@@ -225,7 +225,7 @@ def auto_set_dir(action: Optional[str] = None, name: Optional[str] = None) -> No
     """
 
     mod = sys.modules["__main__"]
-    basename = str(os.path.basename(mod.__file__))  # type: ignore
+    basename = str(os.path.basename(mod.__file__))  # type: ignore  # pylint: disable=E1101
     auto_dir_name = os.path.join("train_log", basename[: basename.rfind(".")])
     if name:
         auto_dir_name += "_%s" % name if os.name == "nt" else ":%s" % name  # pylint: disable=C0209
diff --git a/deepdoctection/utils/pdf_utils.py b/deepdoctection/utils/pdf_utils.py
index 70fda4f9..3ef5585f 100644
--- a/deepdoctection/utils/pdf_utils.py
+++ b/deepdoctection/utils/pdf_utils.py
@@ -152,7 +152,6 @@ def __iter__(self) -> Generator[Tuple[bytes, int], None, None]:
 def _input_to_cli_str(
     input_file_name: Pathlike, output_file_name: Pathlike, dpi: int, size: Optional[Tuple[int, int]] = None
 ) -> List[str]:
-
     cmd_args: List[str] = []
 
     if pdf_to_ppm_available():
diff --git a/deepdoctection/utils/settings.py b/deepdoctection/utils/settings.py
index b721b283..e6574c13 100644
--- a/deepdoctection/utils/settings.py
+++ b/deepdoctection/utils/settings.py
@@ -46,7 +46,7 @@ def from_value(cls, value: str) -> "ObjectTypes":
         raise ValueError(f"value {value} does not have corresponding member")
 
 
-TypeOrStr = Union[ObjectTypes, str]
+TypeOrStr = Union[ObjectTypes, str]  # pylint: disable=C0103
 
 object_types_registry = catalogue.create("deepdoctection", "settings", entry_points=True)
 
diff --git a/deepdoctection/utils/tqdm.py b/deepdoctection/utils/tqdm.py
index 1b49152b..fc438f1b 100644
--- a/deepdoctection/utils/tqdm.py
+++ b/deepdoctection/utils/tqdm.py
@@ -36,15 +36,15 @@ def get_tqdm_default_kwargs(
     :param kwargs: extra arguments to be used.
     """
 
-    return dict(
-        total=kwargs.get("total"),
-        leave=True,
-        smoothing=0.5,
-        dynamic_ncols=True,
-        ascii=True,
-        bar_format="{l_bar}{bar}|{n_fmt}/{total_fmt}[{elapsed}<{remaining},{rate_noinv_fmt}]",
-        mininterval=5,
-    )
+    return {
+        "total": kwargs.get("total"),
+        "leave": True,
+        "smoothing": 0.5,
+        "dynamic_ncols": True,
+        "ascii": True,
+        "bar_format": "{l_bar}{bar}|{n_fmt}/{total_fmt}[{elapsed}<{remaining},{rate_noinv_fmt}]",
+        "mininterval": 5,
+    }
 
 
 def get_tqdm(total: Optional[Union[int, float]] = None, **kwargs: Union[str, int, float]) -> TqdmType:
diff --git a/deepdoctection/utils/transform.py b/deepdoctection/utils/transform.py
index d4d54ad2..6c523093 100644
--- a/deepdoctection/utils/transform.py
+++ b/deepdoctection/utils/transform.py
@@ -150,7 +150,7 @@ def pad_image(image: ImageType, top: int, right: int, bottom: int, left: int) ->
     :param bottom: Bottom pixel value to pad
     :param left: Left pixel value to pad
     """
-    return np.pad(image, ((left, right), (top, bottom), (0, 0)), "constant", constant_values=(255))
+    return np.pad(image, ((left, right), (top, bottom), (0, 0)), "constant", constant_values=255)
 
 
 class PadTransform(BaseTransform):
diff --git a/docs/install.md b/docs/install.md
index 0ef0e87d..ad3e9fb0 100644
--- a/docs/install.md
+++ b/docs/install.md
@@ -11,7 +11,7 @@ by the user.
 - Linux **or** macOS. (Windows is not supported but there is [Dockerfile](../docker/pytorch-cpu-jupyter/Dockerfile) available)
 - Python >=  3.8
 - [Poppler](https://poppler.freedesktop.org/)
-- PyTorch >= 1.8 **or** Tensorflow >=2.9 and CUDA
+- 1.8 <= PyTorch < 2.0 **or** Tensorflow >=2.9 and CUDA
 
 With respect to the deep learning framework, you must decide between [Tensorflow](https://www.tensorflow.org/install?hl=en) 
 and [PyTorch](https://pytorch.org/get-started/locally/).
diff --git a/docs/tutorials/_imgs/requirements_deepdoctection.png b/docs/tutorials/_imgs/requirements_deepdoctection.png
index 7db1ec1a..395abe0f 100644
Binary files a/docs/tutorials/_imgs/requirements_deepdoctection.png and b/docs/tutorials/_imgs/requirements_deepdoctection.png differ
diff --git a/setup.cfg b/setup.cfg
index 0de88f5e..0c3a5dd3 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -21,7 +21,6 @@ disable=
     E1205, # logging-too-many-args
 
 extension-pkg-whitelist=cv2
-load-plugins=pylint_strict_informational
 
 [pylint.TYPECHECK]
 generated-members=torch.*
diff --git a/setup.py b/setup.py
index 039a40a0..71a45869 100644
--- a/setup.py
+++ b/setup.py
@@ -50,10 +50,10 @@ def get_version():
     "lxml>=4.9.1",
     "mock==4.0.3",
     "networkx>=2.7.1",
-    "numpy>=1.21,<1.24",
+    "numpy>=1.21",
     "opencv-python==4.5.4.60",
-    "packaging>=20.0,<22.0",
-    "Pillow<10.0",  # we need this requirement for Detectron2 as long they have not fixed #5010
+    "packaging>=20.0",
+    "Pillow",
     "pycocotools>=2.0.2",
     "pypdf2>=1.27.5,<2.10.1",
     "python-prctl",
@@ -85,11 +85,11 @@ def get_version():
     "python-doctr==0.6.0",
     "fasttext",
     # dev dependencies
-    "click==8.0.4",  # version will not break black
-    "black==22.3.0",
+    "click",  # version will not break black
+    "black==23.7.0",
     "isort",
-    "pylint==2.13.4",
-    "mypy==0.942",
+    "pylint==2.17.4",
+    "mypy==1.4.1",
     # docs
     "jinja2==3.0.3",
     "mkdocs-material",


Test patch:
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index 7a749cfd..73574daf 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -21,17 +21,31 @@ jobs:
       fail-fast: true
       matrix:
         include:
-          - { name: '3.8-basic-tf', python: '3.8', os: ubuntu-20.04, tox: py310,
+          - { name: '3.8-basic-tf', python: '3.8', os: ubuntu-20.04,
               dll: tensorflow==2.9, extras: ,
               test_cases: test-basic }
-          - { name: '3.8-basic-pt', python: '3.8', os: ubuntu-20.04, tox: py310,
+          - { name: '3.8-basic-pt', python: '3.8', os: ubuntu-20.04,
               dll: 'torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cpu',
               extras: ,
               test_cases: test-basic }
-          - { name: '3.8-tf', python: '3.8', os: ubuntu-20.04, tox: py310,
+          - { name: '3.8-tf', python: '3.8', os: ubuntu-20.04,
               dll: tensorflow==2.9, extras: tf,
               test_cases: test-tf }
-          - { name: '3.8-pt', python: '3.8', os: ubuntu-20.04, tox: py310,
+          - { name: '3.8-pt', python: '3.8', os: ubuntu-20.04,
+              dll: 'torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cpu',
+              extras: source-pt,
+              test_cases: test-pt }
+          - { name: '3.10-basic-tf', python: '3.10', os: ubuntu-22.04,
+              dll: tensorflow==2.9, extras: ,
+              test_cases: test-basic }
+          - { name: '3.10-basic-pt', python: '3.10', os: ubuntu-22.04,
+              dll: 'torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cpu',
+              extras: ,
+              test_cases: test-basic }
+          - { name: '3.10-tf', python: '3.10', os: ubuntu-22.04,
+              dll: tensorflow==2.9, extras: tf,
+              test_cases: test-tf }
+          - { name: '3.10-pt', python: '3.10', os: ubuntu-22.04,
               dll: 'torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cpu',
               extras: source-pt,
               test_cases: test-pt }
diff --git a/tests/analyzer/test_dd.py b/tests/analyzer/test_dd.py
index 12394992..7d2fc32f 100644
--- a/tests/analyzer/test_dd.py
+++ b/tests/analyzer/test_dd.py
@@ -29,7 +29,7 @@
 @mark.integration
 def test_dd_analyzer_builds_and_process_image_layout_correctly() -> None:
     """
-    Analyzer integration test with setting tables = False and ocr = False
+    Analyzer integration test with setting USE_TABLE_SEGMENTATION = False and USE_OCR = False
     """
 
     # Arrange
@@ -53,7 +53,7 @@ def test_dd_analyzer_builds_and_process_image_layout_correctly() -> None:
 @mark.integration
 def test_dd_analyzer_builds_and_process_image_layout_and_tables_correctly() -> None:
     """
-    Analyzer integration test with setting tables = True and ocr = False
+    Analyzer integration test with setting USE_OCR = False
     """
 
     # Arrange
@@ -88,7 +88,7 @@ def test_dd_analyzer_builds_and_process_image_layout_and_tables_correctly() -> N
 @mark.integration
 def test_dd_analyzer_builds_and_process_image_correctly() -> None:
     """
-    Analyzer integration test with setting tables = True and ocr = True
+    Analyzer integration test with setting USE_TABLE_SEGMENTATION = True and USE_OCR = True
     """
 
     # Arrange
@@ -130,3 +130,117 @@ def test_dd_analyzer_builds_and_process_image_correctly() -> None:
     assert text_["text"] == page.text
     assert len(text_["text_list"]) == 632
     assert len(text_["annotation_ids"]) == 632
+
+
+@mark.integration
+def test_dd_analyzer_with_tatr() -> None:
+    """
+    Analyzer integration test with setting USE_OCR=False and table transformer for table detection and table recognition
+    """
+
+    # Arrange
+    analyzer = get_dd_analyzer(
+        config_overwrite=[
+            "USE_OCR=False",
+            "PT.LAYOUT.WEIGHTS=microsoft/table-transformer-detection/pytorch_model.bin",
+            "PT.ITEM.WEIGHTS=microsoft/table-transformer-structure-recognition/pytorch_model.bin",
+            "PT.ITEM.FILTER=['table']",
+        ]
+    )
+
+    # Act
+    df = analyzer.analyze(path=get_integration_test_path())
+    output = collect_datapoint_from_dataflow(df)
+
+    # Assert
+    assert len(output) == 1
+    page = output[0]
+    assert isinstance(page, Page)
+    # 9 for d2 and 10 for tp model
+    assert not page.layouts
+    assert len(page.tables) == 1
+    assert len(page.tables[0].cells) in {11, 13}  # type: ignore
+
+
+@mark.integration
+def test_dd_analyzer_with_doctr() -> None:
+    """
+    Analyzer integration test with setting USE_LAYOUT=False and USE_TABLE_SEGMENTATION=False and OCR.USE_DOCTR=True
+    """
+
+    # Arrange
+    analyzer = get_dd_analyzer(
+        config_overwrite=[
+            "USE_LAYOUT=False",
+            "USE_TABLE_SEGMENTATION=False",
+            "OCR.USE_TESSERACT=False",
+            "OCR.USE_DOCTR=True",
+            "TEXT_ORDERING.INCLUDE_RESIDUAL_TEXT_CONTAINER=True",
+        ]
+    )
+
+    # Act
+    df = analyzer.analyze(path=get_integration_test_path())
+    output = collect_datapoint_from_dataflow(df)
+
+    # Assert
+    assert len(output) == 1
+    page = output[0]
+    assert isinstance(page, Page)
+    assert len(page.layouts) in {67}
+    assert (
+        page.text_no_line_break
+        == "Festlegung der VV und angemessene Risikoadjustierung Die W- Pools der DWS Gruppe werden einer Anpassung "
+        "der Risiken unterzogen, die die Adjustierung ex ante als auch ex post umfasst. Die angewandte robuste soll "
+        "sicherstellen, dass bei der Festlegung der W sowohl der risikoadjustierten Leistung als auch der Kapital- "
+        "und Liquiditétsausstattung der DWS Gruppe Rechnung getragen wird. Die mittlung des Gesamtbetrags der Wo "
+        'orientiert sich primâr an () der Tragfâhigkeit fur die DWS Gruppe (das heiBt, was kann" die DWS Gruppe '
+        "langfristig an Wi im Einklang mit regulatorisch Anforderungen gewâhren) und (i) der Leistung (das heilt, "
+        'was, sollte" die DWS Gruppe an W gewâhren, um fûr eine angemessene leistungsbezogene Vergltung zu sorgen '
+        "und gleichzeiti den langfristigen Erfolg des Unternehmens zu sichern). Die DWS Gruppe hat fûr die "
+        "Festlegung der W auf Ebene der individuellen Mitarbeiter die Grundsâtze fûr die Festlegung der "
+        'variablen Vergitung" eingefuhrt. Diese enthalten Information Uber die Faktoren und MessgrôBen, die bei '
+        "Entscheidungen: zur MI berlcksichtigt werden mussen. Dazu zâhlen beispielsweise Investmentperfomance, "
+        "Kundenbindung, Erwàgungen Unternehmenskutur sowie Zielvereinbarungen und eistungsbeurteilung im des "
+        'Ganzheitliche Leistung" Zudem werden der und Diszipl sowie deren Einfluss auf die W einbezogen. Bei per '
+        "Ermessensentséheidlung erfolgenden Sub-PoolZuteilungen verwendet das DWS DCC die internen (finanziellen "
+        "und nichtfinanziellen) Balanced Scorecard.Kennzahlen zur Erstellung differenzierter und leistungsbezogener "
+        "W-Pools. Vergutung fûr das Jahr 2018 Nach der hervorragenden Entwicklung im Jahr 2017 hatte die globale "
+        "emegemseralugliaoe 2018 mit einigen Schwierigkeiten zu kàmpfen. Grûnde waren ungûnstige Marktbedin gungen, "
+        "stârkere geopolitische Spannungen und die negative Stimmung unter den Anlegern, vor allem am europàischen "
+        "Retail-Markt. Auch die DWS Gruppe blieb von dieser Entwicklung nicht verschont. Vor diesem Hintergrund hat "
+        "das DCC die Tragfàhigkeit der W fûr das Jahr 2018 kontrolliert und festgestellt, dass die Kapital- und "
+        "Liquidititsaustattung der DWS Gruppe unter gung des Ergebnisses vor und nach Steuern klar Uber den "
+        "regulatorisch vorgeschriebenen Mindestanforderungen und dem Schwellenwert fûr die Risikotoleranz liegt. "
+        "Als Teil der im Màrz 20191 fûr das Performance- Jahr 2018 gewâhrten W wurde die Gruppenkomponente allen "
+        "berechtigten gewàhrt. Der der Bank AGI hat fûr 2018 unter Berlcksichtigung der betrâchtlichen Leistungen "
+        "der auf Basis der Bewertung der vier festgelegten! Leistungs- undi in seinem von 70 % festgelegt. einen "
+        "Zielerreichungsgrad Identifizierung von Risikotràgern Gemas Gesetz vom 17 Dezember 2010 uber die "
+        "Organismen "
+        "fûr gemeinsame Anlagen (in seiner jeweils gultigen Fassung) sowie den ESMA-Leitinien unter "
+        "Berlcksichtigung "
+        "der OGAW- Richtlinie hat die Gesellschaft Mitarbeiter mit wesentlichem Einfluss auf das Risikoprofil der "
+        'Gesellschaft ermittelt GRisikotrâger"). Das Identifi-enungsveariahren basiert auf der Bewertung des '
+        "Einflusses folgender Kategorien von Mitarbeitern auf das Risikoprofil der Gesellschaft oder einen von "
+        "ihr verwalteten Fonds: (a) GeschaitstlhungSenion Management, (b) Portfolio- Investmentmanager, (c) "
+        "Kontrolfunktionen, (d) Mitarbeiter mit Leitungsfunktionen in Verv waltung, Marketing und Human Resources, "
+        "(e) sonstige Mitarbeiter (Risikotràger) mit wesentlichem Einfluss, ( sonstige Mitarbeiter in der gleichen "
+        "Vergltungsstufe wie sonstige Risikotràger. Mindestens 40 % der W fûr Risikotrâger werden aufgeschoben "
+        "vergeben. Des Weiteren werder fur wichtige Anlageexperten mindestens 50 % sowohl des direkt ausgezahlten "
+        "als auch des aufgeschobenen Teils in Form von aktienbasierten oder fondsbasierten Instrumenten der DWS "
+        "Gruppe gewâhrt. Alle aufgeschobenen Komponenten sind bestimmten Leistungs und Verfilledingungen "
+        "unterworfen, "
+        "um eine angemessene nachtrâgliche Risikoadjustierung zu gewâhr leisten. Bei einem W-Betrag von weniger als "
+        "EUR 50.000 erhalten Risikotrâger ihre gesamte Wi in bar und ohne Aufschub. Zusammenfassung der zur "
+        "Vergitung fur die fur 2018 Jahresdurchschnitt der Mitarbeiterzahl 139 EUR 15.315.952 Gesamtvergltung: "
+        "Fixe Vergutung EUR 13.151.856 Variable Vergitung EUR 2.164.096 davon: Carried Interest EURO "
+        "Gesamtvergltung "
+        "fûr Senior Management EUR 1.468.434 Gesamtvergitung fur sonstige Risikotrâger EUR 324.229 Gesamtvergutung "
+        "fûr Mitarbeiter mit Kontrollfunktionen EUR 554.046 Vergitungsdaten fur Delegierte, an die die Gesellschaft "
+        "Portfolio- oder Riskomamnagemenaufyaben ubertragen hat, sind nicht in der Tabelle erfasst. Unter "
+        "Berlcksichtigung: diverser Verginungsbestanteile entsprechend den Definitionen in den ESMA-Leitinien, die "
+        "Geldzahlungen oder -leistungen (wie Bargeld, Anteile, Optionsscheir Rentenbeitràge) oder Nicht-Idirekte) "
+        "Geldleistungen (wie Gehalsnebenleistungen oder Sondervergitungen fûr Fahrzeuge, Mobiltelefone, usw.) "
+        'umfassen. Senior Management" umfasst nur den der Gesellschaft. Der Vorstand erfllt die als Fuhrungskrâfte '
+        "der Gesellschaft. Ober den hinaus wurden keine Fuhrungskrâfte identifiziert. 22 "
+    )
diff --git a/tests/conftest.py b/tests/conftest.py
index e7358564..b21cc270 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -255,9 +255,9 @@ def fixture_col_sub_cats() -> List[CategoryAnnotation]:
 
 
 @fixture(name="cell_sub_cats")
-def fixture_cell_sub_cats() -> List[
-    Tuple[CategoryAnnotation, CategoryAnnotation, CategoryAnnotation, CategoryAnnotation]
-]:
+def fixture_cell_sub_cats() -> (
+    List[Tuple[CategoryAnnotation, CategoryAnnotation, CategoryAnnotation, CategoryAnnotation]]
+):
     """fixture cell_sub_cats"""
     return deepcopy(Annotations().get_cell_sub_cats())
 
@@ -340,17 +340,17 @@ def fixture_dp_image_fully_segmented(
 
 
 @fixture(name="cell_sub_cats_when_table_fully_tiled")
-def fixture_cell_sub_cats_when_table_fully_tiled() -> List[
-    Tuple[CategoryAnnotation, CategoryAnnotation, CategoryAnnotation, CategoryAnnotation]
-]:
+def fixture_cell_sub_cats_when_table_fully_tiled() -> (
+    List[Tuple[CategoryAnnotation, CategoryAnnotation, CategoryAnnotation, CategoryAnnotation]]
+):
     """fixture cell_sub_cats_when_table_fully_tiled"""
     return deepcopy(Annotations().get_cell_sub_cats_when_table_fully_tiled())
 
 
 @fixture(name="summary_sub_cats_when_table_fully_tiled")
-def fixture_summary_sub_cats_when_table_fully_tiled() -> Tuple[
-    CategoryAnnotation, CategoryAnnotation, CategoryAnnotation, CategoryAnnotation
-]:
+def fixture_summary_sub_cats_when_table_fully_tiled() -> (
+    Tuple[CategoryAnnotation, CategoryAnnotation, CategoryAnnotation, CategoryAnnotation]
+):
     """fixture summary_sub_cats_when_table_fully_tiled"""
     return deepcopy(Annotations().get_summary_sub_cats_when_table_fully_tiled())
 
diff --git a/tests/extern/test_doctrocr.py b/tests/extern/test_doctrocr.py
index 6fd24bec..8f38eca0 100644
--- a/tests/extern/test_doctrocr.py
+++ b/tests/extern/test_doctrocr.py
@@ -42,7 +42,6 @@ def get_mock_word_results(np_img: ImageType, predictor, device) -> List[Detectio
 def get_mock_text_line_results(  # type: ignore
     inputs: List[Tuple[str, ImageType]], predictor, device  # pylint: disable=W0613
 ) -> List[DetectionResult]:
-
     """
     Returns two DetectionResult
     """
diff --git a/tests/mapper/data.py b/tests/mapper/data.py
index 49e0e587..24ee883f 100644
--- a/tests/mapper/data.py
+++ b/tests/mapper/data.py
@@ -782,7 +782,8 @@ def get_first_ann_category(self, as_index: bool = True) -> str:
             return "1"
         return self.categories["1"]
 
-    def get_first_ann_sub_category_header_name(self) -> ObjectTypes:  # pylint: disable=R0201
+    @staticmethod
+    def get_first_ann_sub_category_header_name() -> ObjectTypes:
         """
         category_name of sub category
         """
@@ -794,91 +795,106 @@ def get_last_ann_category_name(self) -> str:
         """
         return self.categories["1"]
 
-    def get_last_ann_sub_category_header_name(self) -> ObjectTypes:  # pylint: disable=R0201
+    @staticmethod
+    def get_last_ann_sub_category_header_name() -> ObjectTypes:
         """
         category_name of sub category
         """
         return CellType.header
 
-    def get_last_ann_sub_category_row_number_id(self) -> str:  # pylint: disable=R0201
+    @staticmethod
+    def get_last_ann_sub_category_row_number_id() -> str:
         """
         row number
         """
         return "1"
 
-    def get_last_ann_sub_category_col_number_id(self) -> str:  # pylint: disable=R0201
+    @staticmethod
+    def get_last_ann_sub_category_col_number_id() -> str:
         """
         col number
         """
         return "1"
 
-    def get_last_ann_sub_category_row_span_id(self) -> str:  # pylint: disable=R0201
+    @staticmethod
+    def get_last_ann_sub_category_row_span_id() -> str:
         """
         row span
         """
         return "1"
 
-    def get_last_ann_sub_category_col_span_id(self) -> str:  # pylint: disable=R0201
+    @staticmethod
+    def get_last_ann_sub_category_col_span_id() -> str:
         """
         col span
         """
         return "1"
 
-    def get_first_ann_sub_category_row_number_id(self) -> str:  # pylint: disable=R0201
+    @staticmethod
+    def get_first_ann_sub_category_row_number_id() -> str:
         """
         row number
         """
         return "14"
 
-    def get_first_ann_sub_category_col_number_id(self) -> str:  # pylint: disable=R0201
+    @staticmethod
+    def get_first_ann_sub_category_col_number_id() -> str:
         """
         col number
         """
         return "9"
 
-    def get_first_ann_sub_category_row_span_id(self) -> str:  # pylint: disable=R0201
+    @staticmethod
+    def get_first_ann_sub_category_row_span_id() -> str:
         """
         row span
         """
         return "1"
 
-    def get_first_ann_sub_category_col_span_id(self) -> str:  # pylint: disable=R0201
+    @staticmethod
+    def get_first_ann_sub_category_col_span_id() -> str:
         """
         col span
         """
         return "1"
 
-    def get_summary_ann_sub_category_rows_id(self) -> str:  # pylint: disable=R0201
+    @staticmethod
+    def get_summary_ann_sub_category_rows_id() -> str:
         """
         number rows
         """
         return "14"
 
-    def get_summary_ann_sub_category_col_id(self) -> str:  # pylint: disable=R0201
+    @staticmethod
+    def get_summary_ann_sub_category_col_id() -> str:
         """
         number cols
         """
         return "9"
 
-    def get_summary_ann_sub_category_row_span_id(self) -> str:  # pylint: disable=R0201
+    @staticmethod
+    def get_summary_ann_sub_category_row_span_id() -> str:
         """
         max row span
         """
         return "1"
 
-    def get_summary_ann_sub_category_col_span_id(self) -> str:  # pylint: disable=R0201
+    @staticmethod
+    def get_summary_ann_sub_category_col_span_id() -> str:
         """
         max col span
         """
         return "5"
 
-    def get_number_of_heads(self) -> int:  # pylint: disable=R0201
+    @staticmethod
+    def get_number_of_heads() -> int:
         """
         number of head cells
         """
         return 10
 
-    def get_number_of_bodies(self) -> int:  # pylint: disable=R0201
+    @staticmethod
+    def get_number_of_bodies() -> int:
         """
         number of body cells
         """
diff --git a/tests/mapper/test_iiitar13k.py b/tests/mapper/test_iiitar13k.py
index de732d33..1ffc5695 100644
--- a/tests/mapper/test_iiitar13k.py
+++ b/tests/mapper/test_iiitar13k.py
@@ -39,7 +39,6 @@ def test_pascal_voc_dict_to_image(
     iiitar13k_category_names_mapping: Dict[str, str],
     iiitar13k_results: IIITar13KJson,
 ) -> None:
-
     """
     testing iiitar13k_to_image is mapping correctly
     """
diff --git a/tests/pipe/test_refine.py b/tests/pipe/test_refine.py
index db64d081..af37cdbe 100644
--- a/tests/pipe/test_refine.py
+++ b/tests/pipe/test_refine.py
@@ -299,8 +299,8 @@ def test_integration_pipeline_component(self, dp_image_fully_segmented_fully_til
         assert len(cells) == 4
         assert row_numbers == {"1", "2"}
         assert col_numbers == {"1", "2"}
-        assert row_spans == {"1", "1", "1", "1"}
-        assert col_spans == {"1", "1", "1", "1"}
+        assert row_spans == {"1"}
+        assert col_spans == {"1"}
         assert summaries_table == ["2", "2", "1", "1"]
         assert isinstance(summary_html, ContainerAnnotation)
         assert summary_html.value == [
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 98858030..1c983e74 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -53,7 +53,7 @@ def collect_datapoint_from_dataflow(
 
     output: List[Any] = []
     if hasattr(df, "reset_state"):
-        df.reset_state()  # type: ignore
+        df.reset_state()
 
     for idx, dp in enumerate(df):
         if max_datapoints is not None: