# Basic Python Project Configuration # Use this template for simple Python projects [project] name = "my-project" version = "0.1.0" description = "A simple Python project" readme = "README.md" requires-python = ">=3.11" authors = [ {name = "Your Name", email = "your.email@example.com"} ] license = {text = "MIT"} keywords = ["example", "project"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", ] # Core dependencies dependencies = [ "requests>=2.31.0", ] # Development dependencies using PEP 735 dependency groups [dependency-groups] dev = [ "pytest>=8.4.2", "pytest-cov>=6.0.0", "pytest-mock>=3.15.1", "ruff>=0.13.3", "pyright>=1.1.406", "mypy>=1.18.2", "pre-commit>=4.3.0", ] # Entry points for CLI tools [project.scripts] my-tool = "my_project.cli:main" # Project URLs [project.urls] Homepage = "https://github.com/yourusername/my-project" Documentation = "https://my-project.readthedocs.io" Repository = "https://github.com/yourusername/my-project.git" Issues = "https://github.com/yourusername/my-project/issues" # Build system [build-system] requires = ["hatchling"] build-backend = "hatchling.build" # uv configuration [tool.uv] managed = true package = true default-groups = ["dev"] # Development server sources (optional) [tool.uv.sources] # Example: Install from git during development # requests = { git = "https://github.com/psf/requests", branch = "main" } # Ruff configuration [tool.ruff] target-version = "py311" line-length = 120 fix = true preview = true [tool.ruff.format] docstring-code-format = true quote-style = "double" line-ending = "lf" skip-magic-trailing-comma = true preview = true [tool.ruff.lint] extend-select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes "I", # isort "UP", # pyupgrade "YTT", # flake8-2020 "S", # flake8-bandit "B", # flake8-bugbear "A", # flake8-builtins "C4", # flake8-comprehensions "T10", # flake8-debugger "SIM", # flake8-simplify "C90", # mccabe "PGH", # pygrep-hooks "RUF", # ruff-specific "TRY", # tryceratops "DOC", # pydocstyle "D", # pydocstyle ] ignore = [ "COM812", # Missing trailing comma "COM819", # Missing trailing comma "D107", # Missing docstring in __init__ "D415", # First line should end with a period "E111", # Indentation is not a multiple of four "E117", # Over-indented for visual indent "E203", # whitespace before ':' "E402", # Module level import not at top "E501", # Line length exceeds maximum limit "ISC001", # isort configuration is missing "ISC002", # isort configuration is missing "Q000", # Remove bad quotes "Q001", # Remove bad quotes "Q002", # Remove bad quotes "Q003", # Remove bad quotes "TRY003", # Exception message should not be too long "S404", # module is possibly insecure "S603", # subprocess-without-shell-equals-true "S606", # start-process-with-no-shell "DOC501", # Missing raises section ] unfixable = ["F401", "S404", "S603", "S606", "DOC501"] [tool.ruff.lint.pycodestyle] max-line-length = 120 [tool.ruff.lint.isort] combine-as-imports = true split-on-trailing-comma = false force-single-line = false force-wrap-aliases = false [tool.ruff.lint.flake8-quotes] docstring-quotes = "double" [tool.ruff.lint.pydocstyle] convention = "google" [tool.ruff.lint.mccabe] max-complexity = 10 [tool.ruff.lint.per-file-ignores] "**/tests/*" = ["S101", "S603", "S607", "D102", "D200", "D100"] "**/test_*.py" = ["S101", "S603", "S607", "D102", "D200", "D100"] # Mypy configuration [tool.mypy] python_version = "3.11" strict = true extra_checks = true warn_unused_configs = true warn_redundant_casts = true warn_unused_ignores = true ignore_missing_imports = true show_error_codes = true pretty = true disable_error_code = "call-arg,arg-type" # Pytest configuration [tool.pytest.ini_options] addopts = [ "--cov=my_project", "--cov-report=term-missing", "-v", ] testpaths = ["tests"] python_files = ["test_*.py"] python_classes = ["Test*"] python_functions = ["test_*"] markers = [ "slow: tests that take significant time to run", "integration: integration tests", ] [tool.coverage.run] omit = ["*/tests/*"] [tool.coverage.report] show_missing = true fail_under = 70