Skip to content

Commit

Permalink
Add initial code and config (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsh9 authored May 15, 2023
1 parent 6e5d819 commit bd95413
Show file tree
Hide file tree
Showing 43 changed files with 4,322 additions and 2 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Python package

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: tox
run: |
python -m pip install --upgrade pip
python -m pip install tox
tox
39 changes: 39 additions & 0 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Upload Python Package

on:
release:
types: [published]

permissions:
contents: read

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,4 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.idea/
23 changes: 23 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
repos:
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort

- repo: https://github.com/jsh9/cercis
rev: 0.1.5
hooks:
- id: cercis
args: [--extend-exclude=^.*tests/data.*\.py$]

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.7.1
hooks:
- id: prettier
exclude: .*\.ya?ml

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
141 changes: 140 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,141 @@
# pydoclint
A linter to check arguments in Python docstrings

A Python docstring linter to check whether a docstring's sections (arguments, returns, raises, ...) match the function signature or function implementation.

It runs really fast. In fact, it is at least 30,000 times faster than [darglint](https://github.com/terrencepreilly/darglint) (another linter of the same purposes which is no longer maintained).

Here is a comparison of running time on some famous Python projects:

| | pydoclint | darglint |
| ------------------------------------------------------------ | --------- | -------------------- |
| [numpy](https://github.com/numpy/numpy) | 0.08 sec | > 40 min (> 30,000x) |
| [scikit-learn](https://github.com/scikit-learn/scikit-learn) | 0.09 sec | > 40 min (> 30,000x) |

Currently, `pydoclint` only works when you write your docstrings in the [numpy stlyle](https://numpydoc.readthedocs.io/en/latest/format.html). Support for the [Google style](https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html) docstrings will be added soon.

## 1. Installation

```
pip install pydoclint
```

Note that `pydoclint` only supports Python 3.8 and above.

## 2. Usage

### 2.1. As a standalone command line tool

```
pydoclint <FILE_OR_FOLDER>
```

Replace `<FILE_OR_FOLDER>` with the file/folder names you want, such as `.`.

### 2.2. As a flake8 plugin

Once you install `pydoclint` you will have also installed `flake8`. Then you can run:

```
flake8 --select=DOC <FILE_OR_FOLDER>
```

If you don't include `--select=DOC` in your command, `flake8` will also run other built-in flake8 linters on your code.

## 3. Style violation codes

`pydoclint` currently has the following style violation codes:

### 3.1. `DOC1xx`: Violations about input arguments

| Code | Explanation |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `DOC101` | Docstring contains fewer arguments than in function signature |
| `DOC102` | Docstring contains more arguments than in function signature |
| `DOC103` | Docstring arguments are different from function arguments. (Or did you miss the space between the argument name and the ":" in the docstring?) |
| `DOC104` | Arguments are the same in the docstring and the function signature, but are in a different order. |
| `DOC105` | Argument names match, but type hints do not match |

### 3.2. `DOC2xx`: Violations about return argument(s)

| Code | Explanation |
| -------- | ---------------------------------------------------------------------------------------------------- |
| `DOC201` | Function/method does not have a return section in docstring |
| `DOC202` | Function/method has a return section in docstring, but there are no return statements or annotations |

### 3.3. `DOC3xx`: Violations about class docstring and class constructor

| Code | Explanation |
| -------- | ------------------------------------------------------------------------------------------- |
| `DOC301` | `__init__()` should not have a docstring; please combine it with the docstring of the class |
| `DOC302` | The docstring for the class does not need a "Returns" sections |

### 3.4. `DOC4xx`: Violations about "yield" statements

| Code | Explanation |
| -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `DOC401` | Function/method returns a Generator, but the docstring does not have a "Yields" section |
| `DOC402` | Function/method has "yield" statements, but the docstring does not have a "Yields" section |
| `DOC403` | Function/method has a "Yields" section in the docstring, but there are no "yield" statements or a Generator return annotation |

### 3.5. `DOC5xx`: Violations about "raise" statements

| Code | Explanation |
| -------- | --------------------------------------------------------------------------------------------------------- |
| `DOC501` | Function/method has "raise" statements, but the docstring does not have a "Raises" section |
| `DOC502` | Function/method has a "Raises" section in the docstring, but there are not "raise" statements in the body |

## 4. Configuration options

There are several configuration options available. They can be used invidually or together.

### 4.1. `--check-type-hint` (shortform: `-th`, default: `True`)

If `True`, the type hints in the docstring and in the Python code need to exactly match.

To turn this optoin on/off, do this:

```
pydoclint --check-type-hint=False <FILE_OR_FOLDER>
```

or

```
flake8 --check-type-hint=False <FILE_OR_FOLDER>
```

### 4.2. `--check-arg-order` (shortform: `-ao`, default: `True`)

If `True`, the input argument order in the docstring needs to match that in the function signature.

To turn this optoin on/off, do this:

```
pydoclint --check-arg-order=False <FILE_OR_FOLDER>
```

or

```
flake8 --check-arg-order=False <FILE_OR_FOLDER>
```

### 4.3. `--skip-checking-short-docstrings` (shortform: `-scsd`, default: `True`)

If `True`, `pydoclint` won't check functions that have only a short description in their docstring.

To turn this optoin on/off, do this:

```
pydoclint --skip-checking-short-docstrings=False <FILE_OR_FOLDER>
```

or

```
flake8 --skip-checking-short-docstrings=False <FILE_OR_FOLDER>
```

### 4.4. `--skip-checking-raises` (shortform: `-scr`, default: `False`)

If `True`, `pydoclint` won't report `DOC501` or `DOC502` if there are `raise` statements in the function/method but there aren't any "raises" sections in the docstring (or vice versa).
1 change: 1 addition & 0 deletions pydoclint/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = '0.1.0'
Loading

0 comments on commit bd95413

Please sign in to comment.