Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: replace flake8 with ruff #144

Merged
merged 18 commits into from
Jan 7, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
],
"settings": {
"editor.formatOnSave": true,
"[toml]": {
"editor.formatOnSave": false
},
"editor.rulers": [
100
],
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
node-version: "16"

- name: Install @devcontainers/cli
run: npm install --location=global @devcontainers/cli
run: npm install --location=global @devcontainers/cli@0.27.1

- name: Start Dev Container with Python ${{ matrix.python-version }}
env:
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ See [My Package](https://github.com/radix-ai/my-package) for an example of a Pyt

Starting development in My Package is as easy as cloning the repository with `git clone git@github.com:radix-ai/my-package`, opening the cloned repository in [VS Code](https://code.visualstudio.com/) and running <kbd>Ctrl/⌘</kbd> + <kbd>⇧</kbd> + <kbd>P</kbd> → _Remote-Containers: Reopen in Container_ with VS Code's [Remote-Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) to start a [Dev Container](https://code.visualstudio.com/docs/remote/containers).

Alternatively, you can start a Dev Container with [GitHub Codespaces](https://github.com/features/codespaces) in your browser by going to [My Package](https://github.com/radix-ai/my-package), clicking on _Code_, and selecting _Create codespace_.
Alternatively, you can start a Dev Container with [GitHub Codespaces](https://github.com/features/codespaces) in your browser by going to [My Package](https://github.com/radix-ai/my-package), clicking on _Code_, then _Codespaces_, and selecting _Create codespace_.

## 🎁 Features

Expand All @@ -18,8 +18,8 @@ Alternatively, you can start a Dev Container with [GitHub Codespaces](https://gi
- 📦 Packaging and dependency management with [Poetry](https://github.com/python-poetry/poetry)
- 🚚 Installing from and publishing to private package repositories and [PyPI](https://pypi.org/)
- ⚡️ Task running with [Poe the Poet](https://github.com/nat-n/poethepoet)
- ✍️ Code formatting with [absolufy-imports](https://github.com/MarcoGorelli/absolufy-imports), [black](https://github.com/psf/black), [isort](https://github.com/PyCQA/isort), [pyupgrade](https://github.com/asottile/pyupgrade), and [yesqa](https://github.com/asottile/yesqa)
- ✅ Code linting with [pre-commit](https://pre-commit.com/): [bandit](https://github.com/PyCQA/bandit), [darglint](https://github.com/terrencepreilly/darglint), [flake8](https://github.com/PyCQA/flake8), [mypy](https://github.com/python/mypy), [pre-commit-hooks](https://github.com/pre-commit/pre-commit-hooks), [pydocstyle](https://github.com/PyCQA/pydocstyle), [pygrep-hooks](https://github.com/pre-commit/pygrep-hooks), [safety](https://github.com/pyupio/safety), [shellcheck](https://github.com/koalaman/shellcheck), and [typeguard](https://github.com/agronholm/typeguard)
- ✍️ Code formatting with [Absolufy-imports](https://github.com/MarcoGorelli/absolufy-imports), [Black](https://github.com/psf/black), and [Ruff](https://github.com/charliermarsh/ruff)
- ✅ Code linting with [Pre-commit](https://pre-commit.com/), [Mypy](https://github.com/python/mypy), and [Ruff](https://github.com/charliermarsh/ruff)
- 🏷 Optionally follows the [Conventional Commits](https://www.conventionalcommits.org/) standard to automate [Semantic Versioning](https://semver.org/) and [Keep A Changelog](https://keepachangelog.com/) with [Commitizen](https://github.com/commitizen-tools/commitizen)
- 💌 Verified commits with [GPG](https://gnupg.org/)
- ♻️ Continuous integration with [GitHub Actions](https://docs.github.com/en/actions) or [GitLab CI/CD](https://docs.gitlab.com/ee/ci/)
Expand All @@ -34,7 +34,7 @@ Alternatively, you can start a Dev Container with [GitHub Codespaces](https://gi
To create a new Python project with this template:
1. Install the latest [Cruft](https://github.com/cruft/cruft) and [Cookiecutter](https://github.com/cookiecutter/cookiecutter) in your [Python environment](https://github.com/pyenv/pyenv-virtualenv) with:
```sh
pip install --upgrade cruft>=2.11.1 cookiecutter>=2.1.1
pip install --upgrade cruft>=2.12.0 cookiecutter>=2.1.1
```
2. Create a new repository and clone it locally.
3. In the directory that contains the cloned repository, run:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"customizations": {
"vscode": {
"extensions": [
"charliermarsh.ruff",
"ms-python.python",
"ryanluker.vscode-coverage-gutters",
"tamasfe.even-better-toml",
Expand All @@ -19,9 +20,13 @@
"reports/coverage.xml"
],
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.organizeImports": true
},
"editor.formatOnSave": true,
"[toml]": {
"editor.formatOnSave": false
},
"editor.rulers": [
100
],
Expand All @@ -32,12 +37,13 @@
"--configfile",
"pyproject.toml"
],
"python.linting.banditEnabled": true,
"python.linting.flake8Enabled": true,
"python.linting.mypyEnabled": true,
"python.linting.pydocstyleEnabled": true,
"python.terminal.activateEnvironment": false,
"python.testing.pytestEnabled": true,
"ruff.importStrategy": "fromEnvironment",
{%- if cookiecutter.development_environment == "strict" %}
"ruff.logLevel": "warn",
{%- endif %}
"terminal.integrated.defaultProfile.linux": "zsh",
"terminal.integrated.profiles.linux": {
"zsh": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
node-version: 16

- name: Install @devcontainers/cli
run: npm install --location=global @devcontainers/cli
run: npm install --location=global @devcontainers/cli@0.27.1

- name: Start Dev Container
env:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ repos:
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.9.0
hooks:
{%- if cookiecutter.development_environment == "strict" %}
- id: python-check-blanket-noqa
- id: python-check-blanket-type-ignore
{%- endif %}
- id: python-check-mock-methods
- id: python-no-log-warn
- id: python-use-type-annotations
- id: rst-backticks
- id: rst-directive-colons
Expand Down Expand Up @@ -61,28 +56,18 @@ repos:
language: system
stages: [commit-msg]
{%- endif %}
- id: pyupgrade
name: pyupgrade
entry: pyupgrade
args: [--py{{ cookiecutter.python_version|replace(".", "") }}-plus]
require_serial: true
language: system
types: [python]
- id: absolufy-imports
name: absolufy-imports
entry: absolufy-imports
require_serial: true
language: system
types: [python]
- id: yesqa
name: yesqa
entry: yesqa
require_serial: true
language: system
types: [python]
- id: isort
name: isort
entry: isort
- id: ruff
name: ruff
entry: ruff
{%- if cookiecutter.development_environment == "simple" %}
args: [--fix-only]
{%- endif %}
require_serial: true
language: system
types: [python]
Expand All @@ -99,23 +84,7 @@ repos:
args: [--check-sourced]
language: system
types: [shell]
- id: bandit
name: bandit
entry: bandit
args: [--configfile, pyproject.toml]
language: system
types: [python]
{%- endif %}
- id: pydocstyle
name: pydocstyle
entry: pydocstyle
language: system
types: [python]
- id: flake8
name: flake8
entry: flake8
language: system
types: [python]
- id: poetry-check
name: poetry check
entry: poetry check
Expand Down
109 changes: 46 additions & 63 deletions {{ cookiecutter.__package_name_kebab_case }}/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,88 +27,68 @@ version_files = ["pyproject.toml:version"]
[tool.poetry.dependencies] # https://python-poetry.org/docs/dependency-specification/
{%- if cookiecutter.with_fastapi_api|int %}
coloredlogs = "^15.0.1"
fastapi = "^0.78.0"
fastapi = { extras = ["all"], version = "^0.88.0" }
gunicorn = "^20.1.0"
{%- endif %}
{%- if cookiecutter.with_fastapi_api|int or cookiecutter.with_streamlit_app|int %}
poethepoet = "^0.16.0"
poethepoet = "^0.17.1"
{%- endif %}
{%- if cookiecutter.with_pydantic_typing|int %}
pydantic = "^1.9.1"
pydantic = "^1.10.4"
{%- endif %}
python = "^{{ cookiecutter.python_version }}"
{%- if cookiecutter.with_sentry_logging|int %}
sentry-sdk = "^1.6.0"
sentry-sdk = "^1.12.1"
{%- endif %}
{%- if cookiecutter.with_streamlit_app|int %}
streamlit = "^1.10.0"
streamlit = "^1.16.0"
{%- endif %}
{%- if cookiecutter.with_typer_cli|int %}
typer = { extras = ["all"], version = "^0.6.1" }
typer = { extras = ["all"], version = "^0.7.0" }
{%- endif %}
{%- if cookiecutter.with_fastapi_api|int %}
uvicorn = { extras = ["standard"], version = "^0.18.2" }
uvicorn = { extras = ["standard"], version = "^0.20.0" }
{%- endif %}

[tool.poetry.group.test.dependencies] # https://python-poetry.org/docs/master/managing-dependencies/
absolufy-imports = "^0.3.1"
{%- if cookiecutter.development_environment == "strict" %}
bandit = { extras = ["toml"], version = "^1.7.4" }
{%- if cookiecutter.with_jupyter_lab|int %}
black = { extras = ["jupyter"], version = "^22.12.0" }
{%- else %}
black = "^22.12.0"
{%- endif %}
black = "^22.6.0"
{%- if cookiecutter.with_conventional_commits|int %}
commitizen = "^2.27.1"
{%- endif %}
coverage = { extras = ["toml"], version = "^6.4.1" }
darglint = "^1.8.1"
flake8 = "^5.0.4"
flake8-bugbear = "^22.6.22"
flake8-comprehensions = "^3.10.0"
flake8-mutable = "^1.2.0"
{%- if cookiecutter.development_environment == "strict" %}
flake8-print = "^5.0.0"
commitizen = "^2.39.1"
{%- endif %}
Flake8-pyproject = "^1.1.0"
flake8-pytest-style = "^1.6.0"
flake8-rst-docstrings = "^0.2.6"
flake8-tidy-imports = "^4.8.0"
isort = "^5.10.1"
mypy = "^0.961"
pep8-naming = "^0.13.0"
coverage = { extras = ["toml"], version = "^7.0.3" }
mypy = "^0.991"
{%- if not cookiecutter.with_fastapi_api|int and not cookiecutter.with_streamlit_app|int %}
poethepoet = "^0.16.0"
poethepoet = "^0.17.1"
{%- endif %}
pre-commit = "^2.19.0"
pydocstyle = { extras = ["toml"], version = "^6.1.1" }
pytest = "^7.1.2"
pre-commit = "^2.21.0"
pytest = "^7.2.0"
pytest-clarity = "^1.0.1"
pytest-mock = "^3.8.1"
pytest-xdist = "^2.5.0"
pyupgrade = "^2.34.0"
pytest-mock = "^3.10.0"
pytest-xdist = "^3.1.0"
ruff = "^0.0.213"
{%- if cookiecutter.development_environment == "strict" %}
safety = "^2.1.1"
shellcheck-py = "^0.8.0"
safety = "^2.3.5"
shellcheck-py = "^0.9.0"
typeguard = "^2.13.3"
{%- endif %}
yesqa = "^1.4.0"

[tool.poetry.group.dev.dependencies] # https://python-poetry.org/docs/master/managing-dependencies/
cruft = "^2.11.0"
cruft = "^2.12.0"
{%- if cookiecutter.with_jupyter_lab|int %}
jupyterlab = "^3.4.3"
jupyterlab = "^3.5.2"
{%- endif %}
pdoc = "^12.0.2"
pdoc = "^12.3.0"
{%- if cookiecutter.private_package_repository_name %}

[[tool.poetry.source]] # https://python-poetry.org/docs/repositories/#using-a-private-repository
name = "{{ cookiecutter.private_package_repository_name|slugify }}"
url = "{{ cookiecutter.private_package_repository_url }}"
{%- endif %}
{%- if cookiecutter.development_environment == "strict" %}

[tool.bandit] # https://bandit.readthedocs.io/en/latest/config.html
skips = ["B101"]
{%- endif %}

[tool.black] # https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file
line-length = 100
Expand All @@ -131,21 +111,6 @@ source = ["src"]
[tool.coverage.xml] # https://coverage.readthedocs.io/en/latest/config.html#xml
output = "reports/coverage.xml"

[tool.flake8] # https://flake8.pycqa.org/en/latest/user/options.html#options-and-their-descriptions
color = "always"
docstring_style = "{{ cookiecutter.docstring_style|lower }}"
doctests = true
ignore = ["DAR103", "E203", "E501", "W503"]
max_line_length = 100
max_complexity = 10
strictness = "{% if cookiecutter.development_environment == 'strict' %}short{% else %}long{% endif %}"

[tool.isort] # https://pycqa.github.io/isort/docs/configuration/options.html
color_output = true
line_length = 100
profile = "black"
src_paths = ["src", "tests"]

[tool.mypy] # https://mypy.readthedocs.io/en/latest/config_file.html
junit_xml = "reports/mypy.xml"
{%- if cookiecutter.with_fastapi_api|int or cookiecutter.with_pydantic_typing|int %}
Expand All @@ -171,9 +136,6 @@ warn_required_dynamic_aliases = true
warn_untyped_fields = true
{%- endif %}

[tool.pydocstyle] # http://www.pydocstyle.org/en/latest/usage.html#configuration-files
convention = "{{ cookiecutter.docstring_style|lower }}"

[tool.pytest.ini_options] # https://docs.pytest.org/en/latest/reference/reference.html#ini-options-ref
addopts = "--color=yes --doctest-modules --exitfirst --failed-first{% if cookiecutter.development_environment == 'strict' %} --strict-config --strict-markers --typeguard-packages={{ cookiecutter.__package_name_snake_case }}{% endif %} --verbosity=2 --junitxml=reports/pytest.xml"
{%- if cookiecutter.development_environment == "strict" %}
Expand All @@ -182,6 +144,27 @@ filterwarnings = ["error", "ignore::DeprecationWarning"]
testpaths = ["src", "tests"]
xfail_strict = true

[tool.ruff] # https://github.com/charliermarsh/ruff
fix = true
ignore-init-module-imports = true
line-length = 100
{%- if cookiecutter.development_environment == "strict" %}
select = ["A", "B", "BLE", "C4", "C90", "D", "DTZ", "E", "ERA", "F", "I", "ISC", "N", "PGH", "PIE", "PLC", "PLE", "PLR", "PLW", "PT", "RET", "RUF", "S", "SIM", "T10", "T20", "TID", "UP", "W", "YTT"]
ignore = ["E501", "PGH001", "S101"]
{%- else %}
select = ["A", "B", "C4", "C90", "D", "DTZ", "E", "F", "I", "ISC", "N", "PGH", "PIE", "PLC", "PLE", "PLR", "PLW", "PT", "RET", "RUF", "SIM", "TID", "UP", "W", "YTT"]
ignore = ["E501", "PGH001", "PGH002", "PGH003", "S101"]
{%- endif %}
{%- if cookiecutter.docstring_style|lower == "numpy" %}
extend-ignore = ["D107", "D203", "D212", "D213", "D402", "D413", "D415", "D416", "D417"]
{%- elif cookiecutter.docstring_style|lower == "google" %}
extend-ignore = ["D203", "D204", "D213", "D215", "D400", "D404", "D406", "D407", "D408", "D409", "D413"]
{%- else %}
extend-ignore = ["D203", "D212", "D213", "D214", "D215", "D404", "D405", "D406", "D407", "D408", "D409", "D410", "D411", "D413", "D415", "D416", "D417"]
{%- endif %}
src = ["src", "tests"]
target-version = "py{{ cookiecutter.python_version|replace('.', '') }}"

[tool.poe.tasks] # https://github.com/nat-n/poethepoet
{%- if cookiecutter.with_fastapi_api|int %}

Expand Down