diff --git a/README.md b/README.md index 77a4eac..46b6b6e 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ provides a simple implementation of the [factorial algorithm](https://en.wikipedia.org/wiki/Factorial) (`fact.lib`) and a command line interface (`fact.cli`). -# Package Management +## Package Management This package uses [uv](https://docs.astral.sh/uv/) to manage dependencies and isolated [Python virtual environments](https://docs.python.org/3/library/venv.html). @@ -41,7 +41,7 @@ To upgrade all uv-managed Python versions to their latest patch releases: uv python upgrade ``` -## Dependencies +### Dependencies Dependencies are defined in [`pyproject.toml`](./pyproject.toml) and specific versions are locked into [`uv.lock`](./uv.lock). This allows for exact reproducible environments across @@ -59,7 +59,7 @@ To upgrade all dependencies to their latest versions: uv lock --upgrade ``` -## Packaging +### Packaging This project is designed as a Python package, meaning that it can be bundled up and redistributed as a single compressed file. @@ -82,7 +82,7 @@ This will generate `dist/fact-1.0.0.tar.gz` and `dist/fact-1.0.0-py3-none-any.wh > Read more about the [advantages of wheels](https://pythonwheels.com/) to understand why > generating wheel distributions are important. -## Publish Distributions to PyPI +### Publish Distributions to PyPI Source and wheel redistributable packages can be [published to PyPI](https://docs.astral.sh/uv/guides/package/) or installed @@ -96,7 +96,7 @@ uv publish > To enable publishing, remove the `"Private :: Do Not Upload"` > [trove classifier](https://pypi.org/classifiers/). -# Enforcing Code Quality +## Enforcing Code Quality Automated code quality checks are performed using [Nox](https://nox.thea.codes/en/stable/) and [`nox-uv`](https://github.com/dantebben/nox-uv). Nox will automatically create virtual environments @@ -113,7 +113,7 @@ To run all default sessions: uv run nox ``` -## Unit Testing +### Unit Testing Unit testing is performed with [pytest](https://pytest.org/). pytest has become the de facto Python unit testing framework. Some key advantages over the built-in @@ -145,7 +145,7 @@ To pass arguments to `pytest` through `nox`: uv run nox -s test -- -k invalid_factorial ``` -## Code Style Checking +### Code Style Checking [PEP 8](https://peps.python.org/pep-0008/) is the universally accepted style guide for Python code. PEP 8 code compliance is verified using [Ruff][Ruff]. Ruff is configured in the @@ -168,7 +168,7 @@ To automatically fix fixable lint errors, run: uv run nox -s lint_fix ``` -## Automated Code Formatting +### Automated Code Formatting [Ruff][Ruff] is used to automatically format code and group and sort imports. @@ -178,7 +178,7 @@ To automatically format code, run: uv run nox -s fmt ``` -## Type Checking +### Type Checking [Type annotations](https://docs.python.org/3/library/typing.html) allows developers to include optional static typing information to Python source code. This allows static analyzers such @@ -202,7 +202,7 @@ uv run nox -s type_check See also [awesome-python-typing](https://github.com/typeddjango/awesome-python-typing). -### Distributing Type Annotations +#### Distributing Type Annotations [PEP 561](https://www.python.org/dev/peps/pep-0561/) defines how a Python package should communicate the presence of inline type annotations to static type @@ -212,16 +212,16 @@ provides further examples on how to do this. Mypy looks for the existence of a file named [`py.typed`](./src/fact/py.typed) in the root of the installed package to indicate that inline type annotations should be checked. -## Continuous Integration +### Continuous Integration Continuous integration is provided by [GitHub Actions](https://github.com/features/actions). This runs all tests, lints, and type checking for every commit and pull request to the repository. GitHub Actions is configured in [`.github/workflows/ci.yml`](./.github/workflows/ci.yml). -# Documentation +## Documentation -## Generating a User Guide +### Generating a User Guide [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/) is a powerful static site generator that combines easy-to-write Markdown, with a number of Markdown extensions that increase @@ -265,7 +265,7 @@ automatically build the user guide and publish it to [GitHub Pages](https://page This is configured in the `docs_github_pages` Nox session. This hosted user guide can be viewed at . -## Generating API Documentation +### Generating API Documentation This project uses [mkdocstrings](https://github.com/mkdocstrings/mkdocstrings) plugin for MkDocs, which renders @@ -287,12 +287,12 @@ Returns: """ ``` -# Project Structure +## Project Structure Traditionally, Python projects place the source for their packages in the root of the project structure, like: -``` {.sourceCode .} +```text {.sourceCode .} fact ├── fact │ ├── __init__.py @@ -339,7 +339,7 @@ by `pytest` when using Nox and the solution this blueprint promotes because it i even though it deviates from the traditional Python project structure. It results is a directory structure like: -``` {.sourceCode .} +```text {.sourceCode .} fact ├── src │ └── fact @@ -353,7 +353,7 @@ fact └── pyproject.toml ``` -# Licensing +## Licensing Licensing for the project is defined in: @@ -391,7 +391,7 @@ nox > pip-licenses --summary 1 PSF-2.0 ``` -# Container +## Container [Docker](https://www.docker.com/) is a tool that allows for software to be packaged into isolated containers. It is not necessary to use Docker in a Python project, but for the purposes of @@ -416,14 +416,14 @@ To run the image in a container: docker run --rm --interactive --tty fact 5 ``` -# AI Agents +## AI Agents AI agentic coding tools are configured in [AGENTS.md](./AGENTS.md). For more details, see . -# Miscellaneous +## Miscellaneous -## Shebang Line +### Shebang Line The proper [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) line for Python scripts is: @@ -451,7 +451,7 @@ print(httpx.get("https://example.com").text) On Windows, remove the `-S` from the shebang and execute the script using the `py` launcher. -## Package Dependency Tree +### Package Dependency Tree `uv tree` is a command for listing installed packages in the form of a dependency tree. For large projects, it is often difficult to determine dependency relationships solely from manually @@ -472,7 +472,7 @@ fact v1.0.0 └── shellingham v1.5.4 (extra: standard) ``` -# Badge +## Badge Support [`python-blueprint`](https://github.com/johnthagen/python-blueprint) by adding the badge to your project: @@ -484,7 +484,7 @@ to your project: [python-blueprint-badge]: https://img.shields.io/badge/%F0%9F%97%BA%EF%B8%8F-python--blueprint-2dcf59.svg ``` -# PyCharm Configuration +## PyCharm Configuration > [!TIP] > Looking for a vivid dark color scheme for PyCharm? @@ -518,7 +518,7 @@ project: - Editor | Code Style | Python | Wrapping and Braces | "From" Import Statements - ☑ Force parentheses if multiline -## Ruff Integration +### Ruff Integration PyCharm natively supports [Ruff](https://docs.astral.sh/ruff/editors/setup/#pycharm) linting and formatting. @@ -538,7 +538,7 @@ errors will be shown within the editor. > on > how to Right-Click | Mark Directory as | Excluded. -## Nox Support +### Nox Support [PyCharm does not yet natively support Nox](https://youtrack.jetbrains.com/issue/PY-37302). The recommended way to launch Nox from PyCharm is to create a **Python** @@ -550,4 +550,4 @@ recommended way to launch Nox from PyCharm is to create a **Python** - Select **Modify Options** | Check **Emulate terminal in output console** to enable colors to be rendered properly -![](docs/static/images/nox_run_configuration.png) +![Nox Run Configuration](docs/static/images/nox_run_configuration.png) diff --git a/docs/licenses/license_report.md b/docs/licenses/license_report.md index e4378e4..ff1bb46 100644 --- a/docs/licenses/license_report.md +++ b/docs/licenses/license_report.md @@ -11,6 +11,6 @@ search: ## License Files -``` +```text --8<-- "docs/licenses/license_files.txt" ``` diff --git a/noxfile.py b/noxfile.py index 8627330..b9791c5 100644 --- a/noxfile.py +++ b/noxfile.py @@ -46,6 +46,7 @@ def test(s: Session) -> None: id="sort_imports", ), param(["ruff", "format", "."], id="format"), + param(["rumdl", "fmt", "."], id="md_format"), ], ) def fmt(s: Session, command: list[str]) -> None: @@ -58,6 +59,7 @@ def fmt(s: Session, command: list[str]) -> None: [ param(["ruff", "check", "."], id="lint_check"), param(["ruff", "format", "--check", "."], id="format_check"), + param(["rumdl", "check", "."], id="md_format_check"), ], ) def lint(s: Session, command: list[str]) -> None: diff --git a/pyproject.toml b/pyproject.toml index 9be484f..cb9d831 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,6 +53,7 @@ type_check = [ ] lint = [ "ruff", + "rumdl", ] docs = [ "mkdocs-material", @@ -133,6 +134,14 @@ split-on-trailing-comma = false [tool.ruff.lint.flake8-tidy-imports] ban-relative-imports = "all" +[tool.rumdl] +line-length = 99 +flavor = "mkdocs" +disable = [ + "MD033", +] + + [tool.pytest.ini_options] addopts = [ "--strict-config", diff --git a/uv.lock b/uv.lock index 7f37439..7912f80 100644 --- a/uv.lock +++ b/uv.lock @@ -522,6 +522,7 @@ licenses = [ ] lint = [ { name = "ruff" }, + { name = "rumdl" }, ] nox = [ { name = "nox-uv" }, @@ -549,7 +550,10 @@ docs = [ { name = "mkdocstrings", extras = ["python"] }, ] licenses = [{ name = "pip-licenses-cli" }] -lint = [{ name = "ruff" }] +lint = [ + { name = "ruff" }, + { name = "rumdl" }, +] nox = [{ name = "nox-uv" }] test = [ { name = "pytest" }, @@ -1438,6 +1442,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fc/07/d781f8f8e1ac24bef9f3269cf62ffb1407ca24c3a8f12e5e22874f90528c/ruff-0.16.6-py3-none-win_arm64.whl", hash = "sha256:7a976c79b958f94e50a022a19f0f8c87387448020935ec14fc74331bd0a7f2c5", size = 10412850, upload-time = "2026-09-03T16:57:26.416Z" }, ] +[[package]] +name = "rumdl" +version = "0.2.73" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8a/c9/fdbf8321f63d8d540efd2ef01c2e5a17f103c028152f7138cd3401f60aa5/rumdl-0.2.73.tar.gz", hash = "sha256:14237a069b4fc9ead00535062b08826c37235a086d170fc2d57f20634892e66a", size = 4695281, upload-time = "2026-09-11T19:07:25.699Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/24/b8c4f5d21446a660aa866dd1bb2aa488e781eaf0cafaec0756a3a95c77c5/rumdl-0.2.73-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0b909fac1ad77a68e34619945f7456bea835057d79568ad8c6eb4b0b4f15d74b", size = 7125343, upload-time = "2026-09-11T19:07:18.27Z" }, + { url = "https://files.pythonhosted.org/packages/d2/35/e2c23352a635578de3692755da99762cf35ab33c82f5ba9951e3c7a35f49/rumdl-0.2.73-py3-none-macosx_11_0_arm64.whl", hash = "sha256:51e9efa2b97babc3181d71a089ae8f842f01eaf78b8aa3c7018e7d10ce3f1928", size = 6736640, upload-time = "2026-09-11T19:07:12.734Z" }, + { url = "https://files.pythonhosted.org/packages/97/c3/61b4f3b2c7be4b4f15d5f45484e8c127e0d03402ed83e3861054b189db5a/rumdl-0.2.73-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:b0ed815d4c957c0448325b23d799247714112cdcf344062527a4fa9b25785da7", size = 6894769, upload-time = "2026-09-11T19:07:15.011Z" }, + { url = "https://files.pythonhosted.org/packages/ee/03/ed945f603896d44d74bdc8c395efc2e846500ed18ed523174060e00637d2/rumdl-0.2.73-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:c56ede961c39eb4f8682cd9330f0fd645b0c7bf791de1c4ba717a41c0ce65000", size = 7326038, upload-time = "2026-09-11T19:07:21.892Z" }, + { url = "https://files.pythonhosted.org/packages/4c/87/c4bd9e7f9915f386c00856619c95a8266ef2283aa57c6bf39dc020dff41a/rumdl-0.2.73-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:baa6177f18b2a6f86b340369bc3836197d27d21618779226c50c670eab807fc7", size = 6867407, upload-time = "2026-09-11T19:07:16.69Z" }, + { url = "https://files.pythonhosted.org/packages/7b/7c/98e633d0c6d47da59d714fdb21fbff3cf2b6bf9d98e21264d9f5d1e291c3/rumdl-0.2.73-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7a9869b6061be47d451d19d3d4ba5b3140a1b5b44e8a614ef005f5044746976f", size = 7296231, upload-time = "2026-09-11T19:07:23.84Z" }, + { url = "https://files.pythonhosted.org/packages/a8/9e/105c61dacbdbb0f4b5ba26d64b258a71a1589dd14a0025d39920789fd636/rumdl-0.2.73-py3-none-win_amd64.whl", hash = "sha256:f27963c641811a3de38797a6aaa3a6ab326b6ba6e85985973015e2e75bec0628", size = 7343232, upload-time = "2026-09-11T19:07:20.034Z" }, +] + [[package]] name = "shellingham" version = "1.5.4"