[project] name = "pydis-qualifier-25" version = "0.1.0" description = "Solution for the Python Discord 2025 Code Jam qualifier problem" authors = [{ name = "ItsDrike", email = "itsdrike@protonmail.com" }] readme = "README.md" requires-python = ">=3.13" dependencies = [] license = "MIT" [tool.uv] default-groups = ["dev", "lint", "test"] [dependency-groups] dev = ["poethepoet>=0.34.0"] lint = [ "basedpyright>=1.29.1", "pre-commit>=4.2.0", "ruff>=0.11.9", "typing-extensions>=4.13.2", ] test = [ "pytest>=8.3.5", "pytest-asyncio>=0.26.0", "pytest-cov>=6.1.1", "coverage>=7.8.0", "hypothesis>=6.136.4", ] [tool.ruff] target-version = "py313" line-length = 119 [tool.ruff.lint] select = ["ALL"] ignore = [ "C90", # mccabe "FBT", # flake8-boolean-trap "CPY", # flake8-copyright "EM", # flake8-errmsg "SLF", # flake8-self "ARG", # flake8-unused-arguments "TD", # flake8-todos "FIX", # flake8-fixme "D100", # Missing docstring in public module "D104", # Missing docstring in public package "D105", # Missing docstring in magic method "D107", # Missing docstring in __init__ "D203", # Blank line required before class docstring "D213", # Multi-line summary should start at second line (incompatible with D212) "D301", # Use r""" if any backslashes in a docstring "D401", # First line should be in imperative mood "D405", # Section name should be properly capitalized "D406", # Section name should end with a newline "D407", # Missing dashed underline after section "D408", # Section underline should be in the line following the section's name "D409", # Section underline should match the length of its name "D410", # Missing blank line after section "D411", # Missing blank line before section "D412", # No blank lines allowed between a section header and its content "D413", # Missing blank line after last section "D414", # Section has no content "D416", # Section name should end with a colon "D417", # Missing argument descrition in the docstring "ANN002", # Missing type annotation for *args "ANN003", # Missing type annotation for **kwargs "ANN204", # Missing return type annotation for special method "ANN401", # Dynamically typed expressions (typing.Any) disallowed "SIM102", # use a single if statement instead of nested if statements "SIM108", # Use ternary operator {contents} instead of if-else-block "COM812", # Missing trailing comma (conflicts with auto-formatter) "TRY003", # No f-strings in raise statements "UP024", # Using errors that alias OSError "PLR2004", # Using unnamed numerical constants "PGH003", # Using specific rule codes in type ignores "E731", # Don't asign a lambda expression, use a def "B904", # Raise without `from` within an `except` clause "G004", # Logging statement uses f-strings ] [tool.ruff.lint.per-file-ignores] "tests/**.py" = [ "D1", # Missing docstrings "S101", # Use of assert "S105", # Hard-coded secrets "S106", # Hard-coded passwords ] [tool.ruff.format] line-ending = "lf" [tool.basedpyright] pythonPlatform = "All" pythonVersion = "3.13" typeCheckingMode = "all" # Diagnostic behavior settings strictListInference = false strictDictionaryInference = false strictSetInference = false analyzeUnannotatedFunctions = true strictParameterNoneValue = true enableTypeIgnoreComments = true deprecateTypingAliases = true enableExperimentalFeatures = false disableBytesTypePromotions = true # Diagnostic rules reportAny = false reportExplicitAny = false reportImplicitStringConcatenation = false reportUnreachable = "hint" reportUnusedParameter = "hint" reportUnannotatedClassAttribute = false reportMissingTypeStubs = "hint" reportUninitializedInstanceVariable = true reportMissingParameterType = false # ruff's flake8-annotations (ANN) already covers this + gives us more control executionEnvironments = [ { root = "tests", extraPaths = [ ".", ], reportUnknownLambdaType = false, reportUnknownArgumentType = false }, ] [tool.pytest.ini_options] minversion = "6.0" testpaths = ["tests"] addopts = "--strict-markers --cov --no-cov-on-fail" markers = [ "basic: Covers the basic qualifier problem", "bonus: Covers the bonus qualifier problem", "extra: Covers some additional things on top of even the bonus", ] [tool.coverage.report] precision = 2 fail_under = 0 show_missing = true skip_covered = false skip_empty = false sort = "cover" exclude_lines = [ "\\#\\s*pragma: no cover", "^\\s*if (typing\\.)?TYPE_CHECKING:", "^\\s*@(abc\\.)?abstractmethod", "^\\s*@(typing\\.)?overload", "^\\s*def __repr__\\(", "^\\s*class .*\\bProtocol\\):", "^\\s*raise NotImplementedError", "^\\s*return NotImplemented", "^\\s*\\.\\.\\.", ] [tool.coverage.run] relative_files = true parallel = true branch = true timid = false source = ["src"] [tool.poe.tasks] test = "pytest -vv --failed-first" retest = "pytest -vv --last-failed"