Skip to content
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: 2 additions & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Changes here will be overwritten by Copier
_commit: v0.0.71
_commit: v0.0.73
_src_path: gh:LabAutomationAndScreening/copier-base-template.git
description: Copier template for creating Python libraries and executables
python_ci_versions:
Expand All @@ -8,6 +8,7 @@ python_ci_versions:
python_version: 3.12.7
repo_name: copier-python-package-template
repo_org_name: LabAutomationAndScreening
repo_org_name_for_copyright: Lab Automation & Screening
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Quote value containing an ampersand to avoid YAML parsing edge cases.

Safer to quote strings with “&” to prevent any anchor parsing quirks.

Apply this diff:

-repo_org_name_for_copyright: Lab Automation & Screening
+repo_org_name_for_copyright: "Lab Automation & Screening"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
repo_org_name_for_copyright: Lab Automation & Screening
repo_org_name_for_copyright: "Lab Automation & Screening"
🤖 Prompt for AI Agents
In .copier-answers.yml around line 11, the value repo_org_name_for_copyright
contains an ampersand and must be quoted to avoid YAML interpreting it as an
anchor; update the line so the string is wrapped in quotes (single or double) —
e.g. change to repo_org_name_for_copyright: "Lab Automation & Screening" —
ensuring proper YAML quoting and saving the file.

ssh_port_number: 55874
template_might_want_to_install_aws_ssm_port_forwarding_plugin: true
template_uses_javascript: false
Expand Down
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,5 @@
"initializeCommand": "sh .devcontainer/initialize-command.sh",
"onCreateCommand": "sh .devcontainer/on-create-command.sh",
"postStartCommand": "sh .devcontainer/post-start-command.sh"
// Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): 86b774f4 # spellchecker:disable-line
// Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): a57008fa # spellchecker:disable-line
}
6 changes: 3 additions & 3 deletions .devcontainer/install-ci-tooling.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import tempfile
from pathlib import Path

UV_VERSION = "0.8.17"
PNPM_VERSION = "10.16.1"
UV_VERSION = "0.8.19"
PNPM_VERSION = "10.17.1"
COPIER_VERSION = "9.10.2"
COPIER_TEMPLATE_EXTENSIONS_VERSION = "0.3.3"
PRE_COMMIT_VERSION = "4.3.0"
Expand Down Expand Up @@ -65,7 +65,7 @@ def main():
)
else:
_ = subprocess.run(
f"curl -fsSL https://astral.sh/uv/{UV_VERSION}/install.sh | sh",
f"curl -fsSL --connect-timeout 20 --max-time 40 --retry 3 --retry-delay 5 --retry-connrefused --proto '=https' https://astral.sh/uv/{UV_VERSION}/install.sh | sh",
check=True,
shell=True,
env=uv_env,
Expand Down
2 changes: 2 additions & 0 deletions .github/reusable_workflows/build-docker-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ jobs:

- name: Checkout code
uses: actions/checkout@v5.0.0
with:
persist-credentials: false

- name: OIDC Auth for ECR
if: ${{ inputs.push-role-name != 'no-push' }}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v5.0.0
with:
persist-credentials: false

- name: Move python script that replaces private package registry information to temp folder so it doesn't get deleted
run: |
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/get-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ jobs:
dependabot-commit-created: ${{ steps.update-hash.outputs.commit-created }}
pr-short-num: ${{ steps.find-pr-num.outputs.number }}
steps:
- name: Display full GitHub context
run: echo '${{ toJSON(github) }}'

- name: Checkout code
uses: actions/checkout@v5.0.0
with:
persist-credentials: false

- name: Update Devcontainer Hash
if: ${{ github.actor == 'dependabot[bot]' && github.event_name == 'push' }}
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/pre-commit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ jobs:
uses: actions/checkout@v5.0.0
with:
ref: ${{ github.ref_name }} # explicitly get the head of the branch, which will include any new commits pushed if this is a dependabot branch
persist-credentials: false

- name: Checkout code not during push
if: ${{ github.event_name != 'push' }}
uses: actions/checkout@v5.0.0
with:
persist-credentials: false

- name: Install latest versions of packages
uses: ./.github/actions/install_deps
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/tag-on-merge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ jobs:
with:
ref: ${{ github.event.pull_request.merge_commit_sha }}
fetch-depth: '0'
persist-credentials: false
- name: Bump version and push tag
uses: mathieudutour/github-tag-action@v6.2
uses: mathieudutour/github-tag-action@a22cf08638b34d5badda920f9daf6e72c477b07b # v6.2
Copy link

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

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

Using a commit SHA for GitHub Actions is a good security practice, but the comment indicates this should be v6.2. Verify that the SHA a22cf08638b34d5badda920f9daf6e72c477b07b actually corresponds to the v6.2 release tag.

Copilot uses AI. Check for mistakes.
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
5 changes: 5 additions & 0 deletions .github/zizmor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
rules:
template-injection:
ignore:
# this is just echo-ing out the github context to be visible for debugging, it's not executing commands
- get-values.yaml:28
Comment on lines +1 to +5
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Tighten ignore path to match the template file precisely.

The ignore entry references get-values.yaml:28; the changed file lives under template/.github/workflows. Use the full path to avoid a mis‑match.

Apply this diff:

-      - get-values.yaml:28
+      - template/.github/workflows/get-values.yaml:28
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
rules:
template-injection:
ignore:
# this is just echo-ing out the github context to be visible for debugging, it's not executing commands
- get-values.yaml:28
rules:
template-injection:
ignore:
# this is just echo-ing out the github context to be visible for debugging, it's not executing commands
- template/.github/workflows/get-values.yaml:28
🤖 Prompt for AI Agents
.github/zizmor.yml lines 1-5: the ignore path "get-values.yaml:28" is too broad
and doesn't include the template directory; update the ignore entry to the full
path "template/.github/workflows/get-values.yaml:28" so it precisely matches the
template file location.

19 changes: 15 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ repos:
.*pyrightconfig\.json|
)$

