Last active
August 27, 2024 11:15
-
-
Save GhostofGoes/75051c4aeb215bc3cf48c10f5454b399 to your computer and use it in GitHub Desktop.
Example pyproject.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This example pyproject.toml is for a basic pip+setuptools setup. | |
# If you use a project management tool (like Poetry), then | |
# those tools will have slightly different configurations or additions. | |
# I highly recommend using a project management tool for your project. | |
# Project management is a highly opinionated subject. | |
# There are a lot of good, robust tools in this space now (as of 2023) | |
# Two that I've used and recommend are Poetry and PDM. | |
# Poetry is more mature, PDM is recent, both work well. | |
# - Poetry: https://python-poetry.org/ | |
# - PDM: https://pdm.fming.dev/latest/ | |
# Resources | |
# | |
# - https://packaging.python.org/en/latest/tutorials/packaging-projects/ | |
# - https://betterprogramming.pub/a-pyproject-toml-developers-cheat-sheet-5782801fb3ed | |
# | |
# Examples of pyproject.toml files from open-source projects: | |
# - https://github.com/carlosperate/awesome-pyproject | |
# - https://github.com/SpikeInterface/spikeinterface/blob/master/pyproject.toml | |
# - https://github.com/codespell-project/codespell/blob/master/pyproject.toml | |
# - https://github.com/hynek/structlog/blob/main/pyproject.toml | |
[build-system] | |
build-backend = "setuptools.build_meta" | |
requires = ["setuptools>=61.0", "wheel>=0.37.1"] | |
[project] | |
# https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ | |
name = "acme" | |
version = "0.0.1" | |
description = "ACME tool" | |
readme = "README.md" | |
requires-python = ">=3.9,<4.0" | |
# "LICENSE" is name of the license file, which must be in root of project folder | |
license = {file = "LICENSE"} | |
authors = [ | |
{name = "Joe Example", email = "[email protected]"}, | |
] | |
keywords = ["keyword", "are", "cool"] | |
# https://pypi.org/classifiers/ | |
# Add PyPI classifiers here | |
classifiers = [ | |
"Development Status :: 5 - Production/Stable", | |
"Environment :: Console", | |
"License :: OSI Approved :: MIT License", | |
"Natural Language :: English", | |
"Operating System :: MacOS", | |
"Operating System :: Microsoft :: Windows", | |
"Operating System :: POSIX", | |
"Operating System :: POSIX :: Linux", | |
"Programming Language :: Python", | |
"Programming Language :: Python :: 3", | |
"Programming Language :: Python :: 3.9", | |
"Programming Language :: Python :: 3.10", | |
"Programming Language :: Python :: 3.11", | |
"Programming Language :: Python :: Implementation :: CPython", | |
] | |
# Required dependencies for install/usage of your package or application | |
# If you don't have any dependencies, leave this section empty | |
# Format for dependency strings: https://peps.python.org/pep-0508/ | |
dependencies = [ | |
# ... put stuff here ... | |
] | |
[project.scripts] | |
# Command line interface entrypoint scripts | |
acme = "acme.__main__:main" | |
[project.urls] | |
# Use PyPI-standard names here | |
# Homepage | |
# Documentation | |
# Changelog | |
# Issue Tracker | |
# Source | |
# Discord server | |
"Homepage" = "<url>" | |
"Documentation" = "<url>" | |
# Development dependencies | |
# pip install -e .[lint,test,exe] | |
# pip install -e .[dev] | |
[project.optional-dependencies] | |
lint = [ | |
# checks for spelling mistakes | |
"codespell>=2.2.4", | |
# ruff linter checks for issues and potential bugs | |
"ruff", | |
# checks for unused code | |
"vulture", | |
# required for codespell to parse pyproject.toml | |
"tomli", | |
# validation of pyproject.toml | |
"validate-pyproject[all]", | |
# automatic sorting of imports | |
"isort", | |
# automatic code formatting to follow a consistent style | |
"black", | |
] | |
test = [ | |
# Handles most of the testing work, including execution | |
# Docs: https://docs.pytest.org/en/stable/contents.html | |
"pytest", | |
# "Coverage" is how much of the code is actually run (it's "coverage") | |
# Generates coverage reports from test suite runs | |
"pytest-cov", | |
"tomli", | |
# pytest wrapper around the "mock" library | |
"pytest-mock", | |
# Randomizes the order of test execution | |
"pytest-randomly", | |
# Required for comparing device data exports and a few other complex structures | |
# Docs: https://zepworks.com/deepdiff/current/ | |
"deepdiff", | |
# Test parallelization, as well as remote execution (which we may do someday) | |
"pytest-xdist[psutil]", | |
# Detailed pytest results saved to a JSON file | |
"pytest-json-report", | |
# Better parsing of doctests | |
"xdoctest", | |
# Mocking of HTTP responses for the "requests" module | |
"requests-mock", | |
# Colors for doctest output | |
"Pygments", | |
] | |
exe = [ | |
"setuptools", | |
"wheel", | |
"build", | |
"tomli", | |
"pyinstaller", | |
"staticx;platform_system=='Linux'", | |
] | |
dev = [ | |
# https://hynek.me/articles/python-recursive-optional-dependencies/ | |
"acme[lint,test,exe]", | |
# Useful for building quick scripts for testing purposes | |
# https://github.com/google/python-fire | |
"fire", | |
# Code quality tools | |
"mypy", | |
# Improved exception traceback output | |
# https://github.com/qix-/better-exceptions | |
"better_exceptions", | |
# Analyzing dependencies | |
# install graphviz to generate graphs | |
"graphviz", | |
"pipdeptree", | |
] | |
[tool.setuptools] | |
# https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html | |
platforms = ["Linux", "Windows"] | |
include-package-data = true | |
zip-safe = true # This just means it's safe to zip up the bdist | |
# Non-code data that should be included in the package source code | |
# https://setuptools.pypa.io/en/latest/userguide/datafiles.html | |
[tool.setuptools.package-data] | |
acme = ["*.xml"] | |
# Python modules and packages that are included in the | |
# distribution package (and therefore become importable) | |
[tool.setuptools.packages.find] | |
exclude = ["tests", "tests.*", "examples"] | |
# PDM example | |
[tool.pdm.scripts] | |
isort = "isort acme" | |
black = "black acme" | |
format = {composite = ["isort", "black"]} | |
check_isort = "isort --check acme tests" | |
check_black = "black --check acme tests" | |
vulture = "vulture --min-confidence 100 acme tests" | |
ruff = "ruff check acme tests" | |
fix = "ruff check --fix acme tests" | |
codespell = "codespell --toml ./pyproject.toml" | |
lint = {composite = ["vulture", "codespell", "ruff", "check_isort", "check_black"]} | |
[tool.codespell] | |
# codespell supports pyproject.toml since version 2.2.2 | |
# NOTE: the "tomli" package must be installed for this to work | |
# https://github.com/codespell-project/codespell#using-a-config-file | |
# NOTE: ignore words for codespell must be lowercase | |
check-filenames = "" | |
ignore-words-list = "word,another,something" | |
skip = "htmlcov,.doctrees,*.pyc,*.class,*.ico,*.out,*.PNG,*.inv,*.png,*.jpg,*.dot" | |
[tool.black] | |
line-length = 88 | |
# If you need to exclude directories from being reformatted by black | |
# force-exclude = ''' | |
# ( | |
# somedirname | |
# | dirname | |
# | filename\.py | |
# ) | |
# ''' | |
[tool.isort] | |
profile = "black" | |
known_first_party = ["acme"] | |
# If you need to exclude files from having their imports sorted | |
extend_skip_glob = [ | |
"acme/somefile.py", | |
"acme/somedir/*", | |
] | |
# https://beta.ruff.rs/docs | |
[tool.ruff] | |
line-length = 99 | |
show-source = true | |
# Rules: https://beta.ruff.rs/docs/rules | |
# If you violate a rule, lookup the rule on the Rules page in ruff docs. | |
# Many rules have links you can click with a explanation of the rule and how to fix it. | |
# If there isn't a link, go to the project the rule was source from (e.g. flake8-bugbear) | |
# and review it's docs for the corresponding rule. | |
# If you're still confused, ask a fellow developer for assistance. | |
# You can also run "ruff rule <rule>" to explain a rule on the command line, without a browser or internet access. | |
select = [ | |
"E", # pycodestyle | |
"F", # Pyflakes | |
"W", # Warning | |
"B", # flake8-bugbear | |
"A", # flake8-builtins | |
"C4", # flake8-comprehensions | |
"T10", # flake8-debugger | |
"EXE", # flake8-executable, | |
"ISC", # flake8-implicit-str-concat | |
"G", # flake8-logging-format | |
"PIE", # flake8-pie | |
"T20", # flake8-print | |
"PT", # flake8-pytest-style | |
"RSE", # flake8-raise | |
"RET", # flake8-return | |
"TID", # flake8-tidy-imports | |
"ARG", # flake8-unused-arguments | |
"PGH", # pygrep-hooks | |
"PLC", # Pylint Convention | |
"PLE", # Pylint Errors | |
"PLW", # Pylint Warnings | |
"RUF", # Ruff-specific rules | |
# ** Things to potentially enable in the future ** | |
# DTZ requires all usage of datetime module to have timezone-aware | |
# objects (so have a tz argument or be explicitly UTC). | |
# "DTZ", # flake8-datetimez | |
# "PTH", # flake8-use-pathlib | |
# "SIM", # flake8-simplify | |
] | |
# Files to exclude from linting | |
extend-exclude = [ | |
"*.pyc", | |
"__pycache__", | |
] | |
# Linting error codes to ignore | |
ignore = [ | |
"F403", # unable to detect undefined names from star imports | |
"F405", # undefined locals from star imports | |
"W605", # invalid escape sequence | |
"A003", # shadowing python builtins | |
"RET505", # unnecessary 'else' after 'return' statement | |
"RET504", # Unnecessary variable assignment before return statement | |
"RET507", # Unnecessary {branch} after continue statement | |
"PT011", # pytest-raises-too-broad | |
"PT012", # pytest.raises() block should contain a single simple statement | |
"PLW0603", # Using the global statement to update is discouraged | |
"PLW2901", # for loop variable overwritten by assignment target | |
"G004", # Logging statement uses f-string | |
"PIE790", # no-unnecessary-pass | |
"PIE810", # multiple-starts-ends-with | |
"PGH003", # Use specific rule codes when ignoring type issues | |
"PLC1901", # compare-to-empty-string | |
] | |
# Linting error codes to ignore on a per-file basis | |
[tool.ruff.per-file-ignores] | |
"__init__.py" = ["F401", "E501"] | |
"acme/somefile.py" = ["E402", "E501"] | |
"acme/somedir/*" = ["E501"] | |
# Configuration for mypy | |
# https://mypy.readthedocs.io/en/stable/config_file.html#using-a-pyproject-toml-file | |
[tool.mypy] | |
python_version = "3.9" | |
follow_imports = "skip" | |
ignore_missing_imports = true | |
files = "acme" # directory mypy should analyze | |
# Directories to exclude from mypy's analysis | |
exclude = [ | |
"acme/somedir", | |
"acme/somefile\\.py", | |
"dirname", | |
] | |
# Configuration for pytest | |
# https://docs.pytest.org/en/latest/reference/customize.html#pyproject-toml | |
[tool.pytest.ini_options] | |
testpaths = "tests" # directory containing your tests | |
norecursedirs = [ | |
".vscode", | |
"__pycache__" | |
] | |
# Warnings that should be ignored | |
filterwarnings = [ | |
"ignore::DeprecationWarning" | |
] | |
# custom markers that can be used using pytest.mark | |
markers = [ | |
"slow: lower-importance tests that take an excessive amount of time", | |
] | |
# Configuration for coverage.py | |
[tool.coverage.run] | |
# files or directories to exclude from coverage calculations | |
omit = [ | |
'acme/somedir/*', | |
'acme/somefile.py', | |
] | |
# Configuration for vulture | |
[tool.vulture] | |
# Files or directories to exclude from vulture | |
# The syntax is a little funky | |
exclude = [ | |
"somedir", | |
"*somefile.py", | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment