From 1b9396a2c60b7e118b9c3440120da6f7fe526144 Mon Sep 17 00:00:00 2001 From: Andrew Vaillancourt Date: Tue, 11 Feb 2025 15:48:04 -0500 Subject: [PATCH] Enforce docstring standards and update pre-commit - Enforce Google-style docstrings in pre-commit hooks: - Add pydocstyle, pydoclint, and interrogate to Pipenv and pre-commit - Configure pydocstyle for PEP 257 and Google-style compliance - Set pydoclint to enforce function signature correctness - Ensure 100% function and class docstring coverage with interrogate: - There are some exceptions, e.g. init, module-level. - More exceptions can be added if the tooling is found to be too strict. - Refine Black hook ordering to ensure all hooks run on formatted files: - Fail commit if formatting is needed (--check) - Auto-format files in a separate step - Prevent bypassing docstring checks by staging unformatted files - Ensure return type consistency (DOC203 best practices): - Require both return type hints (-> type) and docstring return types - Explain rationale for requiring both: - Type hints help with static analysis and runtime type checking - Docstring return types improve readability and documentation clarity - Pre-commit hooks validate consistency across both formats - Update pre-commit hooks to explicitly check for this requirement - Restructure pre-commit and linting configuration: - Move .pydocstyle.ini, .flake8, and pyproject.toml to the root - Update pre-commit hooks to reference these configs in the new structure - Modify tox.ini to prevent packaging errors and improve workflow: - Add `skipsdist = True` to disable setuptools packaging - Set `usedevelop = False` to prevent unintended package installation - Ensure `tox` only runs documentation and linting tasks - Aligns with StarlingX repository standards and prevents conflicts - Retain the pre-commit/ directory for potential future hooks - Update documentation and improve contributor guidance: - Add CONTRIBUTING.rst with detailed contribution guidelines - Create contributors.rst in doc/source for Sphinx-rendered docs - Link contributors.rst in index.rst for visibility in generated docs - Ensure contributing.rst references the latest CONTRIBUTING.rst - Document VSCode and PyCharm auto-doc settings in CONTRIBUTING.rst This commit ensures consistent docstring enforcement, improves pre-commit integration, aligns with best practices, and enhances contributor documentation. Change-Id: Iba282c20502adb81a7739ec6c3ed8b6f3bc45077 Signed-off-by: Andrew Vaillancourt --- pre-commit/.flake8 => .flake8 | 7 +- .pre-commit-config.yaml | 82 +++++-- CONTRIBUTING.rst | 223 ++++++++++++++++++++ Pipfile | 5 + Pipfile.lock | 133 +++++++++--- README.rst | 28 +-- doc/source/contributing.rst | 9 + doc/source/index.rst | 19 +- pydocstyle.ini | 12 ++ pre-commit/pyproject.toml => pyproject.toml | 6 +- tox.ini | 3 + 11 files changed, 451 insertions(+), 76 deletions(-) rename pre-commit/.flake8 => .flake8 (51%) create mode 100644 CONTRIBUTING.rst create mode 100644 doc/source/contributing.rst create mode 100644 pydocstyle.ini rename pre-commit/pyproject.toml => pyproject.toml (64%) diff --git a/pre-commit/.flake8 b/.flake8 similarity index 51% rename from pre-commit/.flake8 rename to .flake8 index f9b49ef3..b08e485b 100644 --- a/pre-commit/.flake8 +++ b/.flake8 @@ -1,7 +1,7 @@ [flake8] -max-line-length = 200 max-doc-length = 200 -ignore = E203, E266, E501, W503, W605 +ignore = E203, E266, E501, W503, W605, DOC301 +disable-docstring-checking = true # Error Codes # https://pep8.readthedocs.io/en/release-1.7.x/intro.html#error-codes @@ -9,4 +9,5 @@ ignore = E203, E266, E501, W503, W605 # E266 - too many leading ‘#’ for block comment # E501 - line too long # W503 - line break before binary operator -# W605 - invalid escape sequence-- need for regular expression \ No newline at end of file +# W605 - invalid escape sequence-- needed for regular expressions +# DOC301 - Allows `__init__()` to have its own docstring instead of forcing it to be merged with the class docstring diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 92044114..da7d3b24 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,32 +1,74 @@ ---- +# ----------------------------------------------------------------------------- +# Pre-Commit Hook Configuration for starlingx/test +# +# This configuration ensures code quality by enforcing formatting, style, and +# documentation standards before commits. The following tools are used: +# +# - `isort` → Sorts and organizes imports. +# - `black` → Formats Python code to maintain consistent style. +# - `flake8` → Runs linting checks for Python code style and errors. +# - `pydocstyle` → Enforces PEP 257 and Google-style docstring conventions. +# - `pydoclint` → Validates that docstrings match function signatures. +# - `interrogate` → Ensures all public functions and classes have docstrings. +# +# Notes: +# - `interrogate` is configured to ignore nested functions (`--ignore-nested-functions`) +# to avoid unnecessary enforcement on pytest teardowns and small helper functions. +# - `black` uses `pyproject.toml` for consistency across formatting tools. +# - `pydocstyle` and `pydoclint` ensure compliance with Google-style docstrings. +# ----------------------------------------------------------------------------- default_stages: [commit] default_language_version: python: python3.11 + repos: - repo: local hooks: - - id: flake8 - name: flake8 - code lint and style checks - entry: flake8 - language: python - types: [python] - args: [--config, pre-commit/.flake8] - id: isort name: isort - import sorting entry: isort language: python types: [python] - args: [--settings-path, pre-commit/pyproject.toml] - - id: black - name: black - check formatting (show diff on FAIL) - entry: black - language: python - types: [python] - args: [--config, pre-commit/pyproject.toml, --check, --diff, --color, --quiet] - - id: black - name: black - auto-format code on FAIL - entry: black - language: python - types: [python] - args: [--config, pre-commit/pyproject.toml] + args: [--settings-path, pyproject.toml] + - id: black + name: black - fail if formatting needed + entry: black + language: python + types: [python] + args: [--config, pyproject.toml, --check] + + - id: black + name: black - auto-format code + entry: black + language: python + types: [python] + args: [--config, pyproject.toml] + + - id: flake8 + name: flake8 - code lint and style checks + entry: flake8 + language: python + types: [python] + args: [--config=.flake8] + + - id: pydocstyle + name: pydocstyle - enforce PEP 257 and Google-style docstrings + entry: pydocstyle + language: python + types: [python] + args: [--config=pydocstyle.ini] + + - id: pydoclint + name: pydoclint - enforce Google-style docstring structure + entry: pydoclint + language: python + types: [python] + args: ["--config=pyproject.toml"] + + - id: interrogate + name: interrogate - ensure all functions and classes have docstrings + entry: interrogate + language: python + types: [python] + args: ["--fail-under", "100", "--ignore-module", "--ignore-init-method", "--ignore-nested-functions", "--verbose"] diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 00000000..28cdf345 --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,223 @@ +======================================== +Contributing to the StarlingX Test Repo +======================================== + +This document outlines the contribution guidelines for the `starlingx/test` repository. + +StarlingX Test is an open-source project, and we welcome contributions from the community. +This guide explains the requirements for code contributions, pre-commit checks, and documentation compliance. + +1. Setting Up Your Development Environment +========================================== + +1.1 Clone the Repository +------------------------ + +First, clone the repository and set up your environment: + +.. code-block:: bash + + git clone https://opendev.org/starlingx/test.git + cd test + +1.2 Install Dependencies +------------------------ + +Ensure you have **Python 3.11** installed, then install dependencies using `pipenv`: + +.. code-block:: bash + + pip install --user pipenv + pipenv install --dev + +1.3 Enable Pre-Commit Hooks +--------------------------- + +Pre-commit hooks are required to ensure code formatting and docstring compliance: + +.. code-block:: bash + + pre-commit install + +Once installed, **pre-commit will automatically run** on every commit. + +2. Code Contribution Guidelines +=============================== + +2.1 Code Style +-------------- + +- Python code must be formatted with ``black`` and ``isort``. +- Line length should not exceed 200 characters. +- Use **f-strings** instead of ``%`` formatting or ``.format()``. + +2.2 Docstring Standards +----------------------- + +All docstrings should follow the **Google Python Style Guide** and must be formatted consistently to pass pre-commit checks. + +- **Google-style docstrings** are required for all **functions and classes**, with the following exceptions: + + - **Module-level docstrings** are **not required** or enforced by pre-commit hooks. + + However, they are **recommended** for utility scripts and config files to clarify their intended use for other developers. + + - ``__init__`` methods are **allowed** to have docstrings but are **not required**. + + If a docstring is present, it should describe the purpose of the constructor and any initialization logic. + +The pre-commit hooks automatically enforce **PEP 257** and **Google-style docstrings** using ``pydocstyle``, ``pydoclint``, and ``interrogate``. + +For auto-generating docstrings that align with these standards, see: :ref:`auto-docstrings`. + +2.3 Type Hinting +---------------- + +All function signatures must include **type hints** for arguments and return values. + +**Example (Required Formatting):** + +.. code-block:: python + + def add(a: int, b: int) -> int: + """ + Adds two numbers. + + Args: + a (int): The first number. + b (int): The second number. + + Returns: + int: The sum of `a` and `b`. + """ + return a + b + +3. Pre-Commit Hooks & Linting +============================= + +This repository uses **pre-commit hooks** to enforce formatting, linting, and docstring compliance. + +3.1 Installed Pre-Commit Hooks +------------------------------ + +The following tools are run automatically on every commit: + +- **black**: Enforces PEP 8-compliant code formatting. +- **isort**: Ensures import statements are correctly ordered. +- **flake8**: Static code analysis and linting. +- **pydocstyle**: Enforces PEP 257 and Google-style docstring formatting. +- **pydoclint**: Ensures function signatures and docstrings match. +- **interrogate**: Ensures all functions and classes have docstrings. + +3.2 Running Pre-Commit Hooks Manually +------------------------------------- + +You can run pre-commit checks manually before committing: + +.. code-block:: bash + + pre-commit run --all-files + +4. Handling Return Types in Docstrings & Type Hints +=================================================== + +4.1 Why Are Return Types Required in Both Docstrings and Type Hints? +-------------------------------------------------------------------- + +We enforce **return type hints** (e.g., ``-> type``) and **docstring return types** (e.g., ``Returns:`` section) **to ensure consistency**. + +**Why is this required?** + +- Ensures clarity in documentation. +- Helps enforce consistency across the project. +- Required by pre-commit hooks (`pydocstyle`, `pydoclint`, `interrogate`). + +4.2 Example of Correct Formatting +--------------------------------- + +**Correct Example:** + +.. code-block:: python + + def multiply(a: int, b: int) -> int: + """ + Multiplies two integers. + + Args: + a (int): The first integer. + b (int): The second integer. + + Returns: + int: The product of `a` and `b`. + """ + return a * b + +**Incorrect Example (Missing `Returns:` section):** + +.. code-block:: python + + def multiply(a: int, b: int) -> int: + """Multiplies two integers.""" + return a * b # Missing `Returns:` section in docstring. + +.. _auto-docstrings: + +5. Auto-Generating Docstrings in VSCode & PyCharm +================================================= + +To simplify docstring compliance, you can use IDE plugins. + +5.1 VSCode: Auto-Generating Docstrings +-------------------------------------- + +1. Install the [Python Docstring Generator](https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring). +2. Configure VSCode to generate **Google-style docstrings** that align with pre-commit checks. + + Add the following settings to your ``settings.json``: + + .. code-block:: json + + { + "autoDocstring.docstringFormat": "google", + "autoDocstring.includeName": true, + "autoDocstring.includeExtendedSummary": true, + "autoDocstring.guessTypes": true, + "autoDocstring.startOnNewLine": true, + "autoDocstring.quoteStyle": "\"\"\"", + "autoDocstring.generateDocstringOnEnter": true + } + +3. Save the file and restart VSCode. + +5.2 PyCharm: Auto-Generating Docstrings +--------------------------------------- + +1. Open **PyCharm**. +2. Go to **File → Settings → Tools → Python Integrated Tools**. +3. Find the **Docstring format** dropdown and select **Google**. +4. Click **Apply** and **OK**. + +6. References +============= + +- `OpenStack Contributor Guide `_ +- `OpenStack Individual Contributor License Agreement (ICLA) `_ +- `OpenDev Developer Documentation `_ +- `StarlingX Contributor Guidelines `_ +- `StarlingX Code Submission Guide `_ +- `How to Contribute to StarlingX (YouTube) `_ +- `OpenStack Git Commit Message Guidelines `_ +- `Google Python Style Guide `_ +- `PEP 257 (Docstring Conventions) `_ +- `PEP 484 (Type Hints) `_ +- `PEP 498 (f-Strings) `_ +- `pydocstyle Documentation `_ +- `pydoclint Documentation `_ +- `interrogate Documentation `_ +- `pre-commit `_ +- `black `_ +- `isort `_ +- `flake8 `_ +- `AutoDocstring for VSCode `_ +- `VSCode: Auto-Generating Docstrings `_ +- `PyCharm: Creating Documentation Comments `_ diff --git a/Pipfile b/Pipfile index 8dabc3ef..943d01b4 100644 --- a/Pipfile +++ b/Pipfile @@ -13,6 +13,11 @@ black = "==24.3.0" isort = "==5.13.2" flake8 = "==7.0.0" +# Docstring Compliance and Enforcement +pydocstyle = "==6.3.0" # Enforce PEP 257 and Google-style docstrings +pydoclint = "==0.4.1" # Validate function signatures match docstrings (Google-style) +interrogate = "==1.5.0" # Ensure all functions and classes have docstrings + # Tools Packages pytest = "==8.1.1" paramiko = "==3.4.0" diff --git a/Pipfile.lock b/Pipfile.lock index 2b876ff2..018b2bfe 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "9301571a01a6b76d26e670a5f0fb8a5d597adc4ca6877f29f29d2ad7c241747d" + "sha256": "91b3ddf1a01a08c3c3b52dd48e801b3155f312616b504656e841ae451d5b7616" }, "pipfile-spec": 6, "requires": { @@ -313,36 +313,40 @@ }, "cryptography": { "hashes": [ - "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7", - "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731", - "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b", - "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc", - "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543", - "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c", - "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591", - "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede", - "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb", - "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f", - "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123", - "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c", - "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c", - "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285", - "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd", - "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092", - "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa", - "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289", - "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02", - "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64", - "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053", - "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417", - "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e", - "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e", - "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7", - "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756", - "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4" + "sha256:00918d859aa4e57db8299607086f793fa7813ae2ff5a4637e318a25ef82730f7", + "sha256:1e8d181e90a777b63f3f0caa836844a1182f1f265687fac2115fcf245f5fbec3", + "sha256:1f9a92144fa0c877117e9748c74501bea842f93d21ee00b0cf922846d9d0b183", + "sha256:21377472ca4ada2906bc313168c9dc7b1d7ca417b63c1c3011d0c74b7de9ae69", + "sha256:24979e9f2040c953a94bf3c6782e67795a4c260734e5264dceea65c8f4bae64a", + "sha256:2a46a89ad3e6176223b632056f321bc7de36b9f9b93b2cc1cccf935a3849dc62", + "sha256:322eb03ecc62784536bc173f1483e76747aafeb69c8728df48537eb431cd1911", + "sha256:436df4f203482f41aad60ed1813811ac4ab102765ecae7a2bbb1dbb66dcff5a7", + "sha256:4f422e8c6a28cf8b7f883eb790695d6d45b0c385a2583073f3cec434cc705e1a", + "sha256:53f23339864b617a3dfc2b0ac8d5c432625c80014c25caac9082314e9de56f41", + "sha256:5fed5cd6102bb4eb843e3315d2bf25fede494509bddadb81e03a859c1bc17b83", + "sha256:610a83540765a8d8ce0f351ce42e26e53e1f774a6efb71eb1b41eb01d01c3d12", + "sha256:6c8acf6f3d1f47acb2248ec3ea261171a671f3d9428e34ad0357148d492c7864", + "sha256:6f76fdd6fd048576a04c5210d53aa04ca34d2ed63336d4abd306d0cbe298fddf", + "sha256:72198e2b5925155497a5a3e8c216c7fb3e64c16ccee11f0e7da272fa93b35c4c", + "sha256:887143b9ff6bad2b7570da75a7fe8bbf5f65276365ac259a5d2d5147a73775f2", + "sha256:888fcc3fce0c888785a4876ca55f9f43787f4c5c1cc1e2e0da71ad481ff82c5b", + "sha256:8e6a85a93d0642bd774460a86513c5d9d80b5c002ca9693e63f6e540f1815ed0", + "sha256:94f99f2b943b354a5b6307d7e8d19f5c423a794462bde2bf310c770ba052b1c4", + "sha256:9b336599e2cb77b1008cb2ac264b290803ec5e8e89d618a5e978ff5eb6f715d9", + "sha256:a2d8a7045e1ab9b9f803f0d9531ead85f90c5f2859e653b61497228b18452008", + "sha256:b8272f257cf1cbd3f2e120f14c68bff2b6bdfcc157fafdee84a1b795efd72862", + "sha256:bf688f615c29bfe9dfc44312ca470989279f0e94bb9f631f85e3459af8efc009", + "sha256:d9c5b9f698a83c8bd71e0f4d3f9f839ef244798e5ffe96febfa9714717db7af7", + "sha256:dd7c7e2d71d908dc0f8d2027e1604102140d84b155e658c20e8ad1304317691f", + "sha256:df978682c1504fc93b3209de21aeabf2375cb1571d4e61907b3e7a2540e83026", + "sha256:e403f7f766ded778ecdb790da786b418a9f2394f36e8cc8b796cc056ab05f44f", + "sha256:eb3889330f2a4a148abead555399ec9a32b13b7c8ba969b72d8e500eb7ef84cd", + "sha256:f4daefc971c2d1f82f03097dc6f216744a6cd2ac0f04c68fb935ea2ba2a0d420", + "sha256:f51f5705ab27898afda1aaa430f34ad90dc117421057782022edf0600bec5f14", + "sha256:fd0ee90072861e276b0ff08bd627abec29e32a53b2be44e41dbcdf87cbee2b00" ], "markers": "python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1'", - "version": "==44.0.0" + "version": "==44.0.1" }, "distlib": { "hashes": [ @@ -360,6 +364,14 @@ "markers": "python_version >= '3.10'", "version": "==5.0.6" }, + "docstring-parser-fork": { + "hashes": [ + "sha256:55d7cbbc8b367655efd64372b9a0b33a49bae930a8ddd5cdc4c6112312e28a87", + "sha256:b44c5e0be64ae80f395385f01497d381bd094a57221fd9ff020987d06857b2a0" + ], + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==0.0.12" + }, "docutils": { "hashes": [ "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", @@ -443,11 +455,11 @@ }, "identify": { "hashes": [ - "sha256:7bec12768ed44ea4761efb47806f0a41f86e7c0a5fdf5950d4648c90eca7e251", - "sha256:cbd1810bce79f8b671ecb20f53ee0ae8e86ae84b557de31d89709dc2a48ba881" + "sha256:155931cb617a401807b09ecec6635d6c692d180090a1cedca8ef7d58ba5b6aa0", + "sha256:3fa266b42eba321ee0b2bb0936a6a6b9e36a1351cbb69055b3082f4193035684" ], "markers": "python_version >= '3.9'", - "version": "==2.6.6" + "version": "==2.6.7" }, "idna": { "hashes": [ @@ -473,6 +485,15 @@ "markers": "python_version >= '3.7'", "version": "==2.0.0" }, + "interrogate": { + "hashes": [ + "sha256:a4ccc5cbd727c74acc98dee6f5e79ef264c0bcfa66b68d4e123069b2af89091a", + "sha256:b6f325f0aa84ac3ac6779d8708264d366102226c5af7d69058cecffcff7a6d6c" + ], + "index": "pypi", + "markers": "python_version >= '3.6'", + "version": "==1.5.0" + }, "isort": { "hashes": [ "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109", @@ -753,6 +774,14 @@ "markers": "python_version >= '3.7'", "version": "==2.9.9" }, + "py": { + "hashes": [ + "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", + "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.11.0" + }, "pycodestyle": { "hashes": [ "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", @@ -769,6 +798,24 @@ "markers": "python_version >= '3.8'", "version": "==2.22" }, + "pydoclint": { + "hashes": [ + "sha256:4e32fdf0a47a2199377617f09af0a82a2157f80543026f919a17112a396e752f", + "sha256:d39ed26a793203afadb1917011710fbf258ac3dddcd79b53212e0a2107221643" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==0.4.1" + }, + "pydocstyle": { + "hashes": [ + "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019", + "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1" + ], + "index": "pypi", + "markers": "python_version >= '3.6'", + "version": "==6.3.0" + }, "pyflakes": { "hashes": [ "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f", @@ -1008,6 +1055,22 @@ "markers": "python_version >= '3.8'", "version": "==0.5.3" }, + "tabulate": { + "hashes": [ + "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", + "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f" + ], + "markers": "python_version >= '3.7'", + "version": "==0.9.0" + }, + "toml": { + "hashes": [ + "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", + "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", + "version": "==0.10.2" + }, "tornado": { "hashes": [ "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803", @@ -1062,11 +1125,11 @@ }, "virtualenv": { "hashes": [ - "sha256:4e4cb403c0b0da39e13b46b1b2476e505cb0046b25f242bee80f62bf990b2779", - "sha256:b8b8970138d32fb606192cb97f6cd4bb644fa486be9308fb9b63f81091b5dc35" + "sha256:fdaabebf6d03b5ba83ae0a02cfe96f48a716f4fae556461d180825866f75b728", + "sha256:febddfc3d1ea571bdb1dc0f98d7b45d24def7428214d4fb73cc486c9568cce6a" ], "markers": "python_version >= '3.8'", - "version": "==20.29.1" + "version": "==20.29.2" }, "wsproto": { "hashes": [ diff --git a/README.rst b/README.rst index dec541f3..c204c2a3 100644 --- a/README.rst +++ b/README.rst @@ -171,10 +171,7 @@ Contribution ------------ 2. **Coding Standards**: - - Ensure your code adheres to project conventions. While more detailed best practices are being refined and will be provided in future updates, the following standards are currently enforced: - - Use `Google style, PEP-compliant docstrings `_ for every function and module. These docstrings should align with the principles outlined in `PEP 257 (Docstring Conventions) `_. Tools for auto-generating these docstrings are available in IDEs such as `VSCode `_ and `PyCharm `_. - - Include `type hints `_ for all function arguments and return types. - - Use `f-strings `_ for string formatting. + - Ensure your code adheres to project conventions. For detailed guidelines, see `CONTRIBUTING.rst`. - Pre-commit hooks will run automatically on every commit once installed to ensure formatting and linting. - **Tools Enforced by Pre-Commit Hooks**: @@ -182,6 +179,9 @@ Contribution - `black `_ - `isort `_ - `flake8 `_ + - `pydocstyle `_ + - `pydoclint `_ + - `interrogate `_ 3. **Submitting Changes**: - Ensure your commit messages adhere to the guidelines in the @@ -193,8 +193,8 @@ Contribution git commit -s # include sign-off git review -References ----------- +6. References +============= - `OpenStack Contributor Guide `_ - `OpenStack Individual Contributor License Agreement (ICLA) `_ @@ -203,13 +203,17 @@ References - `StarlingX Code Submission Guide `_ - `How to Contribute to StarlingX (YouTube) `_ - `OpenStack Git Commit Message Guidelines `_ -- `Google Style Python Docstrings `_ -- `VSCode: Auto-Generating Docstrings `_ -- `PyCharm: Creating Documentation Comments `_ -- `PEP 257: Docstring Conventions `_ -- `PEP 484: Type Hints `_ -- `PEP 498: f-Strings `_ +- `Google Python Style Guide `_ +- `PEP 257 (Docstring Conventions) `_ +- `PEP 484 (Type Hints) `_ +- `PEP 498 (f-Strings) `_ +- `pydocstyle Documentation `_ +- `pydoclint Documentation `_ +- `interrogate Documentation `_ - `pre-commit `_ - `black `_ - `isort `_ - `flake8 `_ +- `AutoDocstring for VSCode `_ +- `VSCode: Auto-Generating Docstrings `_ +- `PyCharm: Creating Documentation Comments `_ diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst new file mode 100644 index 00000000..d0d85407 --- /dev/null +++ b/doc/source/contributing.rst @@ -0,0 +1,9 @@ +============================== +Contribution Guidelines +============================== + +This document provides contribution guidelines for ``starlingx/test``. + +For the complete contribution guide, refer to the latest ``CONTRIBUTING.rst`` in the repository root or view it on OpenDev. + +🔗 `View CONTRIBUTING.rst on OpenDev `_ diff --git a/doc/source/index.rst b/doc/source/index.rst index 9f6cb39e..692e77f9 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -10,7 +10,8 @@ This project contains **Automated Test Cases** that validate the **StarlingX pro The test framework provides tools and structured test cases to ensure the stability and reliability of StarlingX components. For more information about StarlingX, see the official documentation: -🔗 https://docs.starlingx.io/ + +🔗 `StarlingX Documentation `_ ---------------------- Repository Structure @@ -23,10 +24,20 @@ The **StarlingX Test Repository Structure** provides an overview of key director directory_structure +------------------- +Contribution Guide +------------------- + +For full contribution guidelines, including coding standards, pre-commit hooks, and best practices, see: + +.. toctree:: + :maxdepth: 1 + + contributing + ----- Links ----- -* **Source Code:** https://opendev.org/starlingx/test -* **Code Review:** https://review.opendev.org/#/q/project:starlingx/test -* **Bug Tracking:** https://storyboard.openstack.org/#!/project/starlingx/test +- **Source Code:** `StarlingX Test Repository `_ +- **Code Review:** `Gerrit Code Review `_ diff --git a/pydocstyle.ini b/pydocstyle.ini new file mode 100644 index 00000000..54d55e87 --- /dev/null +++ b/pydocstyle.ini @@ -0,0 +1,12 @@ +# Enforce Google-style docstrings while avoiding conflicts with pydoclint +[pydocstyle] +convention = google + +# Ignored rules: +# D100 - Ignore missing module-level docstrings (unnecessary in structured frameworks) +# D107 - Ignore missing docstrings for __init__ methods (handled by interrogate) +# D200 - Allow multi-line docstrings instead of forcing one-liners (Google-style) +# D203 - Allow class docstrings to be directly under the class definition (Google-style) +# D212 - Allow function/method docstring summaries to start on the second line (Google-style) +# D213 - Allow class docstring summaries to start on the first line (Google-style) +add-ignore = D100,D107,D200,D203,D212,D213 diff --git a/pre-commit/pyproject.toml b/pyproject.toml similarity index 64% rename from pre-commit/pyproject.toml rename to pyproject.toml index ff2c3f7e..54b76987 100644 --- a/pre-commit/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,14 @@ [tool.isort] py_version = "311" profile = "black" -line_length = 200 [tool.black] target-version = ['py311'] -line-length = 200 skip-string-normalization = true preview = true include = '\.py' +[tool.pydoclint] +style = "google" +check-return-types = true +allow-init-docstring = true diff --git a/tox.ini b/tox.ini index c179d7e6..575977c4 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,10 @@ [tox] envlist = py311 +skipsdist = True # Ensures tox does not attempt to package the repository [testenv:docs] basepython = python3 +usedevelop = False # Prevents installation as a package deps = -r{toxinidir}/doc/requirements.txt commands = rm -rf doc/build @@ -11,6 +13,7 @@ allowlist_externals = rm [testenv:releasenotes] basepython = python3 +usedevelop = False # Ensures tox only runs documentation generation deps = -r{toxinidir}/doc/requirements.txt commands = rm -rf releasenotes/build