Code Monkey home page Code Monkey logo

template-python-hello-world's Introduction

Python Template - Hello World Banner

A minimal template for Python development

GitHub Actions Status Coverage: 100% branches Kodiak Dependabot Status License Conventional Commits Code Style Imports: isort Checked with mypy Code Style: prettier

Why?

This repository exists to show a working example of Python formatting, linting and import sorting configurations with continuous integration.

Structure

This is a very simple, single Python module. It is not a Python package and does not contain the structure or tooling required for packaging / installing a Python project.

Formatting

Formatting is handled by black.

Black is an uncompromising Python code formatting tool. It takes a Python file as an input, and provides a reformatted Python file as an output, using rules that are a strict subset of PEP 8. It offers very little in the way of configuration (line length being the main exception) in order to achieve formatting consistency. It is deterministic - it will always produce the same output from the same inputs.

The line length configuration is stored in pyproject.toml.

Configuring Black to automatically run every time code is modified allows developers to forget about how code should be formatted and stay focused on functionality. Many IDEs and text editors allow this. Git hooks can also be used to execute Black before Python code is committed to a repository - this is not configured here as use of autosave and continuous integration checks makes it redundant.

VSCode Configuration

In VSCode, you can set the default Python formatter using the setting: "python.formatting.provider": "black", and then turn on autosave using "editor.formatOnSave": true. VSCode will pick up the line length configuration from a pyproject.toml file per repository.

Linting

Linting is handled by pylint.

Pylint checks Python files in order to detect syntax errors and potential bugs (unreachable code / unused variables), provide refactoring help,

The configuration is stored in pyproject.toml.

VSCode Configuration

Pylint is enabled by default in VSCode. VSCode will respect Pylint configurations stored in a pyproject.toml file per repository.

Sorting Imports

Import sorting is handled by isort.

isort sorts Python imports alphabetically within their respective sections:

  1. Standard library imports
  2. Related third party imports
  3. Local application / library specific imports

isort has many configuration options but these can cause inconsistencies with Black, so must be carefully assessed. The configurations within this repository will provide consistently ordered / formatted imports.

The configuration is stored in pyproject.toml.

VSCode Configuration

It is possible to configure VSCode to run isort every time you save, using the codeActionsOnSave": { "source.organizeImports": true } setting. This currently causes a race condition when formatting by black is also configured to occur on save ("editor.formatOnSave": true), leading to lines being erroneously deleted. The VSCode Python team can't do anything about this.

The configuration stored here works with black - that is to say, black will not reformat changes made by isort - but it is still unsafe to apply both commands simultaneously.

In VSCode, you can manually trigger import sorting by:

  • right clicking anywhere within a file and selecting Sort Imports.
  • command palette (Ctrl + Shift + P), then Python Refactor: Sort Imports.
  • creating a shortcut key for python.sortImports

There is also some discussion over whether black should just handle import sorting itself.

Line Length

Line length needs to be consistently configured for formatting, linting and while sorting imports. In order to change the line length for a specific project, it will need to be updated in pyproject.toml.

Commit Messages

Commit messages must conform to conventional commits:

type(optional-scope): description

where type is one of build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test as specified in .gitlint.

For example:

ci(github-actions): add new matrix jobs for Python 3.8

Continuous Integration

GitHub Actions

The GitHub Actions workflow is stored at .github/workflows/push.yml.

This configuration contains two jobs, with each containing a build matrix with two different versions of Python. The second job depends on the first job being completed successfully by using the needs key within the second job.

Linter

The first job, linter, tests formatting, linting and correct sorting of imports.

gitlint

This command runs gitlint on the most recent commit, to check that commit message titles conform to the conventional commits specification. Earlier commits may not conform, but all commits that are included in a Pull Request are checked by the next command. Pull Requests are the recommended code review workflow before merging into master.

gitlint --commits origin/${{ github.base_ref }}..${{ github.event.pull_request.head.sha }}

This command runs gitlint over all commits in a Pull Request, to check that commit message titles conform to the conventional commits specification.

black . --check --diff

This command runs the black formatter over the Python files in the current directory. The --check flag ensures that the command will error out if any changes are required, rather than making changes. --diff will show the difference.

black will respect the line length configuration stored in pyproject.toml.

pylint salutation.py test_salutation.py

