12.3. Modules pyproject.toml

Modern Python packages can contain a pyproject.toml file, first introduced in PEP 518 and later expanded in PEP 517, PEP 621 and PEP 660. This file contains build system requirements and information, which are used by pip to build the package. [1]

[project]
name = "ares3"
version = "1.0.0"
requires-python = ">=3.11"
license.file = "LICENSE"  # https://peps.python.org/pep-0639/#add-license-files-key
authors = [{name = "Mark Watney", email = "mwatney@nasa.gov"}]
dynamic = ["readme"]

urls.homepage = "https://github.com/nasa/ares3"
urls.repository = "https://github.com/nasa/ares3.git"
urls.documentation = "https://github.com/nasa/ares3"
urls.bugtracker = "https://github.com/nasa/ares3/issues"

keywords = [
    "ares",
    "mars",
    "nasa",
    "human-spaceflight"]

classifiers = [
    "Development Status :: 3 - Alpha",
    "Environment :: Web Environment",
    "Framework :: Django",
    "Framework :: Django :: 4.1",
    "Intended Audience :: Other Audience",
    "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
    "Topic :: Software Development :: Libraries :: Python Modules",
    "Natural Language :: English",
    "Natural Language :: Polish",
    "Operating System :: OS Independent",
    "Programming Language :: Python",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: Implementation :: CPython",
    "Topic :: Internet :: WWW/HTTP",
    "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
    "Topic :: Internet :: WWW/HTTP :: WSGI :: Application"]

## Dependencies
# https://peps.python.org/pep-0440/#version-specifiers

dependencies = [
    "django == 4.1.*",
    "django-ninja == 0.19.*"]

optional-dependencies.test = [
    "mypy",
    "pylint",
    "coverage"]


## Console scripts
# Builder will install a shell script named `myapp-cli` in venv's
# bin directory: `.venv/bin/myapp-cli`

[project.scripts]
ares3-cli = "ares3.manage:main"

[project.gui-scripts]
ares3-gui = "ares3.manage:gui"

# An "entry point" is typically a function (or other callable
# function-like object) that a developer or user of your Python
# package might want to use. The most popular kind of entry point
# is the console_scripts entry point, which points to a function
# that you want made available as a command-line tool to whoever
# installs your package.
[project.entry-points.console_scripts]
ares3-run = "ares3.manage:main"


## Build System

[build-system]
requires = ['setuptools >= 65.6']
build-backend = 'setuptools.build_meta'

[tool.setuptools.packages.find]
where = ["."]
exclude = ["ares3.*.tests*"]

[tool.setuptools.dynamic]
readme.file = "README.rst"
# version.attr = "aviation.__version__"  ## if 'version' in dynamic


## External Tools Configuration

# https://ichard26-testblackdocs.readthedocs.io/en/refactor_docs/pyproject_toml.html
[tool.black]
line-length = 79
target_version = ["py311"]
include = '\.pyi?$'
exclude = [
    '*.egg-info',
    ".git",
    ".mypy_cache",
    ".venv",
    "build",
    "dist",
]


# https://mypy.readthedocs.io/en/stable/config_file.html
# https://mypy.readthedocs.io/en/stable/config_file.html#using-a-pyproject-toml-file
[tool.mypy]
python_version = "3.11"
files = ["src"]
modules = ["ares3"]
exclude = [
    '*.egg-info',
    ".git",
    ".mypy_cache",
    "build",
    "dist"]
warn_return_any = true
warn_unused_configs = true
# namespace_packages = false
# explicit_package_bases = false
# ignore_missing_imports = false
# follow_imports = "normal"
# follow_imports_for_stubs = false
# no_site_packages = false
# no_silence_site_packages = false
# # Platform configuration
# platform = "linux-64"
# # Disallow dynamic typing
# disallow_any_unimported = false # TODO
# disallow_any_expr = false # TODO
# disallow_any_decorated = false # TODO
# disallow_any_explicit = false # TODO
# disallow_any_generics = true
# disallow_subclassing_any = true
# # Untyped definitions and calls
# disallow_untyped_calls = true
# disallow_untyped_defs = true
# disallow_incomplete_defs = true
# check_untyped_defs = true
# disallow_untyped_decorators = true
# # None and Optional handling
# no_implicit_optional = true
# strict_optional = true
# # Configuring warnings
# warn_redundant_casts = true
# warn_unused_ignores = true
# warn_no_return = true
# warn_return_any = true
# warn_unreachable = false # GH#27396
# # Suppressing errors
# show_none_errors = true
# ignore_errors = false
# enable_error_code = "ignore-without-code"
# # Miscellaneous strictness flags
# allow_untyped_globals = false
# allow_redefinition = false
# local_partial_types = false
# implicit_reexport = true
# strict_equality = true
# # Configuring error messages
# show_error_context = false
# show_column_numbers = false
# show_error_codes = true

