Skip to content

Commit

Permalink
docs: Added minimal docstring sanity check (#686)
Browse files Browse the repository at this point in the history
* docs: Fixed docstrings of doctr/utils

* docs: Fixed docstrings of MASTER

* chore: Added pydocstyle config

* chore: Updated deps

* docs: Updated Makefile & CONTRIBUTING

* ci: Added a docstring check job
  • Loading branch information
fg-mindee committed Dec 9, 2021
1 parent c2af6e9 commit 9c45ba6
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 7 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,22 @@ jobs:
run: |
mypy --version
mypy --config-file mypy.ini doctr/
pydocstyle-py3:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
python: [3.7]
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python }}
architecture: x64
- name: Run isort
run: |
pip install pydocstyle
pydocstyle --version
pydocstyle doctr/
3 changes: 3 additions & 0 deletions .pydocstyle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[pydocstyle]
select = D300,D301,D417
match = .*\.py
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ mypy --config-file mypy.ini doctr/
```
The `mypy.ini` file will be read to check your typing.

#### Docstring format

To keep a sane docstring structure, if you install [pydocstyle](https://github.com/PyCQA/pydocstyle), you can verify your docstrings as follows:

```shell
pydocstyle doctr/
```
The `.pydocstyle` file will be read to configure this operation.


### Modifying the documentation

Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ quality:
isort . -c -v
flake8 ./
mypy doctr/
pydocstyle doctr/

# this target runs checks on all files and potentially modifies some of them
style:
Expand Down
6 changes: 4 additions & 2 deletions doctr/models/recognition/master/pytorch.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ class MASTER(_MASTER, nn.Module):
num_heads: number of heads for the mutli-head attention module
num_layers: number of decoder layers to stack
max_length: maximum length of character sequence handled by the model
input_size: size of the image inputs
dropout: dropout probability of the decoder
input_shape: size of the image inputs
cfg: config dictionary
"""

feature_pe: torch.Tensor
Expand Down Expand Up @@ -263,7 +265,7 @@ def forward(
return_model_output: if True, return logits
return_preds: if True, decode logits
Return:
Returns:
A torch tensor, containing logits
"""

Expand Down
4 changes: 3 additions & 1 deletion doctr/models/recognition/master/tensorflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,9 @@ class MASTER(_MASTER, Model):
num_heads: number of heads for the mutli-head attention module
num_layers: number of decoder layers to stack
max_length: maximum length of character sequence handled by the model
input_size: size of the image inputs
dropout: dropout probability of the decoder
input_shape: size of the image inputs
cfg: config dictionary
"""

def __init__(
Expand Down
9 changes: 9 additions & 0 deletions doctr/utils/fonts.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@


def get_font(font_family: Optional[str] = None, font_size: int = 13) -> ImageFont.ImageFont:
"""Resolves a compatible ImageFont for the system
Args:
font_family: the font family to use
font_size: the size of the font upon rendering
Returns:
the Pillow font
"""

# Font selection
if font_family is None:
Expand Down
25 changes: 24 additions & 1 deletion doctr/utils/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ def update(
Args:
gt: list of groung-truth character sequences
pred: list of predicted character sequences"""
pred: list of predicted character sequences
"""

if len(gt) != len(pred):
raise AssertionError("prediction size does not match with ground-truth labels size")
Expand Down Expand Up @@ -391,6 +392,12 @@ def __init__(
self.reset()

def update(self, gts: np.ndarray, preds: np.ndarray) -> None:
"""Updates the metric
Args:
gts: a set of relative bounding boxes either of shape (N, 4) or (N, 5) if they are rotated ones
preds: a set of relative bounding boxes either of shape (M, 4) or (M, 5) if they are rotated ones
"""

if preds.shape[0] > 0:
# Compute IoU
Expand Down Expand Up @@ -497,6 +504,14 @@ def update(
gt_labels: List[str],
pred_labels: List[str],
) -> None:
"""Updates the metric
Args:
gt_boxes: a set of relative bounding boxes either of shape (N, 4) or (N, 5) if they are rotated ones
pred_boxes: a set of relative bounding boxes either of shape (M, 4) or (M, 5) if they are rotated ones
gt_labels: a list of N string labels
pred_labels: a list of M string labels
"""

if gt_boxes.shape[0] != len(gt_labels) or pred_boxes.shape[0] != len(pred_labels):
raise AssertionError("there should be the same number of boxes and string both for the ground truth "
Expand Down Expand Up @@ -627,6 +642,14 @@ def update(
gt_labels: np.ndarray,
pred_labels: np.ndarray,
) -> None:
"""Updates the metric
Args:
gt_boxes: a set of relative bounding boxes either of shape (N, 4) or (N, 5) if they are rotated ones
pred_boxes: a set of relative bounding boxes either of shape (M, 4) or (M, 5) if they are rotated ones
gt_labels: an array of class indices of shape (N,)
pred_labels: an array of class indices of shape (M,)
"""

if gt_boxes.shape[0] != gt_labels.shape[0] or pred_boxes.shape[0] != pred_labels.shape[0]:
raise AssertionError("there should be the same number of boxes and string both for the ground truth "
Expand Down
3 changes: 2 additions & 1 deletion doctr/utils/visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,14 +305,15 @@ def synthesize_page(
def draw_boxes(
boxes: np.ndarray,
image: np.ndarray,
color: Optional[Tuple] = None,
color: Optional[Tuple[int, int, int]] = None,
**kwargs
) -> None:
"""Draw an array of relative straight boxes on an image
Args:
boxes: array of relative boxes, of shape (*, 4)
image: np array, float32 or uint8
color: color to use for bounding box edges
"""
h, w = image.shape[:2]
# Convert boxes to absolute coords
Expand Down
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"flake8>=3.9.0",
"isort>=5.7.0",
"mypy>=0.812",
"pydocstyle>=6.1.1",
# Docs
"sphinx<3.5.0",
"sphinx-rtd-theme==0.4.3",
Expand Down Expand Up @@ -135,7 +136,8 @@ def deps_list(*pkgs):
extras["quality"] = deps_list(
"flake8",
"isort",
"mypy"
"mypy",
"pydocstyle",
)

extras["docs_specific"] = deps_list(
Expand Down
2 changes: 1 addition & 1 deletion tests/common/test_requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

def test_deps_consistency():

IGNORE = ["flake8", "isort", "mypy", "importlib_metadata", "tensorflow-cpu"]
IGNORE = ["flake8", "isort", "mypy", "pydocstyle", "importlib_metadata", "tensorflow-cpu"]
# Collect the deps from all requirements.txt
REQ_FILES = ["requirements.txt", "requirements-pt.txt", "tests/requirements.txt", "docs/requirements.txt"]
folder = Path(__file__).parent.parent.parent.absolute()
Expand Down

0 comments on commit 9c45ba6

Please sign in to comment.