| [build-system] |
| build-backend = "setuptools.build_meta" |
| |
| requires = [ "setuptools>=77" ] |
| |
| [project] |
| name = "pylint" |
| description = "python code static checker" |
| readme = "README.rst" |
| keywords = [ "lint", "linter", "python", "static code analysis" ] |
| license = "GPL-2.0-or-later" |
| license-files = [ "LICENSE", "CONTRIBUTORS.txt" ] |
| authors = [ |
| { name = "Python Code Quality Authority", email = "code-quality@python.org" }, |
| ] |
| requires-python = ">=3.10.0" |
| classifiers = [ |
| "Development Status :: 6 - Mature", |
| "Environment :: Console", |
| "Intended Audience :: Developers", |
| "Operating System :: OS Independent", |
| "Programming Language :: Python", |
| "Programming Language :: Python :: 3 :: Only", |
| "Programming Language :: Python :: 3.10", |
| "Programming Language :: Python :: 3.11", |
| "Programming Language :: Python :: 3.12", |
| "Programming Language :: Python :: 3.13", |
| "Programming Language :: Python :: Implementation :: CPython", |
| "Programming Language :: Python :: Implementation :: PyPy", |
| "Topic :: Software Development :: Debuggers", |
| "Topic :: Software Development :: Quality Assurance", |
| "Topic :: Software Development :: Testing", |
| "Typing :: Typed", |
| ] |
| dynamic = [ "version" ] |
| # All the dependencies of the project will be configured here, once pip fully supports PEP735 |
| # TODO: Remove all requirements.txt files and use this section instead once pip supports PEP735 |
| dependencies = [ |
| # Also upgrade requirements_test_min.txt. |
| # Pinned to dev of second minor update to allow editable installs and fix primer issues, |
| # see https://github.com/pylint-dev/astroid/issues/1341 |
| "astroid>=4.0.0b2,<=4.1.0.dev0", |
| "colorama>=0.4.5; sys_platform=='win32'", |
| "dill>=0.2; python_version<'3.11'", |
| "dill>=0.3.6; python_version>='3.11'", |
| "dill>=0.3.7; python_version>='3.12'", |
| "isort>=4.2.5,!=5.13,<7", |
| "mccabe>=0.6,<0.8", |
| "platformdirs>=2.2", |
| "tomli>=1.1; python_version<'3.11'", |
| "tomlkit>=0.10.1", |
| "typing-extensions>=3.10; python_version<'3.10'", |
| ] |
| |
| optional-dependencies.spelling = [ "pyenchant~=3.2" ] |
| optional-dependencies.testutils = [ "gitpython>3" ] |
| |
| urls."Bug Tracker" = "https://github.com/pylint-dev/pylint/issues" |
| urls."Discord Server" = "https://discord.com/invite/Egy6P8AMB5" |
| urls."Docs: Contributor Guide" = "https://pylint.readthedocs.io/en/latest/development_guide/contributor_guide/index.html" |
| urls."Docs: User Guide" = "https://pylint.readthedocs.io/en/latest/" |
| urls."homepage" = "https://github.com/pylint-dev/pylint" |
| urls."Source Code" = "https://github.com/pylint-dev/pylint" |
| urls."What's New" = "https://pylint.readthedocs.io/en/latest/whatsnew/3/" |
| scripts.pylint = "pylint:run_pylint" |
| scripts.pylint-config = "pylint:_run_pylint_config" |
| scripts.pyreverse = "pylint:run_pyreverse" |
| scripts.symilar = "pylint:run_symilar" |
| |
| [dependency-groups] |
| dev = [ |
| "contributors-txt>=1", |
| "pre-commit", |
| "tbump~=6.11.0", |
| ] |
| |
| test = [ |
| "coverage~=7.8", |
| "pytest-cov~=6.0", |
| "pytest-xdist~=3.6", |
| "six", |
| "tox>=3", |
| "types-setuptools==78.1.0.20250329", |
| { include-group = "test-min" }, |
| ] |
| |
| docs = [ |
| "furo==2024.8.6", |
| "sphinx==8.2.3", |
| "sphinx-reredirects<1", |
| "towncrier~=24.8", |
| ] |
| |
| # Configuration for the build system |
| test-min = [ |
| # Base test dependencies |
| "astroid==4.0.0a0", # Pinned to a specific version for tests |
| "py~=1.11.0", |
| "pytest~=8.3", |
| "pytest-benchmark~=5.1", |
| "pytest-timeout~=2.3", |
| "requests", |
| "setuptools; python_version>='3.12'", |
| "towncrier~=24.8", |
| "typing-extensions~=4.12", |
| ] |
| |
| [tool.setuptools.packages.find] |
| include = [ "pylint*" ] |
| |
| [tool.setuptools.package-dir] |
| # Simulate editable_mode=compat, described at: |
| # https://github.com/pypa/setuptools/issues/3767 |
| # TODO: remove after solving root cause described at: |
| # https://github.com/pylint-dev/astroid/pull/2267#issuecomment-1666642781 |
| "" = "." |
| |
| [tool.setuptools.package-data] |
| pylint = [ "testutils/testing_pylintrc", "py.typed" ] |
| |
| [tool.setuptools.dynamic] |
| version = { attr = "pylint.__pkginfo__.__version__" } |
| |
| [tool.ruff] |
| |
| # ruff is less lenient than pylint and does not make any exceptions |
| # (for docstrings, strings and comments in particular). |
| line-length = 115 |
| |
| extend-exclude = [ |
| "tests/**/data/", |
| "tests/**/functional/", |
| "tests/input/", |
| "tests/regrtest_data/", |
| ] |
| |
| lint.select = [ |
| "B", # bugbear |
| "D", # pydocstyle |
| "E", # pycodestyle |
| "F", # pyflakes |
| "I", # isort |
| "PIE", # flake8-pie |
| "PTH", # flake8-pathlib |
| "PYI", # flake8-pyi |
| "RUF", # ruff |
| "UP", # pyupgrade |
| "W", # pycodestyle |
| ] |
| lint.ignore = [ |
| "B905", # `zip()` without an explicit `strict=` parameter |
| "D100", # Missing docstring in public module |
| "D101", # Missing docstring in public class |
| "D102", # Missing docstring in public method |
| "D103", # Missing docstring in public function |
| "D104", # Missing docstring in public package |
| "D105", # Missing docstring in magic method |
| "D106", # Missing docstring in public nested class |
| "D107", # Missing docstring in `__init__` |
| "D205", # 1 blank line required between summary line and description |
| "D400", # First line should end with a period |
| "D401", # First line of docstring should be in imperative mood |
| "PTH100", # `os.path.abspath()` should be replaced by `Path.resolve()` |
| "PTH103", # `os.makedirs()` should be replaced by `Path.mkdir(parents=True)` |
| "PTH107", # `os.remove()` should be replaced by `Path.unlink()` |
| "PTH108", # `os.unlink()` should be replaced by `Path.unlink()` |
| "PTH109", # `os.getcwd()` should be replaced by `Path.cwd()` |
| "PTH110", # `os.path.exists()` should be replaced by `Path.exists()` |
| "PTH111", # `os.path.expanduser()` should be replaced by `Path.expanduser()` |
| "PTH112", # `os.path.isdir()` should be replaced by `Path.is_dir()` |
| "PTH113", # `os.path.isfile()` should be replaced by `Path.is_file()` |
| "PTH118", # `os.path.join()` should be replaced by `Path` with `/` operator |
| "PTH119", # `os.path.basename()` should be replaced by `Path.name` |
| "PTH120", # `os.path.dirname()` should be replaced by `Path.parent` |
| "PTH122", # `os.path.splitext()` should be replaced by `Path.suffix`, `Path.stem`, and `Path.parent` |
| "PTH123", # `open()` should be replaced by `Path.open()` |
| "PTH207", # Replace `glob` with `Path.glob` or `Path.rglob` |
| "PTH208", # Use `pathlib.Path.iterdir()` instead" |
| "RUF012", # mutable default values in class attributes |
| "UP038", # Use `X | Y` in `isinstance` call instead of `(X, Y)` |
| ] |
| lint.pydocstyle.convention = "pep257" |
| |
| [tool.isort] |
| profile = "black" |
| known_third_party = [ "platformdirs", "astroid", "sphinx", "isort", "pytest", "mccabe", "six", "toml" ] |
| extra_standard_library = [ "_string" ] |
| skip_glob = [ |
| "tests/functional/**", |
| "tests/input/**", |
| "tests/extensions/data/**", |
| "tests/regrtest_data/**", |
| "tests/data/**", |
| "astroid/**", |
| "venv/**", |
| ] |
| src_paths = [ "pylint" ] |
| |
| [tool.codespell] |
| ignore-words = [ "custom_dict.txt" ] |
| |
| # Disabled the spelling files for obvious reason, but also, |
| # the test file with typing extension imported as 'te' and: |
| # tests/functional/i/implicit/implicit_str_concat_latin1.py: |
| # - bad encoding |
| # pylint/pyreverse/diagrams.py and tests/pyreverse/test_diagrams.py: |
| # - An API from pyreverse use 'classe', and would need to be deprecated |
| # pylint/checkers/imports.py: |
| # - 'THIRDPARTY' is a value from isort that would need to be handled even |
| # if isort fix the typo in newer versions |
| # tests/functional/m/member/member_checks.py: |
| # - typos are voluntary to create credible 'no-member' |
| |
| skip = """ |
| tests/checkers/unittest_spelling.py,\ |
| CODE_OF_CONDUCT.md,\ |
| CONTRIBUTORS.txt,\ |
| pylint/checkers/imports.py,\ |
| pylint/pyreverse/diagrams.py,\ |
| tests/pyreverse/test_diagrams.py,\ |
| tests/functional/i/implicit/implicit_str_concat_latin1.py,\ |
| tests/functional/m/member/member_checks.py,\ |
| tests/functional/t/type/typevar_naming_style_rgx.py,\ |
| tests/functional/t/type/typevar_naming_style_default.py,\ |
| tests/functional/m/member/member_checks_async.py,\ |
| """ |
| |
| [tool.pytest.ini_options] |
| testpaths = [ "tests" ] |
| python_files = [ "*test_*.py" ] |
| addopts = "--strict-markers" |
| filterwarnings = [ |
| "error", |
| # Added in Python 3.14 |
| "ignore:'break' in a 'finally' block:SyntaxWarning", |
| "ignore:'return' in a 'finally' block:SyntaxWarning", |
| "ignore:'continue' in a 'finally' block:SyntaxWarning", |
| ] |
| markers = [ |
| "primer_stdlib: Checks for crashes and errors when running pylint on stdlib", |
| "benchmark: Baseline of pylint performance, if this regress something serious happened", |
| "timeout: Marks from pytest-timeout.", |
| "needs_two_cores: Checks that need 2 or more cores to be meaningful", |
| ] |
| |
| [tool.mypy] |
| scripts_are_modules = true |
| warn_unused_ignores = true |
| show_error_codes = true |
| enable_error_code = "ignore-without-code" |
| strict = true |
| # TODO: Remove this once pytest has annotations |
| disallow_untyped_decorators = false |
| |
| [[tool.mypy.overrides]] |
| ignore_missing_imports = true |
| module = [ |
| "_pytest.*", |
| "_string", |
| "astroid.*", |
| # `colorama` ignore is needed for Windows environment |
| "colorama", |
| "contributors_txt", |
| "coverage", |
| "dill", |
| "enchant.*", |
| "git.*", |
| "mccabe", |
| "pytest_benchmark.*", |
| "pytest", |
| "sphinx.*", |
| ] |
| |
| [tool.pyright] |
| include = [ |
| "pylint", |
| # not checking the tests yet, but we could |
| ] |
| pythonVersion = "3.10" |
| typeCheckingMode = "basic" |
| reportMissingImports = "none" # pytest / astroid are not detected |
| reportOptionalMemberAccess = "none" # 150 issues |
| reportArgumentType = "none" # 12 issues |
| reportAttributeAccessIssue = "none" # 11 issues |
| reportInvalidTypeForm = "none" # 6 issues |
| reportOptionalCall = "none" # 2 issues |
| reportGeneralTypeIssues = "none" # 1 issue |
| reportCallIssue = "none" # 1 issue |
| reportInvalidTypeVarUse = "none" # 2 warnings |
| |
| [tool.aliases] |
| test = "pytest" |