Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/codestyle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@ jobs:
- uses: pre-commit/action@v3.0.1
with:
extra_args: '--all-files'

- name: Type check with mypy
run: |
pip install mypy numpy
mypy paddleocr/
2 changes: 1 addition & 1 deletion paddleocr/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from ._cli import main


def console_entry() -> int:
def console_entry() -> None:
# See https://docs.python.org/3/library/signal.html#note-on-sigpipe
try:
# Flush output here to force SIGPIPE to be triggered while inside this
Expand Down
10 changes: 8 additions & 2 deletions paddleocr/_abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

import abc
import argparse
from typing import Any


class CLISubcommandExecutor(metaclass=abc.ABCMeta):
@abc.abstractmethod
def add_subparser(self, subparsers):
def add_subparser(
self, subparsers: argparse._SubParsersAction
) -> argparse.ArgumentParser:
raise NotImplementedError

@abc.abstractmethod
def execute_with_args(self, args):
def execute_with_args(self, args: argparse.Namespace) -> None:
raise NotImplementedError
22 changes: 18 additions & 4 deletions paddleocr/_common_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

import argparse
from typing import Any

from paddlex.inference import PaddlePredictorOption
from paddlex.utils.device import get_default_device, parse_device

Expand All @@ -28,7 +33,9 @@
from ._utils.cli import str2bool