This command runs the pylint checks for errors, bugs, non-conforming code style and potential code structure improvements over our Python module and tests.

pylint uses the configurations stored in pyproject.toml.

isort . --check --diff

This command runs the isort import sorter recursively over the Python files in the current directory. The --check flag ensures that the command will error out if any changes are required, rather than making changes. --diff will show the difference.

isort will respect the configurations stored in pyproject.toml.

Test

The second job, test, runs tests using pytest and verifies test coverage.

pytest

Simply execute pytest and it will find things that look like tests and run them.

Tests run in a random order thanks to pytest-randomly. This helps to detect interdependencies between tests. A test sequence can be reproduced by using the same --randomly-seed=VALUE option. pytest will always print this value, for example:

Using --randomly-seed=1548714831

This randomness can also be used to generate fuzzing input.

Automated Pull Request Merging

Kodiak

Kodiak is enabled on this repository, configured by .kodiak.toml.

Kodiak is a GitHub Bot that automatically merges pull requests that have been labelled automerge :rocket: once CI and required approvals have passed. Kodiak is free for open source repositories, but requires a per user subscription for private repositories.

Automated Dependency Updates

Dependabot

Dependabot is enabled on this repository, configured by .github/dependabot.yml.

Dependabot checks the dependencies listed in requirements-dev.txt daily to check if any new versions of those dependencies have been released. If Dependabot finds a new release, it opens a new Pull Request with a version bump, and attempts to show the changelog for that change. It also provides a compatibility prediction based on all of the Pull Requests that it has opened on other open source repositories and whether continuous integration was successful.

Dependabot is owned by GitHub and free for both open source and private repositories.

Automated Vulnerability Checks

Development

Prerequisites:

  • Python 3.8 through 3.12 (this can be changed in .python-version and pyproject.toml)
  • Poetry

Optional dependencies:

  • Pyenv to use the reference Python version in pyproject.toml with a simple pyenv install
  1. Install the project dependencies: poetry install
  2. Activate the virtualenv: poetry shell

Install Git hooks:

pre-commit install --hook-type=commit-msg --hook-type=pre-commit --overwrite

They run on every commit to check the repository contents and commit message.

template-python-hello-world's People

Contributors

bencheng1990 avatar blacha avatar dependabot-preview[bot] avatar dependabot[bot] avatar dwsilk avatar l0b0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

template-python-hello-world's Issues

Add NixOS support

Nix shell (possibly with direnv) is a very handy way to get a specific setup for a particular project just right and easily reproducible, without affecting any other projects.

Add docs about installing isort in git hooks

I'm finding that sometimes VS Code isort "on save" stuff is not working that well for isort. It might be best to add some notes about installing isort as a git pre-commit hook in .git/hooks/pre-commit:

#!/usr/bin/env python
import sys
from isort.hooks import git_hook

sys.exit(git_hook(strict=True, modify=False))

Improve gitlint processing of commits

At the moment gitlint is checking all commits against in the current branch against master: gitlint --commits origin/master.. This can cause problems if users are directly committing to master (I know), or when PRs are squashed and merged to master and github automatically increases the message length (adds issue number on the end!)

What would be more robust is running it for a range of commits in the PR branch or against the last (or few?) commit in master.

Note I see github actions only have a crude way of getting the range of commits: https://github.community/t5/GitHub-Actions/How-to-get-the-full-range-of-commits-for-a-PR/td-p/45074

Support more Python versions

Ideally we should support all the not yet EOL-ed Python versions (possibly with a job which is allowed to fail in case of beta versions like 3.10), in case someone wants to use this template for developments which will run in many different environments.

Default configuration of line lengths for git commit messages

Early discussion here: #9

By default, gitlint requires commit titles to be <72 chars and the commit body to be wrapped at 80 chars.

In terms of other services that we use:

GitHub will truncate titles with a "show more" ellipses at 72 chars.

dependabot does restrict commit titles to <72 chars (see here) but doesn't restrict the commit body so its PRs will fail with a commit body length restriction, as it has here.

I propose:

  • titles with a warning at 50 chars, hard limit at 72 chars
  • body with a warning at 80 chars, no hard limit

This matches the default configuration of commitlint: https://github.com/conventional-changelog/commitlint/blob/master/docs/reference-rules.md

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.