# https://pycqa.github.io/isort/docs/configuration/options.html
[tool.isort]
atomic = true                           # Ensures the output doesn't save if the resulting file contains syntax errors
combine_as_imports = false              # Combines as imports on the same line
combine_star = true                     # Ensures that if a star import is present, nothing else is imported from that namespace
ensure_newline_before_comments = true   # Inserts a blank line before a comment following an import
force_alphabetical_sort = false         # Force all imports to be sorted as a single section
force_alphabetical_sort_within_sections = true  # Force all imports to be sorted alphabetically within a section
force_sort_within_sections = true       # Don't sort straight-style imports (like import sys) before from-style imports (like from itertools import groupby). Instead, sort the imports by module, independent of import style
group_by_package = false                # If True isort will automatically create section groups by the top-level package they come from
honor_noqa = true                       # Tells isort to honor noqa comments to enforce skipping those comments
include_trailing_comma = true           # Includes a trailing comma on multi line imports that include parentheses
lexicographical = false                 # Lexicographical order is strictly alphabetical order. For example by default isort will sort 1, 10, 2 into 1, 2, 10 - but with lexicographical sorting enabled it will remain 1, 10, 2
line_length = 79                        # The max length of an import line (used for wrapping long imports)
lines_after_imports = 2                 # The number of blank lines to place after imports
lines_between_sections = -1             # The number of lines to place between sections
lines_between_types = 0                 # The number of lines to place between direct and from imports
multi_line_output = 9                   # Multi line output (0-grid, 1-vertical, 2-hanging, 3-vert-hanging, 4-vert-grid, 5-vert-grid-grouped, 6-deprecated-alias-for-5, 7-noqa, 8-vertical-hanging-indent-bracket, 9-vertical-prefix-from-module-import, 10-hanging-indent-with-parentheses)
order_by_type = true                    # Order imports by type, which is determined by case, in addition to alphabetically
profile = "black"                       # Base profile type to use for configuration. Profiles include: black, django, pycharm, google, open_stack, plone, attrs, hug, wemake, appnexus
py_version=3                            # Tells isort to set the known standard library based on the specified Python version
remove_redundant_aliases = true         # Tells isort to remove redundant aliases from imports, such as `import os as os`
skip = [".gitignore", ".dockerignore"]  # Files that isort should skip over
skip_gitignore = true                   # Treat project as a git repository and ignore files listed in .gitignore
skip_glob = ["docs/*"]                  # Files that isort should skip over
skip_glob = ["tests/*"]                 # Files that isort should skip over
src_paths = ["src", "test"]             # Add an explicitly defined source path (modules within src paths have their imports automatically categorized as first_party). Glob expansion (* and **) is supported for this option


# https://github.com/pytest-dev/pytest/blob/main/pyproject.toml
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--strict-config --strict-markers --doctest-modules"
doctest_optionflags = "NORMALIZE_WHITESPACE ELLIPSIS"
python_files = ["test_*.py", "*_test.py", "test/*.py", "tests/*.py"]


# pylint --generate-toml-config >> pyproject.toml
[tool.pylint]
max-line-length = 79
ignore = [".git"]
good-names = ["i", "j", "k", "x", "Run", "_"]
design.max-args = 5                     # Maximum number of arguments for function / method.
design.max-attributes = 7               # Maximum number of attributes for a class (see R0902).
design.max-bool-expr = 5                # Maximum number of boolean expressions in an if statement (see R0916).
design.max-branches = 12                # Maximum number of branch for function / method body.
design.max-locals = 15                  # Maximum number of locals for function / method body.
design.max-parents = 7                  # Maximum number of parents for a class (see R0901).
design.max-public-methods = 20          # Maximum number of public methods for a class (see R0904).
design.max-returns = 6                  # Maximum number of return / yield for function / method body.
design.max-statements = 50              # Maximum number of statements in function / method body.
design.min-public-methods = 2           # Minimum number of public methods for a class (see R0903).
format.ignore-long-lines = "^(\\s*(# )?<?https?://\\S+>?$|.*models.))"  # Regexp for a line that is allowed to be longer than the limit.
format.max-line-length = 79             # Maximum number of characters on a single line.
format.max-module-lines = 1000          # Maximum number of lines in a module.
logging.logging-format-style = "new"    # The type of string formatting that logging methods do. `old` means using % formatting, `new` is for `{}` formatting.
logging.logging-modules = ["logging"]   # Logging modules to check that the string format arguments are in logging function parameter format.
refactoring.max-nested-blocks = 5       # Maximum number of nested blocks for function / method body
reports.output-format = "parseable"     # Set the output format. Available formats are text, parseable, colorized, json, and msvs (visual studio)
reports.reports = true                  # Tells whether to display a full report or only the messages.
reports.score = true                    # Activate the evaluation score.
similarities.min-similarity-lines = 4   # Minimum lines number of a similarity.
disable = [
    "missing-module-docstring",         # "C0114"
    "missing-class-docstring",          # "C0115"
    "missing-function-docstring",       # "C0116"
    "too-few-public-methods",           # "R0903"
    "too-many-arguments",               # "R0913"
]

To verify use: pip install .

12.3.1. References