def parse_common_args(kwargs, *, default_enable_hpi):
def parse_common_args(
kwargs: dict[str, Any], *, default_enable_hpi: bool | None
) -> dict[str, Any]:
default_vals = {
"device": DEFAULT_DEVICE,
"enable_hpi": default_enable_hpi,
Expand Down Expand Up @@ -57,13 +64,15 @@ def parse_common_args(kwargs, *, default_enable_hpi):
return kwargs


def prepare_common_init_args(model_name, common_args):
def prepare_common_init_args(
model_name: str | None, common_args: dict[str, Any]
) -> dict[str, Any]:
device = common_args["device"]
if device is None:
device = get_default_device()
device_type, _ = parse_device(device)

init_kwargs = {}
init_kwargs: dict[str, Any] = {}
init_kwargs["device"] = device
init_kwargs["use_hpip"] = common_args["enable_hpi"]

Expand Down Expand Up @@ -94,7 +103,12 @@ def prepare_common_init_args(model_name, common_args):
return init_kwargs


def add_common_cli_opts(parser, *, default_enable_hpi, allow_multiple_devices):
def add_common_cli_opts(
parser: argparse.ArgumentParser,
*,
default_enable_hpi: bool | None,
allow_multiple_devices: bool,
) -> None:
if allow_multiple_devices:
help_ = "Device(s) to use for inference, e.g., `cpu`, `gpu`, `npu`, `gpu:0`, `gpu:0,1`. If multiple devices are specified, inference will be performed in parallel. Note that parallel inference is not always supported. By default, GPU 0 will be used if available; otherwise, the CPU will be used."
else:
Expand Down
18 changes: 10 additions & 8 deletions paddleocr/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

DEFAULT_DEVICE = None
DEFAULT_USE_TENSORRT = False
DEFAULT_PRECISION = "fp32"
DEFAULT_ENABLE_MKLDNN = True
DEFAULT_MKLDNN_CACHE_CAPACITY = 10
DEFAULT_CPU_THREADS = 10
SUPPORTED_PRECISION_LIST = ["fp32", "fp16"]
DEFAULT_USE_CINN = False
from __future__ import annotations

DEFAULT_DEVICE: str | None = None
DEFAULT_USE_TENSORRT: bool = False
DEFAULT_PRECISION: str = "fp32"
DEFAULT_ENABLE_MKLDNN: bool = True
DEFAULT_MKLDNN_CACHE_CAPACITY: int = 10
DEFAULT_CPU_THREADS: int = 10
SUPPORTED_PRECISION_LIST: list[str] = ["fp32", "fp16"]
DEFAULT_USE_CINN: bool = False
4 changes: 3 additions & 1 deletion paddleocr/_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

import os

DISABLE_AUTO_LOGGING_CONFIG = (
DISABLE_AUTO_LOGGING_CONFIG: bool = (
os.getenv("PADDLEOCR_DISABLE_AUTO_LOGGING_CONFIG", "0") == "1"
)
18 changes: 11 additions & 7 deletions paddleocr/_models/_doc_vlm.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

import abc
import argparse
from typing import Any

from .._utils.cli import (
get_subcommand_args,
Expand All @@ -25,13 +29,13 @@
class BaseDocVLM(PaddleXPredictorWrapper):
def __init__(
self,
*args,
**kwargs,
):
self._extra_init_args = {}
*args: Any,
**kwargs: Any,
) -> None:
self._extra_init_args: dict[str, Any] = {}
super().__init__(*args, **kwargs)

def _get_extra_paddlex_predictor_init_args(self):
def _get_extra_paddlex_predictor_init_args(self) -> dict[str, Any]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PaddleOCR要求Python 3.8及以上版本,而在py3.8中dict[str, Any]这样的语法是不被支持的,可能需要统一改造下

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里我用了 from __future__ import annotations 预防了这个问题

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我理解这个主要是会导致type hint的lazy evaluation,从而使运行时import模块不会报错,但如果用户在python 3.8手动去eval这些type hint的话,还是会报错的。可以评估一下

return self._extra_init_args


Expand All @@ -40,10 +44,10 @@ class BaseDocVLMSubcommandExecutor(PredictorCLISubcommandExecutor):

@property
@abc.abstractmethod
def wrapper_cls(self):
def wrapper_cls(self) -> type[PaddleXPredictorWrapper]:
raise NotImplementedError

def execute_with_args(self, args):
def execute_with_args(self, args: argparse.Namespace) -> None:
params = get_subcommand_args(args)
params["input"] = self.input_validator(params["input"])
perform_simple_inference(self.wrapper_cls, params)
18 changes: 11 additions & 7 deletions paddleocr/_models/_image_classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

import abc
import argparse
from typing import Any

from .._utils.cli import (
add_simple_inference_args,
Expand All @@ -26,20 +30,20 @@ class ImageClassification(PaddleXPredictorWrapper):
def __init__(
self,
*,
topk=None,
**kwargs,
):
topk: int | None = None,
**kwargs: Any,
) -> None:
self._extra_init_args = {
"topk": topk,
}
super().__init__(**kwargs)

def _get_extra_paddlex_predictor_init_args(self):
def _get_extra_paddlex_predictor_init_args(self) -> dict[str, Any]:
return self._extra_init_args


class ImageClassificationSubcommandExecutor(PredictorCLISubcommandExecutor):
def _update_subparser(self, subparser):
def _update_subparser(self, subparser: argparse.ArgumentParser) -> None:
add_simple_inference_args(subparser)

subparser.add_argument(
Expand All @@ -50,9 +54,9 @@ def _update_subparser(self, subparser):

@property
@abc.abstractmethod
def wrapper_cls(self):
def wrapper_cls(self) -> type[PaddleXPredictorWrapper]:
raise NotImplementedError

def execute_with_args(self, args):
def execute_with_args(self, args: argparse.Namespace) -> None:
params = get_subcommand_args(args)
perform_simple_inference(self.wrapper_cls, params)
26 changes: 15 additions & 11 deletions paddleocr/_models/_object_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

import abc
import argparse
from typing import Any

from .._utils.cli import (
add_simple_inference_args,
Expand All @@ -27,13 +31,13 @@ class ObjectDetection(PaddleXPredictorWrapper):
def __init__(
self,
*,
img_size=None,
threshold=None,
layout_nms=None,
layout_unclip_ratio=None,
layout_merge_bboxes_mode=None,
**kwargs,
):
img_size: int | None = None,
threshold: float | None = None,
layout_nms: bool | None = None,
layout_unclip_ratio: float | None = None,
layout_merge_bboxes_mode: str | None = None,
**kwargs: Any,
) -> None:
self._extra_init_args = {
"img_size": img_size,
"threshold": threshold,
Expand All @@ -43,12 +47,12 @@ def __init__(
}
super().__init__(**kwargs)

def _get_extra_paddlex_predictor_init_args(self):
def _get_extra_paddlex_predictor_init_args(self) -> dict[str, Any]:
return self._extra_init_args


class ObjectDetectionSubcommandExecutor(PredictorCLISubcommandExecutor):
def _update_subparser(self, subparser):
def _update_subparser(self, subparser: argparse.ArgumentParser) -> None:
add_simple_inference_args(subparser)

subparser.add_argument(
Expand Down Expand Up @@ -79,9 +83,9 @@ def _update_subparser(self, subparser):

@property
@abc.abstractmethod
def wrapper_cls(self):
def wrapper_cls(self) -> type[PaddleXPredictorWrapper]:
raise NotImplementedError

def execute_with_args(self, args):
def execute_with_args(self, args: argparse.Namespace) -> None:
params = get_subcommand_args(args)
perform_simple_inference(self.wrapper_cls, params)
25 changes: 15 additions & 10 deletions paddleocr/_models/_text_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,24 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

import argparse
from typing import Any


class TextDetectionMixin:
def __init__(
self,
*,
limit_side_len=None,
limit_type=None,
thresh=None,
box_thresh=None,
unclip_ratio=None,
input_shape=None,
**kwargs,
):
limit_side_len: int | None = None,
limit_type: str | None = None,
thresh: float | None = None,
box_thresh: float | None = None,
unclip_ratio: float | None = None,
input_shape: tuple[int, int, int] | None = None,
**kwargs: Any,
) -> None:
self._extra_init_args = {
"limit_side_len": limit_side_len,
"limit_type": limit_type,
Expand All @@ -35,12 +40,12 @@ def __init__(
}
super().__init__(**kwargs)

def _get_extra_paddlex_predictor_init_args(self):
def _get_extra_paddlex_predictor_init_args(self) -> dict[str, Any]:
return self._extra_init_args


class TextDetectionSubcommandExecutorMixin:
def _add_text_detection_args(self, subparser):
def _add_text_detection_args(self, subparser: argparse.ArgumentParser) -> None:
subparser.add_argument(
"--limit_side_len",
type=int,
Expand Down
Loading
Loading