- repo: https://github.com/pre-commit/mirrors-prettier # TODO: switch to a different approach...this was archived in 2024
rev: f12edd9c7be1c20cfa42420fd0e6df71e42b51ea # frozen: v4.0.0-alpha.8
- repo: https://github.com/rbubley/mirrors-prettier
rev: 5ba47274f9b181bce26a5150a725577f3c336011 # frozen: v3.6.2
hooks:
- id: prettier
# TODO: get template YAML and MD files more in line with prettier expectations so we can start using prettier on those too
Expand All @@ -125,6 +125,7 @@ repos:
.*/vendor_files/.*|
.*/schema.graphql|
.*generated/graphql.ts|
template/.*|
)$
files: (.*.json)|(.*.ts)|(.*.jsx)|(.*.tsx)|(.*.yaml)|(.*.yml)|(.*.md)|(.*.html)|(.*.css)|(.*.scss)|(.*.less)|(.*.vue)|(.*.graphql)|(.*.gql)

Expand Down Expand Up @@ -178,6 +179,11 @@ repos:
- id: check-merge-conflict
- id: check-case-conflict

- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 83987cd6ad8943c7f029b500b14aaf82c00a01fa # frozen: 0.34.0
hooks:
- id: check-github-workflows

- repo: https://github.com/maresb/check-json5
rev: 893a2b5a0a27c3540bd8fcafe2968ccc05237179 # 1.0
hooks:
Expand Down Expand Up @@ -205,6 +211,11 @@ repos:
hooks:
- id: detect-private-key

# - repo: https://github.com/woodruffw/zizmor-pre-commit # TODO: implement this: https://github.com/LabAutomationAndScreening/copier-base-template/issues/95
# rev: b933184438555436e38621f46ceb0c417cbed400 # frozen: v1.13.0
# hooks:
# - id: zizmor

# Linting

- repo: https://github.com/Lucas-C/pre-commit-hooks-markup
Expand All @@ -215,15 +226,15 @@ repos:
exclude: docs/.*\.rst$

- repo: https://github.com/hadolint/hadolint
rev: 87de847754330ad47ae16bdfe2d1a757ccb4b4d4 # frozen: v2.13.1
rev: 4e697ba704fd23b2409b947a319c19c3ee54d24f # frozen: v2.14.0
hooks:
- id: hadolint-docker
name: Lint Dockerfiles
exclude: .*\.jinja$
description: Runs hadolint to lint Dockerfiles

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 13a6bda8ea7612b3aec844ded16569d424b9a1ab # frozen: v0.13.0
rev: a113f03edeabb71305f025e6e14bd2cd68660e29 # frozen: v0.13.1
hooks:
- id: ruff
name: ruff-src
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# Usage
To create a new repository using this template:
1. Create a basic devcontainer either using the Codespaces default or using the file `.devcontainer/devcontainer-to-instantiate-template.json` from [the base template repo](https://github.com/LabAutomationAndScreening/copier-base-template/blob/main/.devcontainer/devcontainer-to-instantiate-template.json)
1. Inside that devcontainer, run `python .devcontainer/install-ci-tooling.py` to install necessary tooling to instantiate the template (you can copy/paste the script from this
1. Inside that devcontainer, run `python .devcontainer/install-ci-tooling.py` to install necessary tooling to instantiate the template (you can copy/paste the script from this repo...and you can paste it in the root of the repo if you want)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Clarify path if script is moved to repo root and tighten wording.

Apply this diff:

-1. Inside that devcontainer, run `python .devcontainer/install-ci-tooling.py` to install necessary tooling to instantiate the template (you can copy/paste the script from this repo...and you can paste it in the root of the repo if you want)
+1. Inside that devcontainer, run `python .devcontainer/install-ci-tooling.py` to install necessary tooling to instantiate the template. You can copy the script from this repo; if you place it at the repository root, run `python install-ci-tooling.py` instead.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
1. Inside that devcontainer, run `python .devcontainer/install-ci-tooling.py` to install necessary tooling to instantiate the template (you can copy/paste the script from this repo...and you can paste it in the root of the repo if you want)
1. Inside that devcontainer, run `python .devcontainer/install-ci-tooling.py` to install necessary tooling to instantiate the template. You can copy the script from this repo; if you place it at the repository root, run `python install-ci-tooling.py` instead.
🤖 Prompt for AI Agents
In README.md around line 10, the instruction about running python
.devcontainer/install-ci-tooling.py is ambiguous if the script is copied to the
repo root and wording is loose; update the sentence to explicitly state both
paths and tighten phrasing: show the primary command using
.devcontainer/install-ci-tooling.py and add an alternative command for running
the script if placed in the repository root (./install-ci-tooling.py), clarify
that you can copy the script from this repository into either location, and
reword to a concise imperative (e.g., "Run ... to install the required tooling;
you may copy the script from this repository to .devcontainer/ or to the
repository root and run the appropriate path").

1. Delete all files currently in the repository. Optional...but makes it easiest to avoid git conflicts.
1. Run copier to instantiate the template: `copier copy --trust gh:LabAutomationAndScreening/copier-python-package-template.git .`
1. Run `python .devcontainer/manual-setup-deps.py --only-create-lock` to generate the lock file(s)
Expand Down
19 changes: 13 additions & 6 deletions extensions/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class ContextUpdater(ContextHook):

@override
def hook(self, context: dict[Any, Any]) -> dict[Any, Any]:
context["uv_version"] = "0.8.17"
context["pnpm_version"] = "10.16.1"
context["uv_version"] = "0.8.19"
context["pnpm_version"] = "10.17.1"
context["pre_commit_version"] = "4.3.0"
context["pyright_version"] = "1.1.405"
context["pytest_version"] = "8.4.2"
Expand All @@ -20,7 +20,7 @@ def hook(self, context: dict[Any, Any]) -> dict[Any, Any]:
context["copier_version"] = "9.10.2"
context["copier_template_extensions_version"] = "0.3.3"
context["sphinx_version"] = "8.1.3"
context["pulumi_version"] = "3.196.0"
context["pulumi_version"] = "3.197.0"
context["pulumi_aws_version"] = "7.7.0"
context["pulumi_aws_native_version"] = "1.33.0"
context["pulumi_command_version"] = "1.1.0"
Expand All @@ -32,12 +32,13 @@ def hook(self, context: dict[Any, Any]) -> dict[Any, Any]:
context["pyinstaller_version"] = "6.16.0"
context["setuptools_version"] = "80.7.1"
context["strawberry_graphql_version"] = "0.282.0"
context["fastapi_version"] = "0.116.1"
context["fastapi_version"] = "0.117.1"
context["fastapi_offline_version"] = "1.7.4"
context["uvicorn_version"] = "0.35.0"
context["uvicorn_version"] = "0.36.0"
context["lab_auto_pulumi_version"] = "0.1.16"
context["ariadne_codegen_version"] = "0.15.2"
context["pytest_mock_version"] = "3.15.0"
context["uuid_utils_version"] = "0.11.0"

context["node_version"] = "24.7.0"
context["nuxt_ui_version"] = "^3.3.3"
Expand All @@ -56,12 +57,18 @@ def hook(self, context: dict[Any, Any]) -> dict[Any, Any]:
context["nuxt_eslint_version"] = "^1.9.0"
context["zod_version"] = "^4.1.5"
context["zod_from_json_schema_version"] = "^0.5.0"
context["types_node_version"] = "^24.3.1"
context["types_node_version"] = "^24.5.1"
context["nuxt_apollo_version"] = "5.0.0-alpha.15"
context["graphql_codegen_cli_version"] = "^6.0.0"
context["graphql_codegen_typescript_version"] = "^5.0.0"
context["graphql_codegen_typescript_operations_version"] = "^5.0.0"
context["tailwindcss_version"] = "^4.1.11"
context["iconify_vue_version"] = "^5.0.0"
context["iconify_json_lucide_version"] = "^1.2.68"
context["nuxt_fonts_version"] = "^0.11.4"
context["nuxtjs_color_mode_version"] = "^3.5.2"
context["vue_test_utils_version"] = "^2.4.6"
context["nuxt_test_utils_version"] = "^3.17.2"

context["gha_checkout"] = "v5.0.0"
context["gha_setup_python"] = "v6.0.0"
Expand Down
1 change: 1 addition & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ ignore = [
"D102", # Docstrings are not always necessary for public methods
"D103", # Docstrings are not always necessary for public functions
"D104", # Docstrings are not always necessary for public packages
"D105", # Docstrings are not always necessary for magic methods
"D106", # Nested classes are usually library-specific and don't always require its own docstring
"D107", # Init shouldn't need its own docstring, those arguments can be captured in the class level docstring
"D203", # Ignore D203 because it's a bug https://github.com/PyCQA/pydocstyle/issues/141
Expand Down
2 changes: 1 addition & 1 deletion template/.devcontainer/install-ci-tooling.py.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def main():
)
else:
_ = subprocess.run(
f"curl -fsSL https://astral.sh/uv/{UV_VERSION}/install.sh | sh",
f"curl -fsSL --connect-timeout 20 --max-time 40 --retry 3 --retry-delay 5 --retry-connrefused --proto '=https' https://astral.sh/uv/{UV_VERSION}/install.sh | sh",
check=True,
shell=True,
env=uv_env,
Expand Down
5 changes: 5 additions & 0 deletions template/.github/workflows/get-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ jobs:
dependabot-commit-created: ${{ steps.update-hash.outputs.commit-created }}
pr-short-num: ${{ steps.find-pr-num.outputs.number }}
steps:
- name: Display full GitHub context
run: echo '${{ toJSON(github) }}'

Comment on lines +27 to +29
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Gate the GitHub context dump to avoid noisy logs and potential metadata leakage.

Restrict to trusted events or an explicit debug flag.

Apply this diff to add a guard on the step:

-      - name: Display full GitHub context
-        run: echo '${{ toJSON(github) }}'
+      - name: Display full GitHub context
+        if: ${{ (github.event_name != 'pull_request' && github.event_name != 'pull_request_target') && (inputs.debug || env.ACTIONS_STEP_DEBUG == 'true') }}
+        run: echo '${{ toJSON(github) }}'

And add this input at the top (outside this hunk) so callers can enable when needed:

# under on.workflow_call.inputs
  debug:
    description: 'Enable verbose context logging'
    type: boolean
    default: false
🤖 Prompt for AI Agents
In template/.github/workflows/get-values.yaml around lines 27 to 29, the
workflow unconditionally echoes the entire GitHub context which can leak
metadata and create noisy logs; add a workflow_call input named debug (boolean,
default false) at the top under on.workflow_call.inputs and modify the Display
full GitHub context step to run only when either inputs.debug is true or the
event is a trusted event (e.g., github.event_name in a whitelist or specific
actor/permission checks); implement the condition using the workflow expression
(inputs.debug == 'true' || <trusted-event-check>) so the echo runs only when
explicitly enabled or for trusted events.

- name: Checkout code
uses: actions/checkout@v5.0.0
with:
persist-credentials: false

- name: Update Devcontainer Hash
if: ${{ github.actor == 'dependabot[bot]' && github.event_name == 'push' }}
Expand Down
3 changes: 3 additions & 0 deletions template/.github/workflows/pre-commit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ jobs:
uses: actions/checkout@v5.0.0
with:
ref: ${{ github.ref_name }} # explicitly get the head of the branch, which will include any new commits pushed if this is a dependabot branch
persist-credentials: false

- name: Checkout code not during push
if: ${{ github.event_name != 'push' }}
uses: actions/checkout@v5.0.0
with:
persist-credentials: false

- name: Install latest versions of packages
uses: ./.github/actions/install_deps
Expand Down
19 changes: 15 additions & 4 deletions template/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ repos:
.*pyrightconfig\.json|
)$

- repo: https://github.com/pre-commit/mirrors-prettier # TODO: switch to a different approach...this was archived in 2024
rev: f12edd9c7be1c20cfa42420fd0e6df71e42b51ea # frozen: v4.0.0-alpha.8
- repo: https://github.com/rbubley/mirrors-prettier
rev: 5ba47274f9b181bce26a5150a725577f3c336011 # frozen: v3.6.2
hooks:
- id: prettier
# TODO: get template YAML and MD files more in line with prettier expectations so we can start using prettier on those too
Expand All @@ -125,6 +125,7 @@ repos:
.*/vendor_files/.*|
.*/schema.graphql|
.*generated/graphql.ts|
template/.*|
)$
files: (.*.json)|(.*.ts)|(.*.jsx)|(.*.tsx)|(.*.yaml)|(.*.yml)|(.*.md)|(.*.html)|(.*.css)|(.*.scss)|(.*.less)|(.*.vue)|(.*.graphql)|(.*.gql)

Expand Down Expand Up @@ -178,6 +179,11 @@ repos:
- id: check-merge-conflict
- id: check-case-conflict

- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 83987cd6ad8943c7f029b500b14aaf82c00a01fa # frozen: 0.34.0
hooks:
- id: check-github-workflows

- repo: https://github.com/maresb/check-json5
rev: 893a2b5a0a27c3540bd8fcafe2968ccc05237179 # 1.0
hooks:
Expand Down Expand Up @@ -205,6 +211,11 @@ repos:
hooks:
- id: detect-private-key

# - repo: https://github.com/woodruffw/zizmor-pre-commit # TODO: implement this: https://github.com/LabAutomationAndScreening/copier-base-template/issues/95
# rev: b933184438555436e38621f46ceb0c417cbed400 # frozen: v1.13.0
# hooks:
# - id: zizmor

# Linting

- repo: https://github.com/Lucas-C/pre-commit-hooks-markup
Expand All @@ -215,15 +226,15 @@ repos:
exclude: docs/.*\.rst$

- repo: https://github.com/hadolint/hadolint
rev: 87de847754330ad47ae16bdfe2d1a757ccb4b4d4 # frozen: v2.13.1
rev: 4e697ba704fd23b2409b947a319c19c3ee54d24f # frozen: v2.14.0
hooks:
- id: hadolint-docker
name: Lint Dockerfiles
exclude: .*\.jinja$
description: Runs hadolint to lint Dockerfiles

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 13a6bda8ea7612b3aec844ded16569d424b9a1ab # frozen: v0.13.0
rev: a113f03edeabb71305f025e6e14bd2cd68660e29 # frozen: v0.13.1
hooks:
- id: ruff
name: ruff-src
Expand Down
1 change: 1 addition & 0 deletions template/ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ ignore = [
"D102", # Docstrings are not always necessary for public methods
"D103", # Docstrings are not always necessary for public functions
"D104", # Docstrings are not always necessary for public packages
"D105", # Docstrings are not always necessary for magic methods
"D106", # Nested classes are usually library-specific and don't always require its own docstring
"D107", # Init shouldn't need its own docstring, those arguments can be captured in the class level docstring
"D203", # Ignore D203 because it's a bug https://github.com/PyCQA/pydocstyle/issues/141
Expand Down