pylint-4.0.5/0000775000175000017500000000000015146021447012751 5ustar epsilonepsilonpylint-4.0.5/MANIFEST.in0000664000175000017500000000047315146021447014513 0ustar epsilonepsiloninclude README.rst include requirements_test_min.txt include requirements_test_pre_commit.txt include requirements_test.txt include tox.ini graft doc graft examples graft script graft tests prune doc/_build prune tests/.benchmarks prune tests/.pylint_primer_tests global-exclude __pycache__ global-exclude *.py[co] pylint-4.0.5/README.rst0000664000175000017500000002277115146021447014451 0ustar epsilonepsilon`Pylint`_ ========= .. _`Pylint`: https://pylint.readthedocs.io/ .. This is used inside the doc to recover the start of the introduction .. image:: https://github.com/pylint-dev/pylint/actions/workflows/tests.yaml/badge.svg?branch=main :target: https://github.com/pylint-dev/pylint/actions .. image:: https://codecov.io/gh/pylint-dev/pylint/branch/main/graph/badge.svg?token=ZETEzayrfk :target: https://codecov.io/gh/pylint-dev/pylint .. image:: https://img.shields.io/pypi/v/pylint.svg :alt: PyPI Package version :target: https://pypi.python.org/pypi/pylint .. image:: https://readthedocs.org/projects/pylint/badge/?version=latest :target: https://pylint.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status .. image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/ambv/black .. image:: https://img.shields.io/badge/linting-pylint-yellowgreen :target: https://github.com/pylint-dev/pylint .. image:: https://results.pre-commit.ci/badge/github/pylint-dev/pylint/main.svg :target: https://results.pre-commit.ci/latest/github/pylint-dev/pylint/main :alt: pre-commit.ci status .. image:: https://bestpractices.coreinfrastructure.org/projects/6328/badge :target: https://bestpractices.coreinfrastructure.org/projects/6328 :alt: CII Best Practices .. image:: https://img.shields.io/ossf-scorecard/github.com/PyCQA/pylint?label=openssf%20scorecard&style=flat :target: https://api.securityscorecards.dev/projects/github.com/PyCQA/pylint :alt: OpenSSF Scorecard .. image:: https://img.shields.io/discord/825463413634891776.svg :target: https://discord.gg/qYxpadCgkx :alt: Discord What is Pylint? --------------- Pylint is a `static code analyser`_ for Python 2 or 3. The latest version supports Python 3.10.0 and above. .. _`static code analyser`: https://en.wikipedia.org/wiki/Static_code_analysis Pylint analyses your code without actually running it. It checks for errors, enforces a coding standard, looks for `code smells`_, and can make suggestions about how the code could be refactored. .. _`code smells`: https://martinfowler.com/bliki/CodeSmell.html Install ------- .. This is used inside the doc to recover the start of the short text for installation For command line use, pylint is installed with:: pip install pylint Or if you want to also check spelling with ``enchant`` (you might need to `install the enchant C library `_): .. code-block:: sh pip install pylint[spelling] It can also be integrated in most editors or IDEs. More information can be found `in the documentation`_. .. _in the documentation: https://pylint.readthedocs.io/en/latest/user_guide/installation/index.html .. This is used inside the doc to recover the end of the short text for installation What differentiates Pylint? --------------------------- Pylint is not trusting your typing and is inferring the actual values of nodes (for a start because there was no typing when pylint started off) using its internal code representation (astroid). If your code is ``import logging as argparse``, Pylint can check and know that ``argparse.error(...)`` is in fact a logging call and not an argparse call. This makes pylint slower, but it also lets pylint find more issues if your code is not fully typed. [inference] is the killer feature that keeps us using [pylint] in our project despite how painfully slow it is. - `Realist pylint user`_, 2022 .. _`Realist pylint user`: https://github.com/charliermarsh/ruff/issues/970#issuecomment-1381067064 pylint, not afraid of being a little slower than it already is, is also a lot more thorough than other linters. There are more checks, including some opinionated ones that are deactivated by default but can be enabled using configuration. How to use pylint ----------------- Pylint isn't smarter than you: it may warn you about things that you have conscientiously done or check for some things that you don't care about. During adoption, especially in a legacy project where pylint was never enforced, it's best to start with the ``--errors-only`` flag, then disable convention and refactor messages with ``--disable=C,R`` and progressively re-evaluate and re-enable messages as your priorities evolve. Pylint is highly configurable and permits to write plugins in order to add your own checks (for example, for internal libraries or an internal rule). Pylint also has an ecosystem of existing plugins for popular frameworks and third-party libraries. .. note:: Pylint supports the Python standard library out of the box. Third-party libraries are not always supported, so a plugin might be needed. A good place to start is ``PyPI`` which often returns a plugin by searching for ``pylint ``. `pylint-pydantic`_, `pylint-django`_ and `pylint-sonarjson`_ are examples of such plugins. More information about plugins and how to load them can be found at `plugins`_. .. _`plugins`: https://pylint.readthedocs.io/en/latest/development_guide/how_tos/plugins.html#plugins .. _`pylint-pydantic`: https://pypi.org/project/pylint-pydantic .. _`pylint-django`: https://github.com/pylint-dev/pylint-django .. _`pylint-sonarjson`: https://github.com/cnescatlab/pylint-sonarjson-catlab Advised linters alongside pylint -------------------------------- Projects that you might want to use alongside pylint include ruff_ (**really** fast, with builtin auto-fix and a large number of checks taken from popular linters, but implemented in ``rust``) or flake8_ (a framework to implement your own checks in python using ``ast`` directly), mypy_, pyright_ / pylance or pyre_ (typing checks), bandit_ (security oriented checks), black_ and isort_ (auto-formatting), autoflake_ (automated removal of unused imports or variables), pyupgrade_ (automated upgrade to newer python syntax) and pydocstringformatter_ (automated pep257). .. _ruff: https://github.com/astral-sh/ruff .. _flake8: https://github.com/PyCQA/flake8 .. _bandit: https://github.com/PyCQA/bandit .. _mypy: https://github.com/python/mypy .. _pyright: https://github.com/microsoft/pyright .. _pyre: https://github.com/facebook/pyre-check .. _black: https://github.com/psf/black .. _autoflake: https://github.com/myint/autoflake .. _pyupgrade: https://github.com/asottile/pyupgrade .. _pydocstringformatter: https://github.com/DanielNoord/pydocstringformatter .. _isort: https://pycqa.github.io/isort/ Additional tools included in pylint ----------------------------------- Pylint ships with two additional tools: - pyreverse_ (standalone tool that generates package and class diagrams.) - symilar_ (duplicate code finder that is also integrated in pylint) .. _pyreverse: https://pylint.readthedocs.io/en/latest/additional_tools/pyreverse/index.html .. _symilar: https://pylint.readthedocs.io/en/latest/additional_tools/symilar/index.html .. This is used inside the doc to recover the end of the introduction Contributing ------------ .. This is used inside the doc to recover the start of the short text for contribution We welcome all forms of contributions such as updates for documentation, new code, checking issues for duplicates or telling us that we can close them, confirming that issues still exist, `creating issues because you found a bug or want a feature`_, etc. Everything is much appreciated! Please follow the `code of conduct`_ and check `the Contributor Guides`_ if you want to make a code contribution. .. _creating issues because you found a bug or want a feature: https://pylint.readthedocs.io/en/latest/contact.html#bug-reports-feedback .. _code of conduct: https://github.com/pylint-dev/pylint/blob/main/CODE_OF_CONDUCT.md .. _the Contributor Guides: https://pylint.readthedocs.io/en/latest/development_guide/contribute.html .. This is used inside the doc to recover the end of the short text for contribution Show your usage ----------------- You can place this badge in your README to let others know your project uses pylint. .. image:: https://img.shields.io/badge/linting-pylint-yellowgreen :target: https://github.com/pylint-dev/pylint Learn how to add a badge to your documentation in `the badge documentation`_. .. _the badge documentation: https://pylint.readthedocs.io/en/latest/user_guide/installation/badge.html License ------- pylint is, with a few exceptions listed below, `GPLv2 `_. The icon files are licensed under the `CC BY-SA 4.0 `_ license: - `doc/logo.png `_ - `doc/logo.svg `_ Support ------- Please check `the contact information`_. .. _`the contact information`: https://pylint.readthedocs.io/en/latest/contact.html .. |tideliftlogo| image:: https://raw.githubusercontent.com/pylint-dev/pylint/main/doc/media/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White.png :width: 200 :alt: Tidelift .. list-table:: :widths: 10 100 * - |tideliftlogo| - Professional support for pylint is available as part of the `Tidelift Subscription`_. Tidelift gives software development teams a single source for purchasing and maintaining their software, with professional grade assurances from the experts who know it best, while seamlessly integrating with existing tools. .. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-pylint?utm_source=pypi-pylint&utm_medium=referral&utm_campaign=readme pylint-4.0.5/doc/0000775000175000017500000000000015146021447013516 5ustar epsilonepsilonpylint-4.0.5/doc/short_text_installation.rst0000664000175000017500000000034215146021447021233 0ustar epsilonepsilon.. include:: ../README.rst :start-after: This is used inside the doc to recover the start of the short text for installation :end-before: This is used inside the doc to recover the end of the short text for installation pylint-4.0.5/doc/development_guide/0000775000175000017500000000000015146021447017215 5ustar epsilonepsilonpylint-4.0.5/doc/development_guide/contributor_guide/0000775000175000017500000000000015146021447022744 5ustar epsilonepsilonpylint-4.0.5/doc/development_guide/contributor_guide/release.rst0000664000175000017500000001244115146021447025120 0ustar epsilonepsilonReleasing a pylint version ========================== So, you want to release the ``X.Y.Z`` version of pylint ? Releasing a major or minor version ---------------------------------- **Before releasing a major or minor version check if there are any unreleased commits on the maintenance branch. If so, release a last patch release first. See ``Releasing a patch version``.** - Write the ``Summary -- Release highlights`` in ``doc/whatsnew`` and upgrade the release date. - Install the release dependencies: ``pip3 install -r requirements_test.txt`` - Bump the version and release by using ``tbump X.Y.0 --no-push --no-tag``. (For example: ``tbump 2.4.0 --no-push --no-tag``) - Check the commit created with ``git show`` amend the commit if required. - Move the ``main`` branch up to a dev version with ``tbump``: .. code:: bash tbump X.Y+1.0-dev0 --no-tag --no-push # You can interrupt after the first step git commit -am "Upgrade the version to x.y+1.0-dev0 following x.y.0 release" For example: .. code:: bash tbump 2.5.0-dev0 --no-tag --no-push git commit -am "Upgrade the version to 2.5.0-dev0 following 2.4.0 release" - tbump will have created a new ``What's new in Pylint X.Y+1`` document. Add it to ``doc/whatsnew/3/index.rst``. Take a look at the examples from ``doc/whatsnew``. Commit that with ``git commit -a --amend``. - Push to a release branch - Open a merge request with the two commits (no one can push directly on ``main``) - After the merge, recover the merged commits on ``main`` and tag the first one (the version should be ``X.Y.Z``) as ``vX.Y.Z`` (For example: ``v2.4.0``) - Push the tag. - Release the version on GitHub with the same name as the tag and copy and paste the appropriate changelog in the description. This triggers the PyPI release. - Create a ``maintenance/X.Y.x`` (For example: ``maintenance/2.4.x`` from the ``v2.4.0`` tag.) - Upgrade the pattern for the protected branches in the settings under ``Branches`` / ``Branch protection rules``. (For example: ``maintenance/2.4*`` instead of ``maintenance/2.3*``.). There’s a lot of configuration done in these settings, do NOT recreate it from scratch. - Delete the ``maintenance/X.Y-1.x`` branch. (For example: ``maintenance/2.3.x``) - Select all the *closed* issues labelled ``backport maintenance/X.Y-1.x`` and label them ``backported``, then rename the ``backport maintenance/X.Y-1.x`` label to ``backport maintenance/X.Y.x`` (for example rename ``backport maintenance/2.3.x`` to ``backport maintenance/2.4.x``) - Close the current milestone and create the new ones (For example: close ``2.4.0``, create ``2.4.1`` and ``2.6.0``) - Hide and deactivate all the patch releases for the previous minor release on `readthedocs `__, except the last one. (For example: hide ``v2.4.0``, ``v2.4.1``, ``v2.4.2`` and keep only ``v2.4.3``) Back-porting a fix from ``main`` to the maintenance branch ---------------------------------------------------------- Whenever a PR on ``main`` should be released in a patch release on the current maintenance branch: - Label the PR with ``backport maintenance/X.Y-1.x``. (For example ``backport maintenance/2.3.x``) - Squash the PR before merging (alternatively rebase if there’s a single commit) - (If the automated cherry-pick has conflicts) - Add a ``Needs backport`` label and do it manually. - You might alternatively also: - Cherry-pick the changes that create the conflict if it’s not a new feature before doing the original PR cherry-pick manually. - Decide to wait for the next minor to release the PR - In any case upgrade the milestones in the original PR and newly cherry-picked PR to match reality. - Release a patch version Releasing a patch version ------------------------- We release patch versions when a crash or a bug is fixed on the main branch and has been cherry-picked on the maintenance branch. - Install the release dependencies: ``pip3 install -r requirements_test.txt`` - Bump the version and release by using ``tbump X.Y-1.Z --no-push``. (For example: ``tbump 2.3.5 --no-push``) - Check the result visually with ``git show``. - Open a merge request of ``release-X.Y-1.Z'`` in ``maintenance/X.Y.x`` (For example: ``release-2.3.5-branch`` in ``maintenance/2.3.x``) to run the CI tests for this branch. - Create and push the tag. - Release the version on GitHub with the same name as the tag and copy and paste the changelog from the ReadtheDoc generated documentation from the pull request pipeline in the description. This triggers the PyPI release. - Merge the ``maintenance/X.Y.x`` branch on the main branch. The main branch should have the changelog for ``X.Y-1.Z+1`` (For example ``v2.3.6``). This merge is required so ``pre-commit autoupdate`` works for pylint. - Fix version conflicts properly, or bump the version to ``X.Y.0-devZ`` (For example: ``2.4.0-dev6``) before pushing on the main branch - Close the current milestone and create the new one (For example: close ``2.3.5``, create ``2.3.6``) Milestone handling ------------------ We move issues that were not done to the next milestone and block releases only if there are any open issues labelled as ``blocker``. pylint-4.0.5/doc/development_guide/contributor_guide/governance.rst0000664000175000017500000001102015146021447025617 0ustar epsilonepsilon============ Governance ============ How to become part of the project ? ----------------------------------- How to become a contributor ? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Follow the code of conduct - Search by yourself before asking for help - Open an issue - Investigate an issue and report your finding - Open a merge request directly if you feel it's a consensual change Reporting a bug is being a contributor already. How to become a triager ? ^^^^^^^^^^^^^^^^^^^^^^^^^ - Create a pylint plugin, then migrate it to the 'pylint-dev' github organization. Or: - Contribute for more than 3 releases consistently. - Do not be too opinionated, follow the code of conduct without requiring emotional works from the maintainers. It does not mean that disagreements are impossible, only that arguments should stay technical and reasonable so the conversation is civil and productive. - Have a maintainer suggest that you become triager, without you asking - Get unanimous approval or neutral agreement from current maintainers. How to become a maintainer ? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Take ownership of a part of the code that is not maintained well at the moment or that you contributed personally (if we feel we can't merge something without your review, you're going to be able to merge those yourself soon). Or: - Contribute two big code merge requests over multiple releases (for example one checker in 2.13 and the following bug after release and one complicated bug fixes in 2.14). Otherwise contributing for more than 3 releases consistently with great technical and interpersonal skills. - Triage for multiple months (close duplicate, clean up issues, answer questions...) - Have an admin suggest that you become maintainer, without you asking - Get unanimous approval or neutral agreement from current maintainers. How to become an admin ? ^^^^^^^^^^^^^^^^^^^^^^^^ - Contribute for several hundreds of commits over a long period of time with excellent interpersonal skills and code quality. - Maintain pylint for multiple years (code review, triaging and maintenance tasks). - At this point probably have another admin leave the project or become inactive for years. - Have an admin suggest that you become an admin, without you asking. - Get unanimous approval or neutral agreement from current admins. How are decisions made ? ------------------------ Everyone is expected to follow the code of conduct. pylint is a do-ocracy / democracy. You're not allowed to behave poorly because you contributed a lot. But if you're not going to do the future maintenance work, your valid opinions might not be taken into account by those that will be affected by it. What are the fundamental tenets of pylint development? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ General: - We favor correctness over performance, because pylint is not used primarily for its performance. Performance is still important and needs to be taken into account from the get go. - We then favor false negatives over false positives if correctness is impossible to achieve. - We try to keep the configuration sane, but if there's a hard decision to take we add an option so that pylint is multiple sizes fit all (after configuration) Where to add a new checker or message: - Error messages (things that will result in an error if run) should be builtin checks, activated by default - Messages that are opinionated, even slightly, should be opt-in (added as :ref:`an extension`) - We don't shy away from opinionated checks (like the while checker), but there's such a thing as too opinionated, if something is too opinionated it should be an external :ref:`pylint plugin`. How are disagreements handled ? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ When something is not consensual users, maintainers, and admins discuss until an agreement is reached. Depending on the difficulty of the discussion and the importance of a fast resolution, a decision can be taken: - Unanimously between discussion participants, contributors and maintainers (preferably) - By asking discussion participants for their opinions with an emoji survey in the issue and then using the majority if no maintainers feel strongly about the issue. - By majority of admins if no admins feel strongly about the issue. - By asking all users for their opinions in a new issue that will be pinned for multiple months before taking the decision if two admins feel strongly on an opposite side of the issue. Once the result is obvious the majority decision is not up for discussion anymore. pylint-4.0.5/doc/development_guide/contributor_guide/major_release.rst0000664000175000017500000000022515146021447026305 0ustar epsilonepsilon- In **major releases** (``1.0.0``) we change everything else (pylint options, json output, dev API...) while still trying to minimize disruption. pylint-4.0.5/doc/development_guide/contributor_guide/contribute.rst0000664000175000017500000001750115146021447025660 0ustar epsilonepsilon============== Contributing ============== .. _repository: Finding something to do ----------------------- Want to contribute to pylint? There's a lot of things you can do. Here's a list of links you can check depending on what you want to do: - `Asking a question on discord`_, or `on github`_ - `Opening an issue`_ - `Making the documentation better`_ - `Making the error message better`_ - `Reproducing bugs and confirming that issues are valid`_ - `Investigating or debugging complicated issues`_ - `Designing or specifying a solution`_ - `Giving your opinion on ongoing discussion`_ - `Fixing bugs and crashes`_ - `Fixing false positives`_ - `Creating new features or fixing false negatives`_ - `Reviewing pull requests`_ .. _`Asking a question on discord`: https://discord.com/invite/qYxpadCgkx .. _`on github`: https://github.com/pylint-dev/pylint/issues/new/choose .. _`Opening an issue`: https://github.com/pylint-dev/pylint/issues/new?assignees=&labels=Needs+triage+%3Ainbox_tray%3A&template=BUG-REPORT.yml .. _`Making the documentation better`: https://github.com/pylint-dev/pylint/issues?q=is%3Aopen+is%3Aissue+label%3A%22Documentation+%3Agreen_book%3A%22 .. _`Making the error message better`: https://github.com/pylint-dev/pylint/issues?q=is%3Aopen%20is%3Aissue%20project%3Apylint-dev%2Fpylint%2F4 .. _`Reproducing bugs and confirming that issues are valid`: https://github.com/pylint-dev/pylint/issues?q=is%3Aopen+is%3Aissue+label%3A%22Needs+reproduction+%3Amag%3A%22%2C%22Cannot+reproduce+%F0%9F%A4%B7%22 .. _`Investigating or debugging complicated issues`: https://github.com/pylint-dev/pylint/issues?q=is%3Aopen+is%3Aissue+label%3A%22Needs+investigation+%F0%9F%94%AC%22 .. _`Designing or specifying a solution`: https://github.com/pylint-dev/pylint/issues?q=is%3Aopen+is%3Aissue+label%3A%22Needs+design+proposal+%3Alock%3A%22%2C%22Needs+specification+%3Aclosed_lock_with_key%3A%22 .. _`Giving your opinion on ongoing discussion`: https://github.com/pylint-dev/pylint/issues?q=is%3Aopen+is%3Aissue+label%3A%22Needs+decision+%3Alock%3A%22 .. _`Fixing bugs and crashes`: https://github.com/pylint-dev/pylint/issues?q=is%3Aopen+is%3Aissue+label%3A%22Bug+%3Abeetle%3A%22%2C%22Crash+%F0%9F%92%A5%22 .. _`Fixing false positives`: https://github.com/pylint-dev/pylint/issues?q=is%3Aopen+is%3Aissue+label%3A%22False+Positive+%F0%9F%A6%9F%22 .. _`Creating new features or fixing false negatives`: https://github.com/pylint-dev/pylint/issues?q=is%3Aopen+is%3Aissue+label%3A%22False+Negative+%F0%9F%A6%8B%22%2C%22Enhancement+%E2%9C%A8%22 .. _`Reviewing pull requests`: https://github.com/pylint-dev/pylint/pulls?q=is%3Aopen+is%3Apr+label%3A%22Needs+review+%F0%9F%94%8D%22 If you are a pylint maintainer there's also: - `Triaging issues`_ - `Labeling issues that do not have an actionable label yet`_ - `Preparing the next patch release`_ - `Checking stale pull requests status`_ .. _`Triaging issues`: https://github.com/pylint-dev/pylint/issues?q=is%3Aopen+is%3Aissue+label%3A%22Needs+triage+%3Ainbox_tray%3A%22 .. _`Labeling issues that do not have an actionable label yet`: https://github.com/pylint-dev/pylint/issues?q=is%3Aopen+is%3Aissue+-label%3A%22Needs+astroid+Brain+%F0%9F%A7%A0%22+-label%3A%22Needs+astroid+update%22+-label%3A%22Needs+backport%22+-label%3A%22Needs+decision+%3Alock%3A%22+-label%3A%22Needs+investigation+%F0%9F%94%AC%22+-label%3A%22Needs+PR%22+-label%3A%22Needs+reproduction+%3Amag%3A%22+-label%3A%22Needs+review+%F0%9F%94%8D%22+-label%3A%22Needs+triage+%3Ainbox_tray%3A%22+-label%3A%22Waiting+on+author%22+-label%3A%22Work+in+progress%22+-label%3AMaintenance+sort%3Aupdated-desc+-label%3A%22Needs+specification+%3Aclosed_lock_with_key%3A%22+-label%3A%22Needs+design+proposal+%3Alock%3A%22 .. _`Preparing the next patch release`: https://github.com/pylint-dev/pylint/issues?q=is%3Aopen+is%3Aissue+label%3A%22Needs+backport%22 .. _`Checking stale pull requests status`: https://github.com/pylint-dev/pylint/pulls?q=is%3Aopen+is%3Apr+label%3A%22Work+in+progress%22%2C%22Needs+astroid+update%22%2C%22Waiting+on+author%22 Creating a pull request ----------------------- Got a change for Pylint? Below are a few steps you should take to make sure your patch gets accepted: - You must use at least Python 3.8 for development of Pylint as it gives you access to the latest ``ast`` parser and some pre-commit hooks do not support python 3.7. - Install the dev dependencies, see :ref:`contributor_install`. - Use our test suite and write new tests, see :ref:`contributor_testing`. .. keep this in sync with the description of PULL_REQUEST_TEMPLATE.md! - Document your change, if it is a non-trivial one: * A maintainer might label the issue ``skip-news`` if the change does not need to be in the changelog. * Otherwise, create a news fragment with ``towncrier create .`` which will be included in the changelog. ```` can be one of the types defined in `./towncrier.toml`. If necessary you can write details or offer examples on how the new change is supposed to work. * Generating the doc is done with ``tox -e docs`` - Send a pull request from GitHub (see `About pull requests`_ for more insight about this topic). - Write comprehensive commit messages and/or a good description of what the PR does. Relate your change to an issue in the tracker if such an issue exists (see `Closing issues via commit messages`_ of the GitHub documentation for more information on this) - Keep the change small, separate the consensual changes from the opinionated one. * Don't hesitate to open multiple PRs if the change requires it. If your review is so big it requires to actually plan and allocate time to review, it's more likely that it's going to go stale. * Maintainers might have multiple 5 to 10 minutes review windows per day, Say while waiting for their teapot to boil, or for their partner to recover from their hilarious nerdy joke, but only one full hour review time per week, if at all. - If you used multiple emails or multiple names when contributing, add your mails and preferred name in the ``script/.contributors_aliases.json`` file. .. _`Closing issues via commit messages`: https://github.blog/2013-01-22-closing-issues-via-commit-messages/ .. _`About pull requests`: https://support.github.com/features/pull-requests .. _tox: https://tox.readthedocs.io/en/latest/ .. _pytest: https://docs.pytest.org/en/latest/ .. _black: https://github.com/psf/black .. _isort: https://github.com/PyCQA/isort .. _astroid: https://github.com/pylint-dev/astroid Tips for Getting Started with Pylint Development ------------------------------------------------ * Read the :ref:`technical-reference`. It gives a short walk through of the pylint codebase and will help you identify where you will need to make changes for what you are trying to implement. * ``astroid.extract_node`` is your friend. Most checkers are AST based, so you will likely need to interact with ``astroid``. A short example of how to use ``astroid.extract_node`` is given :ref:`here `. * When fixing a bug for a specific check, search the code for the warning message to find where the warning is raised, and therefore where the logic for that code exists. * When adding a new checker class you can use the :file:`get_unused_message_id_category.py` script in :file:`./script` to get a message id that is not used by any of the other checkers. Building the documentation ---------------------------- You can use the makefile in the doc directory to build the documentation:: $ make -C doc/ install-dependencies $ make -C doc/ html We're reusing generated files for speed, use ``make clean`` or ``tox -e docs`` when you want to start from scratch. How to choose the target version ? ---------------------------------- Choose depending on the kind of change you're doing: .. include:: patch_release.rst .. include:: minor_release.rst .. include:: major_release.rst pylint-4.0.5/doc/development_guide/contributor_guide/oss_fuzz.rst0000664000175000017500000001265215146021447025366 0ustar epsilonepsilon====================== OSS-Fuzz integration ====================== Platform overview ----------------- `OSS-Fuzz `_ is Google's free fuzzing platform for open source software. It runs astroid's fuzz targets to help detect reliability issues that could affect astroid and Pylint. Google provides public `build logs `_ and `fuzzing stats `_, but most of the details about bug reports and fuzzed testcases require approved access. Gaining access ^^^^^^^^^^^^^^ The configuration files for the OSS-Fuzz integration can be found in the `OSS-Fuzz repository `_. The ``project.yaml`` file controls who has access to bug reports and testcases. Ping the maintainers if you'd like to be added to the list (note: a Google account is required for access). Fuzzing progress ---------------- Once you have access to OSS-Fuzz, you can log in to https://oss-fuzz.com/ with your Google account to see a dashboard of astroid's fuzzing progress. Testcases ^^^^^^^^^ The dashboard contains a link to a `testcases page `_ that lists all testcases that currently trigger a bug in astroid. Every testcase has a dedicated page with links to view and download a minimized testcase for reproducing the failure. Each testcase page also contains a stacktrace for the failure and stats about how often the failure is encountered while fuzzing. Reproducing a failure """"""""""""""""""""" You can download a minimized testcase and run it locally to debug a failure on your machine. For example, to reproduce a failure with the ``fuzz_parse`` fuzz target, you can run the following commands: .. code:: bash mkdir fuzzing-repro cd fuzzing-repro # Note: Atheris doesn't support Python 3.12+ yet: # https://github.com/google/atheris/issues/82 uv venv --python 3.11 source .venv/bin/activate git clone https://github.com/pylint-dev/astroid.git cd astroid uv pip install atheris==2.3.0 uv pip install --editable . # Save the minimized testcase as `minimized.py` in the astroid directory cat << EOF > ./run_fuzz_parse.py import astroid import atheris with open('minimized.py', 'rb') as f: fdp = atheris.FuzzedDataProvider(f.read()) code = fdp.ConsumeUnicodeNoSurrogates(fdp.ConsumeIntInRange(0, 4096)) astroid.builder.parse(code) EOF python ./run_fuzz_parse.py If the failure does not reproduce locally, you can try reproducing the issue in an OSS-Fuzz container: .. code:: bash git clone https://github.com/google/oss-fuzz.git cd oss-fuzz python infra/helper.py build_image astroid python infra/helper.py build_fuzzers astroid python infra/helper.py reproduce astroid fuzz_parse minimized.py Some failures may only be reproducible in an OSS-Fuzz container because of differences in Python versions between the OSS-Fuzz platform and your local environment. Code coverage ^^^^^^^^^^^^^ The dashboard also links to code coverage data for individual fuzz targets and combined code coverage data for all targets (click on the "TOTAL COVERAGE" link for the combined data). The combined coverage data is helpful for identifying coverage gaps, insufficient corpus data, and potential candidates for future fuzz targets. Bug reports ^^^^^^^^^^^ Bug reports for new failures are automatically filed in the OSS-Fuzz bug tracker with an `astroid label `_. Make sure you are logged in to view all existing issues. Build maintenance ----------------- Google runs compiled fuzz targets on Google Compute Engine VMs. This architecture requires each project to provide a ``Dockerfile`` and ``build.sh`` script to download code, configure dependencies, compile fuzz targets, and package any corpus files. astroid's build files and fuzz-target code can be found in the `OSS-Fuzz repo `_. If dependencies change or if new fuzz targets are added, then you may need to modify the build files and build a new Docker image for OSS-Fuzz. Building an image ^^^^^^^^^^^^^^^^^ Run the following commands to build astroid's OSS-Fuzz image and fuzz targets: .. code:: bash git clone https://github.com/google/oss-fuzz.git cd oss-fuzz python infra/helper.py build_image astroid python infra/helper.py build_fuzzers astroid Any changes you make to the build files must be submitted as pull requests to the OSS-Fuzz repo. Debugging build failures """""""""""""""""""""""" You can debug build failures during the ``build_fuzzers`` stage by creating a container and manually running the ``compile`` command: .. code:: bash # Create a container for building fuzz targets python infra/helper.py shell astroid # Run this command inside the container to build the fuzz targets compile The ``build.sh`` script will be located at ``/src/build.sh`` inside the container. Quick links ----------- - `OSS-Fuzz dashboard `_ - `OSS-Fuzz configuration files, build scripts, and fuzz targets for astroid `_ - `All open OSS-Fuzz bugs for astroid `_ - `Google's OSS-Fuzz documentation `_ pylint-4.0.5/doc/development_guide/contributor_guide/tests/0000775000175000017500000000000015146021447024106 5ustar epsilonepsilonpylint-4.0.5/doc/development_guide/contributor_guide/tests/install.rst0000664000175000017500000000306515146021447026312 0ustar epsilonepsilon.. _contributor_install: Contributor installation ======================== Basic installation ------------------ Pylint is developed using the git_ distributed version control system. You can clone Pylint using :: git clone https://github.com/pylint-dev/pylint Before you start testing your code, you need to install your source-code package locally. Suppose you just cloned pylint with the previous ``git clone`` command. To set up your environment for testing, open a terminal and run:: cd pylint python3 -m venv venv source venv/bin/activate pip install -r requirements_test_min.txt pip install -e . This ensures your testing environment is similar to Pylint's testing environment on GitHub. **Optionally** (Because there's an auto-fix if you open a merge request): We have pre-commit hooks which should take care of the autoformatting for you before each commit. To enable it, run ``pre-commit install`` in the ``pylint`` root directory. Astroid installation -------------------- If you're testing new changes in astroid you need to also clone astroid_ and install with an editable installation alongside pylint as follows:: # Suppose you're in the pylint directory git clone https://github.com/pylint-dev/astroid.git python3 -m pip install -e astroid/ You're now using the local astroid in pylint and can control the version with git for example:: cd astroid/ git switch my-astroid-dev-branch .. _pytest-cov: https://pypi.org/project/pytest-cov/ .. _astroid: https://github.com/pylint-dev/astroid .. _git: https://git-scm.com/ pylint-4.0.5/doc/development_guide/contributor_guide/tests/writing_test.rst0000664000175000017500000001700715146021447027367 0ustar epsilonepsilon.. _writing_tests: Writing tests ============= Pylint uses three types of tests: unittests, functional tests and primer tests. - :ref:`unittests ` can be found in ``pylint/tests``. Unless you're working on pylint's internal you're probably not going to have to write any. - :ref:`Global functional tests ` can be found in the ``pylint/tests/functional``. They are mainly used to test whether Pylint emits the correct messages. - :ref:`Configuration's functional tests ` can be found in the ``pylint/tests/config/functional``. They are used to test Pylint's configuration loading. - :ref:`Primer tests ` you can suggest a new external repository to check but there's nothing to do most of the time. .. _writing_unittests: Unittest tests -------------- Most other tests reside in the '/pylint/test' directory. These unittests can be used to test almost all functionality within Pylint. A good step before writing any new unittests is to look at some tests that test a similar functionality. This can often help write new tests. If your new test requires any additional files you can put those in the ``/pylint/test/regrtest_data`` directory. This is the directory we use to store any data needed for the unittests. .. _writing_functional_tests: Functional tests ---------------- These are located under ``/pylint/test/functional`` and they are formed of multiple components. First, each Python file is considered to be a test case and it should be accompanied by a ``.txt`` file, having the same name. The ``.txt`` file contains the ``pylint`` messages that are supposed to be emitted by the given test file. In your ``.py`` test file, each line for which Pylint is supposed to emit a message has to be annotated with a comment following this pattern ``# [message_symbol]``, as in:: a, b, c = 1 # [unbalanced-tuple-unpacking] If multiple messages are expected on the same line, then this syntax can be used:: a, b, c = 1.test # [unbalanced-tuple-unpacking, no-member] You can also use ``# +n: [`` where ``n`` is an integer to deal with special cases, e.g., where the above regular syntax makes the line too long:: A = 5 # +1: [singleton-comparison] B = A == None # The test will look for the `singleton-comparison` message in this line If you need special control over Pylint's configuration, you can also create a ``.rc`` file, which can set sections of Pylint's configuration. The ``.rc`` file can also contain a section ``[testoptions]`` to pass options for the functional test runner. The following options are currently supported: - "min_pyver": Minimal python version required to run the test - "max_pyver": Python version from which the test won't be run. If the last supported version is 3.9 this setting should be set to 3.10. - "min_pyver_end_position": Minimal python version required to check the end_line and end_column attributes of the message - "requires": Packages required to be installed locally to run the test - "except_implementations": List of python implementations on which the test should not run - "exclude_platforms": List of operating systems on which the test should not run **Different output for different Python versions** Sometimes the linting result can change between Python releases. In these cases errors can be marked as conditional. Supported operators are ``<``, ``<=``, ``>`` and ``>=``. .. code-block:: python def some_func() -> X: # <3.14:[undefined-variable] ... # It can also be combined with offsets # +1:<3.14:[undefined-variable] def some_other_func() -> X: ... class X: ... Since the output messages are different, it is necessary to add two separate files for it. First ``.314.txt``, this will include the output messages for ``>=3.14``, i.e. should be empty here. Second ``.txt``, this will be the default for all other Python versions. .. note:: This does only work if the code itself is parsable in all tested Python versions. For new syntax, use ``min_pyver`` / ``max_pyver`` instead. **Functional test file locations** For existing checkers, new test cases should preferably be appended to the existing test file. For new checkers, a new file ``new_checker_message.py`` should be created (Note the use of underscores). This file should then be placed in the ``test/functional/n`` sub-directory. Some additional notes: - If the checker is part of an extension the test should go in ``test/functional/ext/extension_name`` - If the test is a regression test it should go in ``test/r/regression`` or ``test/r/regression_02``. The file name should start with ``regression_``. - For some sub-directories, such as ``test/functional/u``, there are additional sub-directories (``test/functional/u/use``). Please check if your test file should be placed in any of these directories. It should be placed there if the sub-directory name matches the word before the first underscore of your test file name. The folder structure is enforced when running the test suite, so you might be directed to put the file in a different sub-directory. **Running and updating functional tests** During development, it's sometimes helpful to run all functional tests in your current environment in order to have faster feedback. Run from Pylint root directory with:: python tests/test_functional.py You can use all the options you would use for pytest_, for example ``-k "test_functional[len_checks]"``. Furthermore, if required the .txt file with expected messages can be regenerated based on the current output by appending ``--update-functional-output`` to the command line:: python tests/test_functional.py --update-functional-output -k "test_functional[len_checks]" .. _writing_config_functional_tests: Functional tests for configurations ----------------------------------- To test the different ways to configure Pylint there is also a small functional test framework for configuration files. These tests can be found in the '/pylint/test/config' directory. To create a new test create a new file with an unused name in the directory of that type of configuration file. Subsequently add a ``filename.result.json`` file with 'filename' being the same name as your configuration file. This file should record what the configuration should be **compared to the standard configuration**. For example, if the configuration should add a warning to the list of disabled messages and you changed the configuration for ``job`` to 10 instead of the default 1 the ``.json`` file should include:: "functional_append": { "disable": [["a-message-to-be-added"],] } "jobs": 10, Similarly if a message should be removed you can add the following to the ``.json`` file:: "functional_remove": { "disable": [["a-message-to-be-removed"],] } If a configuration is incorrect and should lead to a crash or warning being emitted you can specify this by adding a ``.out`` file. This file should have the following name ``name_of_configuration_testfile.error_code.out``. So, if your test is called ``bad_configuration.toml`` and should exit with exit code 2 the ``.out`` file should be named ``bad_configuration.2.out``. The content of the ``.out`` file should have a similar pattern as a normal Pylint output. Note that the module name should be ``{abspath}`` and the file name ``{relpath}``. .. _tox: https://tox.wiki/en/latest/ .. _pytest: https://docs.pytest.org/en/latest/ .. _pytest-cov: https://pypi.org/project/pytest-cov/ .. _astroid: https://github.com/pylint-dev/astroid pylint-4.0.5/doc/development_guide/contributor_guide/tests/launching_test.rst0000664000175000017500000000641615146021447027656 0ustar epsilonepsilonLaunching tests =============== pytest ------ Since we use pytest_ to run the tests, you can also use it on its own. We do recommend using the tox_ command though:: pytest tests/ -k test_functional You can use pytest_ directly. If you want to run tests on a specific portion of the code with pytest_ and your local python version:: python3 -m pytest Everything in tests/message with coverage for the relevant code (require `pytest-cov`_):: python3 -m pytest tests/message/ --cov=pylint.message coverage html Only the functional test "missing_kwoa_py3":: python3 -m pytest "tests/test_functional.py::test_functional[missing_kwoa_py3]" tox --- You can also *optionally* install tox_ and run our tests using the tox_ package, as in:: python -m tox python -m tox -epy313 # for Python 3.13 suite only python -m tox -epylint # for running Pylint over Pylint's codebase python -m tox -eformatting # for running formatting checks over Pylint's codebase It's usually a good idea to run tox_ with ``--recreate``. This flag tells tox_ to re-download all dependencies before running the tests. This can be important when a new version of astroid_ or any of the other dependencies has been published:: python -m tox --recreate # The entire tox environment will be recreated python -m tox --recreate -e py310 # The python 3.10 tox environment will be recreated To run only a specific test suite, use a pattern for the test filename (**without** the ``.py`` extension), as in:: python -m tox -e py310 -- -k test_functional python -m tox -e py310 -- -k \*func\* python -m tox --recreate -e py310 -- -k test_functional # With recreation of the environment .. _primer_tests: Primer tests ------------ Pylint also uses what we refer to as ``primer`` tests. These are tests that are run automatically in our Continuous Integration and check whether any changes in Pylint lead to crashes or fatal errors on the ``stdlib``, and also assess a pull request's impact on the linting of a selection of external repositories by posting the diff against ``pylint``'s current output as a comment. To run the primer test for the ``stdlib``, which only checks for crashes and fatal errors, you can add ``--primer-stdlib`` to the pytest_ command. For example:: pytest -m primer_stdlib --primer-stdlib To produce the output generated on Continuous Integration for the linting of external repositories, run these commands:: python tests/primer/__main__.py prepare --clone python tests/primer/__main__.py run --type=pr To fully simulate the process on Continuous Integration, you should then checkout ``main``, and then run these commands:: python tests/primer/__main__.py run --type=main python tests/primer/__main__.py compare The list of repositories is created on the basis of three criteria: 1) projects need to use a diverse range of language features, 2) projects need to be well maintained and 3) projects should not have a codebase that is too repetitive. This guarantees a good balance between speed of our CI and finding potential bugs. You can find the latest list of repositories and any relevant code for these tests in the ``tests/primer`` directory. .. _pytest-cov: https://pypi.org/project/pytest-cov/ .. _astroid: https://github.com/pylint-dev/astroid pylint-4.0.5/doc/development_guide/contributor_guide/tests/index.rst0000664000175000017500000000045715146021447025755 0ustar epsilonepsilon.. _contributor_testing: .. _test_your_code: ============== Testing pylint ============== Pylint is very well tested and has a high code coverage. New contributions are not accepted unless they include tests. .. toctree:: :maxdepth: 3 :titlesonly: install launching_test writing_test pylint-4.0.5/doc/development_guide/contributor_guide/patch_release.rst0000664000175000017500000000011515146021447026272 0ustar epsilonepsilon- In **patch release** (``1.2.3``), we only fix false positives and crashes. pylint-4.0.5/doc/development_guide/contributor_guide/index.rst0000664000175000017500000000042415146021447024605 0ustar epsilonepsilon.. _contribute_guide: Contributing to pylint ====================== The contributor guide will help you if you want to contribute to pylint itself. .. toctree:: :maxdepth: 2 :titlesonly: contribute tests/index profiling oss_fuzz release governance pylint-4.0.5/doc/development_guide/contributor_guide/minor_release.rst0000664000175000017500000000025615146021447026325 0ustar epsilonepsilon- In **minor releases** (``1.2.0``), we add checks, remove checks, drop python interpreters past end of life, upgrade astroid minor/major versions and fix false negatives. pylint-4.0.5/doc/development_guide/contributor_guide/profiling.rst0000664000175000017500000001117115146021447025470 0ustar epsilonepsilon.. -*- coding: utf-8 -*- .. _profiling: =================================== Profiling and performance analysis =================================== Performance analysis for Pylint ------------------------------- To analyse the performance of Pylint we recommend to use the ``cProfile`` module from ``stdlib``. Together with the ``pstats`` module this should give you all the tools you need to profile a Pylint run and see which functions take how long to run. The documentation for both modules can be found at cProfile_. To profile a run of Pylint over itself you can use the following code and run it from the base directory. Note that ``cProfile`` will create a document called ``stats`` that is then read by ``pstats``. The human-readable output will be stored by ``pstats`` in ``./profiler_stats``. It will be sorted by ``cumulative time``: .. sourcecode:: python import cProfile import pstats import sys sys.argv = ["pylint", "pylint"] cProfile.run("from pylint import __main__", "stats") with open("profiler_stats", "w", encoding="utf-8") as file: stats = pstats.Stats("stats", stream=file) stats.sort_stats("cumtime") stats.print_stats() You can also interact with the stats object by sorting or restricting the output. For example, to only print functions from the ``pylint`` module and sort by cumulative time you could use: .. sourcecode:: python import cProfile import pstats import sys sys.argv = ["pylint", "pylint"] cProfile.run("from pylint import __main__", "stats") with open("profiler_stats", "w", encoding="utf-8") as file: stats = pstats.Stats("stats", stream=file) stats.sort_stats("cumtime") stats.print_stats("pylint/pylint") Lastly, to profile a run over your own module or code you can use: .. sourcecode:: python import cProfile import pstats import sys sys.argv = ["pylint", "your_dir/your_file"] cProfile.run("from pylint import __main__", "stats") with open("profiler_stats", "w", encoding="utf-8") as file: stats = pstats.Stats("stats", stream=file) stats.sort_stats("cumtime") stats.print_stats() The documentation of the ``pstats`` module discusses other possibilities to interact with the profiling output. Performance analysis of a specific checker ------------------------------------------ To analyse the performance of specific checker within Pylint we can use the human-readable output created by ``pstats``. If you search in the ``profiler_stats`` file for the file name of the checker you will find all functional calls from functions within the checker. Let's say we want to check the ``visit_importfrom`` method of the ``variables`` checker:: ncalls tottime percall cumtime percall filename:lineno(function) 622 0.006 0.000 8.039 0.013 /MY_PROGRAMMING_DIR/pylint/pylint/checkers/variables.py:1445(visit_importfrom) The previous line tells us that this method was called 622 times during the profile and we were inside the function itself for 6 ms in total. The time per call is less than a millisecond (0.006 / 622) and thus is displayed as being 0. Often you are more interested in the cumulative time (per call). This refers to the time spent within the function and any of the functions it called or the functions they called (etc.). In our example, the ``visit_importfrom`` method and all of its child-functions took a little over 8 seconds to execute, with an execution time of 0.013 ms per call. You can also search the ``profiler_stats`` for an individual function you want to check. For example ``_analyse_fallback_blocks``, a function called by ``visit_importfrom`` in the ``variables`` checker. This allows more detailed analysis of specific functions:: ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.000 0.000 /MY_PROGRAMMING_DIR/pylint/pylint/checkers/variables.py:1511(_analyse_fallback_blocks) Parsing the profiler stats with other tools ------------------------------------------- Often you might want to create a visual representation of your profiling stats. A good tool to do this is gprof2dot_. This tool can create a ``.dot`` file from the profiling stats created by ``cProfile`` and ``pstats``. You can then convert the ``.dot`` file to a ``.png`` file with one of the many converters found online. You can read the gprof2dot_ documentation for installation instructions for your specific environment. Another option would be snakeviz_. .. _cProfile: https://docs.python.org/3/library/profile.html .. _gprof2dot: https://github.com/jrfonseca/gprof2dot .. _snakeviz: https://jiffyclub.github.io/snakeviz/ pylint-4.0.5/doc/development_guide/api/0000775000175000017500000000000015146021447017766 5ustar epsilonepsilonpylint-4.0.5/doc/development_guide/api/pylint.rst0000664000175000017500000000352615146021447022045 0ustar epsilonepsilon======= Pylint ======= As you would launch the command line ------------------------------------ You can use the ``run_pylint`` function, which is the same function called by the command line (using ``sys.argv``). You can supply arguments yourself: .. sourcecode:: python from pylint import run_pylint run_pylint(argv=["--disable=line-too-long", "myfile.py"]) Recover the result in a stream ------------------------------ You can also use ``pylint.lint.Run`` directly if you want to do something that can't be done using only pylint's command line options. Here's the basic example: .. sourcecode:: python from pylint.lint import Run Run(argv=["--disable=line-too-long", "myfile.py"]) With ``Run`` it is possible to invoke pylint programmatically with a reporter initialized with a custom stream: .. sourcecode:: python from io import StringIO from pylint.lint import Run from pylint.reporters.text import TextReporter pylint_output = StringIO() # Custom open stream reporter = TextReporter(pylint_output) Run(["test_file.py"], reporter=reporter, exit=False) print(pylint_output.getvalue()) # Retrieve and print the text report The reporter can accept any stream object as as parameter. In this example, the stream outputs to a file: .. sourcecode:: python from pylint.lint import Run from pylint.reporters.text import TextReporter with open("report.out", "w") as f: reporter = TextReporter(f) Run(["test_file.py"], reporter=reporter, exit=False) This would be useful to capture pylint output in an open stream which can be passed onto another program. If your program expects that the files being linted might be edited between runs, you will need to clear pylint's inference cache: .. sourcecode:: python from pylint.lint import pylinter pylinter.MANAGER.clear_cache() pylint-4.0.5/doc/development_guide/api/index.rst0000664000175000017500000000053015146021447021625 0ustar epsilonepsilon### API ### You can call ``Pylint``, ``symilar`` and ``pyreverse`` from another Python program thanks to their APIs: .. sourcecode:: python from pylint import run_pylint, run_pyreverse, run_symilar run_pylint("--disable=C", "myfile.py") run_pyreverse(...) run_symilar(...) .. toctree:: :maxdepth: 1 :hidden: pylint pylint-4.0.5/doc/development_guide/how_tos/0000775000175000017500000000000015146021447020677 5ustar epsilonepsilonpylint-4.0.5/doc/development_guide/how_tos/custom_checkers.rst0000664000175000017500000003156215146021447024621 0ustar epsilonepsilon.. _write_a_checker: How to Write a Checker ====================== You can find some simple examples in the distribution (`custom.py `_ , `custom_raw.py `_ and `deprecation_checker.py `_). .. TODO Create custom_token.py There are three kinds of checkers: * Raw checkers, which analyse each module as a raw file stream. * Token checkers, which analyse a file using the list of tokens that represent the source code in the file. * AST checkers, which work on an AST representation of the module. The AST representation is provided by the ``astroid`` library. ``astroid`` adds additional information and methods over ``ast`` in the standard library, to make tree navigation and code introspection easier. .. TODO Writing a Raw Checker .. TODO Writing a Token Checker Writing an AST Checker ---------------------- Let's implement a checker to make sure that all ``return`` nodes in a function return a unique constant. Firstly we will need to fill in some required boilerplate: .. code-block:: python import astroid from astroid import nodes from typing import TYPE_CHECKING, Optional from pylint.checkers import BaseChecker if TYPE_CHECKING: from pylint.lint import PyLinter class UniqueReturnChecker(BaseChecker): name = "unique-returns" msgs = { "W0001": ( "Returns a non-unique constant.", "non-unique-returns", "All constants returned in a function should be unique.", ), } options = ( ( "ignore-ints", { "default": False, "type": "yn", "metavar": "", "help": "Allow returning non-unique integers", }, ), ) So far we have defined the following required components of our checker: * A name. The name is used to generate a special configuration section for the checker, when options have been provided. * A message dictionary. Each checker is being used for finding problems in your code, the problems being displayed to the user through **messages**. The message dictionary should specify what messages the checker is going to emit. See `Defining a Message`_ for the details about defining a new message. We have also defined an optional component of the checker. The options list defines any user configurable options. It has the following format:: options = ( ("option-symbol", {"argparse-like-kwarg": "value"}), ) * The ``option-symbol`` is a unique name for the option. This is used on the command line and in config files. The hyphen is replaced by an underscore when used in the checker, similarly to how you would use ``argparse.Namespace``: .. code-block:: python if not self.linter.config.ignore_ints: ... Next we'll track when we enter and leave a function. .. code-block:: python def __init__(self, linter: Optional["PyLinter"] = None) -> None: super().__init__(linter) self._function_stack = [] def visit_functiondef(self, node: nodes.FunctionDef) -> None: self._function_stack.append([]) def leave_functiondef(self, node: nodes.FunctionDef) -> None: self._function_stack.pop() In the constructor we initialise a stack to keep a list of return nodes for each function. An AST checker is a visitor, and should implement ``visit_`` or ``leave_`` methods for the nodes it's interested in. In this case we have implemented ``visit_functiondef`` and ``leave_functiondef`` to add a new list of return nodes for this function, and to remove the list of return nodes when we leave the function. Finally we'll implement the check. We will define a ``visit_return`` function, which is called with an ``.astroid.nodes.Return`` node. .. _astroid_extract_node: .. TODO We can shorten/remove this bit once astroid has API docs. We'll need to be able to figure out what attributes an ``.astroid.nodes.Return`` node has available. We can use ``astroid.extract_node`` for this:: >>> node = astroid.extract_node("return 5") >>> node >>> help(node) >>> node.value We could also construct a more complete example:: >>> node_a, node_b = astroid.extract_node(""" ... def test(): ... if True: ... return 5 #@ ... return 5 #@ ... """) >>> node_a.value >>> node_a.value.value 5 >>> node_a.value.value == node_b.value.value True For ``astroid.extract_node``, you can use ``#@`` at the end of a line to choose which statements will be extracted into nodes. For more information on ``astroid.extract_node``, see the `astroid documentation `_. Now we know how to use the astroid node, we can implement our check. .. code-block:: python def visit_return(self, node: nodes.Return) -> None: if not isinstance(node.value, nodes.Const): return for other_return in self._function_stack[-1]: if node.value.value == other_return.value.value and not ( self.linter.config.ignore_ints and node.value.pytype() == int ): self.add_message("non-unique-returns", node=node) self._function_stack[-1].append(node) Once we have established that the source code has failed our check, we use ``~.BaseChecker.add_message`` to emit our failure message. Finally, we need to register the checker with pylint. Add the ``register`` function to the top level of the file. .. code-block:: python def register(linter: "PyLinter") -> None: """This required method auto registers the checker during initialization. :param linter: The linter to register the checker to. """ linter.register_checker(UniqueReturnChecker(linter)) We are now ready to debug and test our checker! Debugging a Checker ------------------- It is very simple to get to a point where we can use ``pdb``. We'll need a small test case. Put the following into a Python file: .. code-block:: python def test(): if True: return 5 return 5 def test2(): if True: return 1 return 5 After inserting pdb into our checker and installing it, we can run pylint with only our checker:: $ pylint --load-plugins=my_plugin --disable=all --enable=non-unique-returns test.py (Pdb) Now we can debug our checker! .. Note:: ``my_plugin`` refers to a module called ``my_plugin.py``. The preferred way of making this plugin available to pylint is by installing it as a package. This can be done either from a packaging index like ``PyPI`` or by installing it from a local source such as with ``pip install``. Alternatively, the plugin module can be made available to pylint by putting this module's parent directory in your ``PYTHONPATH`` environment variable. If your pylint config has an ``init-hook`` that modifies ``sys.path`` to include the module's parent directory, this will also work, but only if either: * the ``init-hook`` and the ``load-plugins`` list are both defined in a configuration file, or... * the ``init-hook`` is passed as a command-line argument and the ``load-plugins`` list is in the configuration file So, you cannot load a custom plugin by modifying ``sys.path`` if you supply the ``init-hook`` in a configuration file, but pass the module name in via ``--load-plugins`` on the command line. This is because pylint loads plugins specified on command line before loading any configuration from other sources. Defining a Message ------------------ Pylint message is defined using the following format:: msgs = { "E0401": ( # message id "Unable to import %s", # template of displayed message "import-error", # message symbol "Used when pylint has been unable to import a module.", # Message description { # Additional parameters: # message control support for the old names of the messages: "old_names": [("F0401", "old-import-error")] "minversion": (3, 5), # No check under this version "maxversion": (3, 7), # No check above this version }, ), The message is then formatted using the ``args`` parameter from ``add_message`` i.e. in ``self.add_message("import-error", args=module_we_cant_import, node=importnode)``, the value in ``module_we_cant_import`` say ``patglib`` will be interpolled and the final result will be: ``Unable to import patglib`` * The ``message-id`` should be a 4-digit number, prefixed with a **message category**. There are multiple message categories, these being ``C``, ``W``, ``E``, ``F``, ``R``, standing for ``Convention``, ``Warning``, ``Error``, ``Fatal`` and ``Refactoring``. The 4 digits should not conflict with existing checkers and the first 2 digits should consistent across the checker (except shared messages). It is safe to use 51-99 as the first 2 digits for custom checkers because this range is reserved for them. * The ``displayed-message`` is used for displaying the message to the user, once it is emitted. * The ``message-symbol`` is an alias of the message id and it can be used wherever the message id can be used. * The ``message-help`` is used when calling ``pylint --help-msg``. Optionally message can contain optional extra options: * The ``old_names`` option permits to change the message id or symbol of a message without breaking the message control used on the old messages by users. The option is specified as a list of tuples (``message-id``, ``old-message-symbol``) e.g. ``{"old_names": [("F0401", "old-import-error")]}``. The symbol / msgid association must be unique so if you're changing the message id the symbol also need to change and you can generally use the ``old-`` prefix for that. * The ``minversion`` or ``maxversion`` options specify minimum or maximum version of python relevant for this message. The option value is specified as tuple with major version number as first number and minor version number as second number e.g. ``{"minversion": (3, 5)}`` * The ``shared`` option enables sharing message between multiple checkers. As mentioned previously, normally the message cannot be shared between multiple checkers. To allow having message shared between multiple checkers, the ``shared`` option must be set to ``True``. Parallelize a Checker --------------------- ``BaseChecker`` has two methods ``get_map_data`` and ``reduce_map_data`` that permit to parallelize the checks when used with the ``-j`` option. If a checker actually needs to reduce data it should define ``get_map_data`` as returning something different than ``None`` and let its ``reduce_map_data`` handle a list of the types returned by ``get_map_data``. An example can be seen by looking at ``pylint/checkers/similar.py``. Testing a Checker ----------------- Pylint is very well suited to test driven development. You can implement the template of the checker, produce all of your test cases and check that they fail, implement the checker, then check that all of your test cases work. Pylint provides a ``pylint.testutils.CheckerTestCase`` to make test cases very simple. We can use the example code that we used for debugging as our test cases. .. code-block:: python import astroid import my_plugin import pylint.testutils class TestUniqueReturnChecker(pylint.testutils.CheckerTestCase): CHECKER_CLASS = my_plugin.UniqueReturnChecker def test_finds_non_unique_ints(self): func_node, return_node_a, return_node_b = astroid.extract_node(""" def test(): #@ if True: return 5 #@ return 5 #@ """) self.checker.visit_functiondef(func_node) self.checker.visit_return(return_node_a) with self.assertAddsMessages( pylint.testutils.MessageTest( msg_id="non-unique-returns", node=return_node_b, ), ): self.checker.visit_return(return_node_b) def test_ignores_unique_ints(self): func_node, return_node_a, return_node_b = astroid.extract_node(""" def test(): #@ if True: return 1 #@ return 5 #@ """) with self.assertNoMessages(): self.checker.visit_functiondef(func_node) self.checker.visit_return(return_node_a) self.checker.visit_return(return_node_b) Once again we are using ``astroid.extract_node`` to construct our test cases. ``pylint.testutils.CheckerTestCase`` has created the linter and checker for us, we simply simulate a traversal of the AST tree using the nodes that we are interested in. pylint-4.0.5/doc/development_guide/how_tos/index.rst0000664000175000017500000000017615146021447022544 0ustar epsilonepsilonHow To Guides ============= .. toctree:: :maxdepth: 2 :titlesonly: custom_checkers plugins transform_plugins pylint-4.0.5/doc/development_guide/how_tos/plugins.rst0000664000175000017500000000525315146021447023117 0ustar epsilonepsilon.. -*- coding: utf-8 -*- .. _plugins: How To Write a Pylint Plugin ============================ Pylint provides support for writing two types of extensions. First, there is the concept of **checkers**, which can be used for finding problems in your code. Secondly, there is also the concept of **transform plugin**, which represents a way through which the inference and the capabilities of Pylint can be enhanced and tailored to a particular module, library of framework. In general, a plugin is a module which should have a function ``register``, which takes an instance of ``pylint.lint.PyLinter`` as input. A plugin can optionally define a function, ``load_configuration``, which takes an instance of ``pylint.lint.PyLinter`` as input. This function is called after Pylint loads configuration from configuration file and command line interface. This function should load additional plugin specific configuration to Pylint. So a basic hello-world plugin can be implemented as: .. sourcecode:: python # Inside hello_plugin.py from typing import TYPE_CHECKING import astroid if TYPE_CHECKING: from pylint.lint import PyLinter def register(linter: "PyLinter") -> None: """This required method auto registers the checker during initialization. :param linter: The linter to register the checker to. """ print('Hello world') We can run this plugin by placing this module in the PYTHONPATH and invoking **pylint** as: .. sourcecode:: bash $ pylint -E --load-plugins hello_plugin foo.py Hello world We can extend hello-world plugin to ignore some specific names using ``load_configuration`` function: .. sourcecode:: python # Inside hello_plugin.py from typing import TYPE_CHECKING import astroid if TYPE_CHECKING: from pylint.lint import PyLinter def register(linter: "PyLinter") -> None: """This required method auto registers the checker during initialization. :param linter: The linter to register the checker to. """ print('Hello world') def load_configuration(linter): name_checker = get_checker(linter, NameChecker) # We consider as good names of variables Hello and World name_checker.config.good_names += ('Hello', 'World') # We ignore bin directory linter.config.black_list += ('bin',) Depending if we need a **transform plugin** or a **checker**, this might not be enough. For the former, this is enough to declare the module as a plugin, but in the case of the latter, we need to register our checker with the linter object, by calling the following inside the ``register`` function:: linter.register_checker(OurChecker(linter)) For more information on writing a checker see :ref:`write_a_checker`. pylint-4.0.5/doc/development_guide/how_tos/transform_plugins.rst0000664000175000017500000001007115146021447025204 0ustar epsilonepsilon Transform plugins ^^^^^^^^^^^^^^^^^ Why write a plugin? ------------------- Pylint is a static analysis tool and Python is a dynamically typed language. So there will be cases where Pylint cannot analyze files properly (this problem can happen in statically typed languages also if reflection or dynamic evaluation is used). The plugins are a way to tell Pylint how to handle such cases, since only the user would know what needs to be done. They are usually operating on the AST level, by modifying or changing it in a way which can ease its understanding by Pylint. Example ------- Let us run Pylint on a module from the Python source: `warnings.py`_ and see what happens: .. sourcecode:: shell amitdev$ pylint -E Lib/warnings.py E:297,36: Instance of 'WarningMessage' has no 'message' member (no-member) E:298,36: Instance of 'WarningMessage' has no 'filename' member (no-member) E:298,51: Instance of 'WarningMessage' has no 'lineno' member (no-member) E:298,64: Instance of 'WarningMessage' has no 'line' member (no-member) Did we catch a genuine error? Let's open the code and look at ``WarningMessage`` class: .. sourcecode:: python class WarningMessage(object): """Holds the result of a single showwarning() call.""" _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file", "line") def __init__(self, message, category, filename, lineno, file=None, line=None): local_values = locals() for attr in self._WARNING_DETAILS: setattr(self, attr, local_values[attr]) self._category_name = category.__name__ if category else None def __str__(self): ... Ah, the fields (``message``, ``category`` etc) are not defined statically on the class. Instead they are added using ``setattr``. Pylint would have a tough time figuring this out. Enter Plugin ------------ We can write a transform plugin to tell Pylint how to analyze this properly. One way to fix our example with a plugin would be to transform the ``WarningMessage`` class, by setting the attributes so that Pylint can see them. This can be done by registering a transform function. We can transform any node in the parsed AST like Module, Class, Function etc. In our case we need to transform a class. It can be done so: .. sourcecode:: python from typing import TYPE_CHECKING import astroid if TYPE_CHECKING: from pylint.lint import PyLinter def register(linter: "PyLinter") -> None: """This required method auto registers the checker during initialization. :param linter: The linter to register the checker to. """ pass def transform(cls): if cls.name == 'WarningMessage': import warnings for f in warnings.WarningMessage._WARNING_DETAILS: cls.locals[f] = [astroid.ClassDef(f, None)] astroid.MANAGER.register_transform(astroid.ClassDef, transform) Let's go through the plugin. First, we need to register a class transform, which is done via the ``register_transform`` function in ``MANAGER``. It takes the node type and function as parameters. We need to change a class, so we use ``astroid.ClassDef``. We also pass a ``transform`` function which does the actual transformation. ``transform`` function is simple as well. If the class is ``WarningMessage`` then we add the attributes to its locals (we are not bothered about type of attributes, so setting them as class will do. But we could set them to any type we want). That's it. Note: We don't need to do anything in the ``register`` function of the plugin since we are not modifying anything in the linter itself. Lets run Pylint with this plugin and see: .. sourcecode:: bash amitdev$ pylint -E --load-plugins warning_plugin Lib/warnings.py amitdev$ All the false positives associated with ``WarningMessage`` are now gone. This is just an example, any code transformation can be done by plugins. See `astroid/brain`_ for real life examples of transform plugins. .. _`warnings.py`: https://hg.python.org/cpython/file/2.7/Lib/warnings.py .. _`astroid/brain`: https://github.com/pylint-dev/astroid/tree/main/astroid/brain pylint-4.0.5/doc/development_guide/technical_reference/0000775000175000017500000000000015146021447023165 5ustar epsilonepsilonpylint-4.0.5/doc/development_guide/technical_reference/checkers.rst0000664000175000017500000000042715146021447025511 0ustar epsilonepsilonCheckers -------- All of the default pylint checkers exist in ``pylint.checkers``. This is where most of pylint's brains exist. Most checkers are AST based and so use ``astroid``. ``pylint.checkers.utils`` provides a large number of utility methods for dealing with ``astroid``. pylint-4.0.5/doc/development_guide/technical_reference/index.rst0000664000175000017500000000035615146021447025032 0ustar epsilonepsilon.. _technical-reference: Technical Reference =================== .. TODO Configuration .. TODO Messages .. TODO Reports .. extensions.rst and features.rst are generated. .. toctree:: :maxdepth: 2 :titlesonly: startup checkers pylint-4.0.5/doc/development_guide/technical_reference/startup.rst0000664000175000017500000000171115146021447025421 0ustar epsilonepsilonStartup and the Linter Class ---------------------------- The two main classes in ``pylint.lint`` are ``.pylint.lint.Run`` and ``.pylint.lint.PyLinter``. The ``.pylint.lint.Run`` object is responsible for starting up pylint. It does some basic checking of the given command line options to find the initial hook to run, find the config file to use, and find which plugins have been specified. It can then create the main ``.pylint.lint.PyLinter`` instance and initialise it with the config file and plugins that were discovered when preprocessing the command line options. Finally the ``.pylint.lint.Run`` object launches any child linters for parallel jobs, and starts the linting process. The ``.pylint.lint.PyLinter`` is responsible for coordinating the linting process. It parses the configuration and provides it for the checkers and other plugins, it handles the messages emitted by the checkers, it handles the output reporting, and it launches the checkers. pylint-4.0.5/doc/requirements.txt0000664000175000017500000000011115146021447016773 0ustar epsilonepsilonSphinx==8.2.3 sphinx-reredirects<1 towncrier>=24.8,<26.0 furo==2025.9.25 pylint-4.0.5/doc/test_messages_documentation.py0000664000175000017500000002122415146021447021670 0ustar epsilonepsilon# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html # For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE # Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt """Functional tests for the code examples in the messages' documentation.""" from __future__ import annotations from collections import Counter from pathlib import Path from typing import TextIO import pytest from pylint import checkers from pylint.config.config_initialization import _config_initialization from pylint.lint import PyLinter from pylint.message.message import Message from pylint.testutils.constants import _EXPECTED_RE from pylint.testutils.reporter_for_tests import FunctionalTestReporter MessageCounter = Counter[tuple[int, str]] def get_functional_test_files_from_directory(input_dir: Path) -> list[tuple[str, Path]]: """Get all functional tests in the input_dir. This also checks the formatting of related.rst files. """ suite: list[tuple[str, Path]] = [] for subdirectory in input_dir.iterdir(): for message_dir in subdirectory.iterdir(): assert_msg = ( f"{subdirectory}: '{message_dir.name}' is in the wrong " f"directory: it does not start with '{subdirectory.name}'" ) assert message_dir.name.startswith(subdirectory.name), assert_msg _add_code_example_to_suite(message_dir, suite, "good") _add_code_example_to_suite(message_dir, suite, "bad") if (message_dir / "related.rst").exists(): with open(message_dir / "related.rst", encoding="utf-8") as file: text = file.read() assert text.startswith( "-" ), f"{message_dir / 'related.rst'} should be a list using '-'." return suite def _add_code_example_to_suite( message_dir: Path, suite: list[tuple[str, Path]], example_type: str ) -> None: """Code example files can either consist of a single file or a directory.""" file = f"{example_type}.py" directory = f"{example_type}" if (message_dir / file).exists(): suite.append( (message_dir.stem, message_dir / file), ) elif (message_dir / directory).is_dir(): dir_to_add = message_dir / directory len_to_add = len(list(dir_to_add.iterdir())) assert len_to_add > 1, ( f"A directory of {example_type} files needs at least two files, " f"but only found one in {dir_to_add}." ) suite.append( (message_dir.stem, dir_to_add), ) TESTS_DIR = Path(__file__).parent.resolve() / "data" / "messages" TESTS = get_functional_test_files_from_directory(TESTS_DIR) TESTS_NAMES = [f"{t[0]}-{t[1].stem}" for t in TESTS] class LintModuleTest: def __init__( self, test_file: tuple[str, Path], multiple_file_messages: list[str] ) -> None: self._test_file = test_file self._multiple_file_messages = multiple_file_messages _test_reporter = FunctionalTestReporter() self._linter = PyLinter() self._linter.config.persistent = 0 checkers.initialize(self._linter) # Check if this message has a custom configuration file (e.g. for enabling optional checkers). # If not, use the default configuration. config_file: Path | None msgid, full_path = test_file pylintrc = full_path.parent / "pylintrc" config_file = pylintrc if pylintrc.exists() else None print(f"Config file used: {config_file}") args = [ str(full_path), "--disable=all", f"--enable=F,{msgid},astroid-error,syntax-error", ] print(f"Command used:\npylint {' '.join(args)}") _config_initialization( self._linter, args_list=args, reporter=_test_reporter, config_file=config_file, ) def runTest(self) -> None: self._runTest() def is_good_test(self) -> bool: return self._test_file[1].stem == "good" def is_bad_test(self) -> bool: return self._test_file[1].stem == "bad" @staticmethod def get_expected_messages(stream: TextIO) -> MessageCounter: """Parse a file and get expected messages.""" messages: MessageCounter = Counter() for i, line in enumerate(stream): match = _EXPECTED_RE.search(line) if match is None: continue line = match.group("line") if line is None: lineno = i + 1 elif line.startswith(("+", "-")): lineno = i + 1 + int(line) else: lineno = int(line) for msg_id in match.group("msgs").split(","): messages[lineno, msg_id.strip()] += 1 return messages def _get_expected(self) -> MessageCounter: """Get the expected messages for a file or directory.""" expected_msgs: MessageCounter = Counter() if self._test_file[1].is_dir(): for test_file in self._test_file[1].iterdir(): with open(test_file, encoding="utf8") as f: expected_msgs += self.get_expected_messages(f) else: with open(self._test_file[1], encoding="utf8") as f: expected_msgs += self.get_expected_messages(f) return expected_msgs def _get_actual(self, messages: list[Message]) -> MessageCounter: """Get the actual messages after a run.""" messages.sort(key=lambda m: (m.line, m.symbol, m.msg)) received_msgs: MessageCounter = Counter() for msg in messages: received_msgs[msg.line, msg.symbol] += 1 return received_msgs def _runTest(self) -> None: """Run the test and assert message differences.""" self._linter.check([str(self._test_file[1])]) expected_messages = self._get_expected() actual_messages_raw = self._linter.reporter.messages if self.is_good_test(): assert not actual_messages_raw, self.assert_message_good( actual_messages_raw ) if self.is_bad_test(): bad_files = [self._test_file[1]] if self._test_file[1].is_dir() and not self.is_multifile_example(): bad_files = list(self._test_file[1].iterdir()) assert len(actual_messages_raw) >= len(bad_files), self.assert_message_bad( bad_files, actual_messages_raw ) assert expected_messages == self._get_actual(actual_messages_raw) def assert_message_good(self, messages: list[Message]) -> str: good = self._test_file[1] msg = f"There should be no warning raised for '{good}' but these messages were raised:\n" file_representations = {} for message in messages: if message.path not in file_representations: with open(message.path) as f: file_representations[message.path] = [ line[:-1] for line in f.readlines() ] file_representations[message.path][ message.line - 1 ] += f" # <-- /!\\ unexpected '{message.symbol}' /!\\" for path, representation in file_representations.items(): file_representation = "\n".join(representation) msg += f"\n\n\nIn {path}:\n\n{file_representation}\n" return msg def is_multifile_example(self) -> bool: """Multiple file example do not need to have one warning for each bad file.""" return self._test_file[0] in self._multiple_file_messages def assert_message_bad(self, bad_files: list[Path], messages: list[Message]) -> str: each = "each file in " if len(bad_files) > 1 else "" msg = ( f"There should be at least one warning raised for " f"{each}'{self._test_file[1]}' ({len(bad_files)} total)\n" ) raised_files: set[Path] = set() for message in messages: raised_files.add(Path(message.path).absolute()) missing_files = set(bad_files) - raised_files for missing_file in missing_files: msg += f"- Missing warning in {missing_file}\n" if messages: msg += f"'{messages[0].symbol}' might need to be added in 'known_multiple_file_messages'.\n\n" return msg @pytest.mark.parametrize("test_file", TESTS, ids=TESTS_NAMES) @pytest.mark.filterwarnings("ignore::DeprecationWarning") def test_code_examples(test_file: tuple[str, Path]) -> None: known_multiple_file_messages = ["cyclic-import", "duplicate-code"] lint_test = LintModuleTest(test_file, known_multiple_file_messages) lint_test.runTest() pylint-4.0.5/doc/logo.png0000664000175000017500000002222215146021447015164 0ustar epsilonepsilonPNG  IHDR [sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< IDATxyezzzd Ā,B^P $Ű%Er*1/ \AV DTIBPAV!6L׹VU]U]L}2~99sy*QU>K8lD]M$ Ld&@6!!h5JBUAKNn .UR҄͘MjH4wImܲBvd2xˢDEUc/HSeh=@Y:?e2ɶ]3zlYv0Y'{E9涗GH{/`/ѪRJL7; `%Bu+R1yK᝗8bΨv2wKc dBC^dהּx Nnk:DyHϫ7N^vT&q-v 0|ס1#Ly,-yڻeuNY2pL&hlD,vraʢ߾6β8$NmDSu2U~]2  I>o)?p[iLIDCX"XuNꐤi\|еO (?Dp-&zj*eb}` >¦|rN>t'/?ԆvP)2U)lEyGwQem&X/reGa񮎓{ XPea<{푫e/v2ؕ"3ϲ. }*_=(*8_.X|{pܭ/ @udiBQ8'?RHw^µCS7ryD!2d2BN>w G6K+'P2W/Teqe^,"CFk9]UssuBz#7 $#TT[M=Ȑ4hŐ W:sJ-AUiD `6x ) K2=-&E Ȑ#iv1{IfX:E_vU!jU>.!byac"m ie_m"C52uv L}!=|S'uh-$\2B D P`m6u:O3Lj Ӏ(m!]=D _>W}sOCޯ-Eޢ3BD]ϿN"îf Ǩ2#[Ȝ|wT2䈐K成0SGMKa4g[DΠD#>Y@ } wECl5u7D!J98TrYu2DAS G-A9tEg-d^%eC\rE!?Z>ϿD։Nkm n!#6:D N3:֝\"W4)2:ogݳQʤ3` "TdhڂdWH DRLZVt:S:H"NX4o!=F 2dx#-ۇ|wX59i!-Dk-$!`ti[H/rE CzOl\AYs+FԋRFv7t6]Sk ,fz(.pMˊ0G41`}-PUVTaf;Z^Q7MccMk vUфh:US:L4uL dEFF2xο⾸mx-L]Y\n녕ĨՃ=ܞw\)?ƀ 7w-`O?<$4qǼInPUEvx > -BAH:w oAJ&̙Mx[< se 1Gd[!b{2|0) x^ 犲H}8z2nb.oH ȕ[A_M5^KCw,"+68J+ՇofCӳܗ4[ 5 hx!w!ӥ\ `{xת[Ȳ َN"dGXs/m7=/"*4' CQkNx1WʕT>|}{r cy||(EM1S|r.\u8n}Q_hm!Cwړ4ZSD* 18͹b:t}::Y%̙3fZY}VED^Og,:Fŷ]ٕMuT"3vɘΒo}so!2,rLm!RFo%>/Tdd-\286Nfl!Kg]0/̒A:Rb5"yvGQM@yv-;N OvÑ#kMK iB~uuH*OxQgmd0"_#W0;j-4L;˚Z!M=N{EFAǺ8-[g9,m Q;M/[i2 i<*QpJ 2rZ[H1D2eul};tH 5$$(ӻ DPx=0>?ԵHLZi2(BἬgS ,Re&NrSkURtq8hcjuG`:hndPbe ve[[ؔG<~z?͞Y5#8/LES'0cis=fcѓnbe"W^'j!C.+|F:{/ɝ*64}yi=韟 }B QKk'l F|s[HfuW~2(/;*S G6N1US1TEFA:tZeܢͥp,'q;wҵRy֭G,Ù@6(SuUz#۳Ϸ@}_k.[hF-GO֠*nuIԛ,MD1y >RE!#@NHȈ.e6*`[HeJLݢU5f$;:7wXb9vϊsUdms:˖qCpZr25-1mt@SRϖ(l!M=D.].mJ+;^c1j}IE&Y}bdOZ.\Gh/V`+?>mE# 5U5a:7.WC}*h qu#U"0{pZ$Nƌ92T&`_9#:\JcҢI&CU9=H̹07f#uXJ#P*[Gp R(!˱EM5Wif#?[tmco8!ŝV`GZ"ds閪-t-0{m KF=0{Jj_D!B=ѥD86_R׷&;=4{ f > hPi(~27m60!ы[V^yJ[_V;N8ku5#];\Hh-%E?i펎d'[N} 7N B$N.IsXSd; kga#@4W&@zvĊ6:2:_=w|<4%UkWն83=o2mz` ;:aU݁倕(t ћb*>0\-x?4uvrԹfͧ"'|[6#F֖֭AȆ#:87f3YjN-~ tYOij/!b%,,O8X2db.z~n̫ne`}(jEuV"XjMwZU~я!kj ӢuEʖadmik; ]s#@)A{[[;֒Yԍj c@ aV>QT!3vvdؘjH;+-G!cP;Q*Q:Pe3 ֵB_ akY2tgvU7f:4[1XI$M´MP42 e%';GH8d8[SBzt˖t jq^ 3fP-}J!c!s*)#a~Vka){-jvʺU n~/Ֆ&:Oa ,HP"X-{i""`Vj^*T):ʱ.3C#z}t@27Bl߰^OJ?_ҧ O :F\l!- J:u-_˗O~E- 54G R {I[Ō)t"'X*|a[DHNyHPVɲGUCTa<+^6\_2̝1Sg)gBz=N{\pC,%Q NYf4̓qeCTA ͼ)}_rZ o +iO'2>($*Jw \dp)y |I4d 9G"d=bm5m\(F6/G:-iwtقH"dB}{6W7}Q݁ `B 4SHZyA1-۝MylLzʢXΑz3}&ߴ%%CxAQVЭ(0d%mm` xC A~я?P=2T 3\BSN^k#Bd(jJ]d :d)jX95s)哗ރׂ'2`2 %^jz-xpe kc%+7"DR))'H<"C) $B>GDp9 雎CEr8 Fp"d2]g(%b_$zF!`l3aUFvBt`" _(KR^/~14'h45D a#-1mikly=1/+f{- `JpJ"-=[jt;ӁlUG+6D-mneXM5`.<3M_I[>JMae cz^ף`\A-Beg^Et ,[lG-f '3M{{GADCZ2~0~ÈȰ/7!?Ki`Ҥ/Q2$ͅYs@P=m&x ^콞aD _x5`YulXY!ږw)rLD792έQs<ٗX:+\hU5`_lE'CKO"y0w!8{d40QLun6v2wXXADv(ta/ˁر`ŇG!A_o!RF(+1Un.-d`ZSј[4c 5ʾחKqo`' "w0 s4&AGCʸH܈XJ;֤osL3F|pX=]QH/ `6F#hH@ЂКl0V_Zz=>>G`D |NϑEh2QS-qؑx\);"RW.SvDH ݷŌ ;"2a0EdXJi;#*lgp sزP]!3>l0's`As@N^A_ [0DD6pEaS5qTNmq&WjOۙn7*eVv~oD}K8өryѾ:;SΪOhʟiL_H{ZAZ#|eF7oj7yd#s1_aH8?v[|fCU^k3+?B9MǢ%4tr[;U {SpvZ;X-);9o'}T}j:NnW~vH- w8?wcIb-_UpA@xc%'iM X[D0}0c ^Kж5j)ԍߣ4;7c! XOɜMyU`|}ȕy/MgXŶ^>J9T&Mw@DI0s`mmp/Xagƞ#害 b.y%kXLU-x糈 `nĸIDATsH4>Hk(ݞ@vkI3U#fE>5M.Okc'7ikfΣlpaj&|p_% -v8N:Zx- g'e2S3硬n3~FƭOhϥ9WijoECbӁwTul?'vwt!t3it!Yl]67ADm3?g_[[aoj扶N}h;r֐vz3Sg`[8uΕԸRs;L y[Q \6BG;HLUpfܬw.o N&M1R֭ظοva4ai3Sg}³^vοO[x"(Iz{ɧ ﯦ+ ytnW_U$ 0BD& $tOTsnزa1ΉWb,Ʒ*lx/cUa;gSI;i!|{B*sk7Ö $󻺑dJrٙ_I;B fygI}PI0 f*lge&umT_xIENDB`pylint-4.0.5/doc/contact.rst0000664000175000017500000000317315146021447015707 0ustar epsilonepsilonContact ======= Bug reports, feedback --------------------- .. _bug reports, feedback: You think you have found a bug in Pylint? Well, this may be the case since Pylint and Python are under heavy development! Please take the time to check if it is already in the issue tracker at https://github.com/pylint-dev/pylint Note that the issue might also be reported in one of Pylint's major dependencies, astroid: * https://github.com/pylint-dev/astroid Discord server -------------- You can discuss your problem using the discord server: https://discord.com/invite/Egy6P8AMB5 Mailing lists ------------- .. _Mailing lists: The code-quality mailing list is shared with other tools that aim at improving the quality of python code. You can subscribe to this mailing list at https://mail.python.org/mailman3/lists/code-quality.python.org/ Archives are available at https://mail.python.org/pipermail/code-quality/ Archives before April 2013 are not available anymore. At https://mail.python.org/pipermail/ it was under ``python-projects``. Support ------- .. image:: media/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White.png :height: 150 :alt: Tidelift :align: left :class: tideliftlogo Professional support for pylint is available as part of the `Tidelift Subscription`_. Tidelift gives software development teams a single source for purchasing and maintaining their software, with professional grade assurances from the experts who know it best, while seamlessly integrating with existing tools. .. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-pylint?utm_source=pypi-pylint&utm_medium=referral&utm_campaign=readme pylint-4.0.5/doc/logo.svg0000664000175000017500000004402515146021447015204 0ustar epsilonepsilon image/svg+xml pylint-4.0.5/doc/data/0000775000175000017500000000000015146021447014427 5ustar epsilonepsilonpylint-4.0.5/doc/data/ruff.toml0000664000175000017500000000141615146021447016270 0ustar epsilonepsilon# Reading ease is drastically reduced on read the doc after 103 chars # (Because of horizontal scrolling) line-length = 103 extend-exclude = [ "messages/d/duplicate-argument-name/bad.py", "messages/m/multiple-class-sub-patterns/bad.py", "messages/s/syntax-error/bad.py", # syntax error in newer python versions "messages/b/bare-name-capture-pattern/bad.py", "messages/s/star-needs-assignment-target/bad.py", "messages/i/invalid-star-assignment-target/bad.py", ] [lint] ignore = [] select = ["E501", "I"] [lint.per-file-ignores] "messages/m/misplaced-future/bad.py" = ["I"] "messages/m/multiple-imports/bad.py" = ["I"] "messages/r/reimported/bad.py" = ["I"] "messages/u/ungrouped-imports/bad.py" = ["I"] "messages/w/wrong-import-order/bad.py" = ["I"] pylint-4.0.5/doc/data/messages/0000775000175000017500000000000015146021447016236 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/w/0000775000175000017500000000000015146021447016504 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/w/wrong-spelling-in-docstring/0000775000175000017500000000000015146021447024051 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/w/wrong-spelling-in-docstring/good.py0000664000175000017500000000005015146021447025346 0ustar epsilonepsilon"""There's no mistake in this string""" pylint-4.0.5/doc/data/messages/w/wrong-spelling-in-docstring/pylintrc0000664000175000017500000000015015146021447025634 0ustar epsilonepsilon[main] # This might not run in your env if you don't have the en_US dict installed. spelling-dict=en_US pylint-4.0.5/doc/data/messages/w/wrong-spelling-in-docstring/bad.py0000664000175000017500000000011015146021447025141 0ustar epsilonepsilon"""There's a mistkae in this string""" # [wrong-spelling-in-docstring] pylint-4.0.5/doc/data/messages/w/wrong-import-position/0000775000175000017500000000000015146021447023012 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/w/wrong-import-position/good.py0000664000175000017500000000014415146021447024313 0ustar epsilonepsilonimport os import sys home = os.environ["HOME"] print(f"Home directory is {home}", file=sys.stderr) pylint-4.0.5/doc/data/messages/w/wrong-import-position/bad.py0000664000175000017500000000020115146021447024103 0ustar epsilonepsilonimport os home = os.environ["HOME"] import sys # [wrong-import-position] print(f"Home directory is {home}", file=sys.stderr) pylint-4.0.5/doc/data/messages/w/wrong-spelling-in-comment/0000775000175000017500000000000015146021447023517 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/w/wrong-spelling-in-comment/good.py0000664000175000017500000000004415146021447025017 0ustar epsilonepsilon# There's no mistake in this string pylint-4.0.5/doc/data/messages/w/wrong-spelling-in-comment/pylintrc0000664000175000017500000000015015146021447025302 0ustar epsilonepsilon[main] # This might not run in your env if you don't have the en_US dict installed. spelling-dict=en_US pylint-4.0.5/doc/data/messages/w/wrong-spelling-in-comment/bad.py0000664000175000017500000000010215146021447024610 0ustar epsilonepsilon# There's a mistkae in this string # [wrong-spelling-in-comment] pylint-4.0.5/doc/data/messages/w/while-used/0000775000175000017500000000000015146021447020552 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/w/while-used/good.py0000664000175000017500000000035615146021447022060 0ustar epsilonepsilonimport requests def fetch_data(): for i in range(1, 6): print(f"Attempt {i}...") try: return requests.get("https://example.com/data") except requests.exceptions.RequestException: pass pylint-4.0.5/doc/data/messages/w/while-used/pylintrc0000664000175000017500000000006115146021447022336 0ustar epsilonepsilon[main] load-plugins=pylint.extensions.while_used pylint-4.0.5/doc/data/messages/w/while-used/bad.py0000664000175000017500000000041615146021447021653 0ustar epsilonepsilonimport requests def fetch_data(): i = 1 while i < 6: # [while-used] print(f"Attempt {i}...") try: return requests.get("https://example.com/data") except requests.exceptions.RequestException: pass i += 1 pylint-4.0.5/doc/data/messages/w/while-used/related.rst0000664000175000017500000000015615146021447022726 0ustar epsilonepsilon- `Stackoverflow discussion `_ pylint-4.0.5/doc/data/messages/w/wildcard-import/0000775000175000017500000000000015146021447021605 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/w/wildcard-import/good.py0000664000175000017500000000016515146021447023111 0ustar epsilonepsilon# Either import module or # only import required objects from module. import abc from abc import ABC, abstractmethod pylint-4.0.5/doc/data/messages/w/wildcard-import/bad.py0000664000175000017500000000004715146021447022706 0ustar epsilonepsilonfrom abc import * # [wildcard-import] pylint-4.0.5/doc/data/messages/w/wrong-exception-operation/0000775000175000017500000000000015146021447023632 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/w/wrong-exception-operation/good.py0000664000175000017500000000007015146021447025131 0ustar epsilonepsilontry: 1 / 0 except (ValueError, TypeError): pass pylint-4.0.5/doc/data/messages/w/wrong-exception-operation/bad.py0000664000175000017500000000012615146021447024731 0ustar epsilonepsilontry: 1 / 0 except ValueError + TypeError: # [wrong-exception-operation] pass pylint-4.0.5/doc/data/messages/w/wrong-import-order/0000775000175000017500000000000015146021447022261 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/w/wrong-import-order/good.py0000664000175000017500000000007115146021447023561 0ustar epsilonepsilonimport os import sys import pylint from . import utils pylint-4.0.5/doc/data/messages/w/wrong-import-order/bad.py0000664000175000017500000000014715146021447023363 0ustar epsilonepsilonimport os from . import utils import pylint # [wrong-import-order] import sys # [wrong-import-order] pylint-4.0.5/doc/data/messages/k/0000775000175000017500000000000015146021447016470 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/k/keyword-arg-before-vararg/0000775000175000017500000000000015146021447023443 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/k/keyword-arg-before-vararg/good.py0000664000175000017500000000005715146021447024747 0ustar epsilonepsilondef func(*args, x=None): return [*args, x] pylint-4.0.5/doc/data/messages/k/keyword-arg-before-vararg/bad.py0000664000175000017500000000011615146021447024541 0ustar epsilonepsilondef func(x=None, *args): # [keyword-arg-before-vararg] return [x, *args] pylint-4.0.5/doc/data/messages/k/kwarg-superseded-by-positional-arg/0000775000175000017500000000000015146021447025302 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/k/kwarg-superseded-by-positional-arg/good.py0000664000175000017500000000014415146021447026603 0ustar epsilonepsilondef print_name(name="Sarah", /, **kwds): print(name) print_name("Jacob") # Will print "Jacob" pylint-4.0.5/doc/data/messages/k/kwarg-superseded-by-positional-arg/bad.py0000664000175000017500000000022115146021447026375 0ustar epsilonepsilondef print_name(name="Sarah", /, **kwds): print(name) print_name(name="Jacob") # [kwarg-superseded-by-positional-arg] # Will print "Sarah" pylint-4.0.5/doc/data/messages/d/0000775000175000017500000000000015146021447016461 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/disallowed-name/0000775000175000017500000000000015146021447021526 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/disallowed-name/good.py0000664000175000017500000000004715146021447023031 0ustar epsilonepsilondef print_fruit(): print("apples") pylint-4.0.5/doc/data/messages/d/disallowed-name/pylintrc0000664000175000017500000000003515146021447023313 0ustar epsilonepsilon[MAIN] bad-names=foo,bar,baz pylint-4.0.5/doc/data/messages/d/disallowed-name/bad.py0000664000175000017500000000006415146021447022626 0ustar epsilonepsilondef foo(): # [disallowed-name] print("apples") pylint-4.0.5/doc/data/messages/d/dict-iter-missing-items/0000775000175000017500000000000015146021447023133 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/dict-iter-missing-items/good.py0000664000175000017500000000024515146021447024436 0ustar epsilonepsilondata = {"Paris": 2_165_423, "New York City": 8_804_190, "Tokyo": 13_988_129} for city, population in data.items(): print(f"{city} has population {population}.") pylint-4.0.5/doc/data/messages/d/dict-iter-missing-items/bad.py0000664000175000017500000000027215146021447024234 0ustar epsilonepsilondata = {"Paris": 2_165_423, "New York City": 8_804_190, "Tokyo": 13_988_129} for city, population in data: # [dict-iter-missing-items] print(f"{city} has population {population}.") pylint-4.0.5/doc/data/messages/d/deprecated-method/0000775000175000017500000000000015146021447022037 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/deprecated-method/good.py0000664000175000017500000000006715146021447023344 0ustar epsilonepsilonimport logging logging.warning("I'm coming, world !") pylint-4.0.5/doc/data/messages/d/deprecated-method/details.rst0000664000175000017500000000017415146021447024220 0ustar epsilonepsilonThe actual replacement needs to be studied on a case by case basis by reading the deprecation warning or the release notes. pylint-4.0.5/doc/data/messages/d/deprecated-method/bad.py0000664000175000017500000000011315146021447023132 0ustar epsilonepsilonimport logging logging.warn("I'm coming, world !") # [deprecated-method] pylint-4.0.5/doc/data/messages/d/duplicate-code/0000775000175000017500000000000015146021447021343 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/duplicate-code/details.rst0000664000175000017500000000116515146021447023525 0ustar epsilonepsilonIf you need to make a change to the logic or functionality of the duplicated code, you will need to identify all the places that need to be changed, which can be time-consuming and error-prone. If there are multiple copies of the same code, then you will also need to test each copy to ensure that the functionality is correct. Duplicate code can be confusing for someone who is trying to understand the logic and flow of the code if they come across multiple identical or nearly identical blocks of code. The reader can then skim and think something is identical when it actually isn't. This is particularly true during review. pylint-4.0.5/doc/data/messages/d/duplicate-code/bad/0000775000175000017500000000000015146021447022071 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/duplicate-code/bad/apple.py0000664000175000017500000000064115146021447023545 0ustar epsilonepsilonclass Apple: def __init__(self): self.remaining_bites = 3 def take_bite(self): if self.remaining_bites > 0: print("You take a bite of the apple.") self.remaining_bites -= 1 else: print("The apple is already eaten up!") def eaten_by_animal(self, animal): self.remaining_bites = 0 print("The apple has been eaten by an animal.") pylint-4.0.5/doc/data/messages/d/duplicate-code/bad/__init__.py0000664000175000017500000000000015146021447024170 0ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/duplicate-code/bad/orange.py0000664000175000017500000000102015146021447023707 0ustar epsilonepsilonclass Orange: # [duplicate-code] def __init__(self): self.remaining_bites = 3 def take_bite(self): if self.remaining_bites > 0: print("You take a bite of the apple.") self.remaining_bites -= 1 else: print("The orange is already eaten up!") def eaten_by_animal(self, animal): if animal == "cat": raise ValueError("A cat would never do that !") self.remaining_bites = 0 print("The orange has been eaten by an animal.") pylint-4.0.5/doc/data/messages/d/duplicate-code/good/0000775000175000017500000000000015146021447022273 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/duplicate-code/good/apple.py0000664000175000017500000000006215146021447023744 0ustar epsilonepsilonfrom fruit import Fruit class Apple(Fruit): ... pylint-4.0.5/doc/data/messages/d/duplicate-code/good/fruit.py0000664000175000017500000000077015146021447024002 0ustar epsilonepsilonclass Fruit: def __init__(self): self.remaining_bites = 3 def take_bite(self): if self.remaining_bites > 0: print(f"You take a bite of the {self.__class__.__name__.lower()}.") self.remaining_bites -= 1 else: print(f"The {self.__class__.__name__.lower()} is already eaten up!") def eaten_by_animal(self, animal): self.remaining_bites = 0 print(f"The {self.__class__.__name__.lower()} has been eaten by an animal.") pylint-4.0.5/doc/data/messages/d/duplicate-code/good/__init__.py0000664000175000017500000000000015146021447024372 0ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/duplicate-code/good/orange.py0000664000175000017500000000032615146021447024121 0ustar epsilonepsilonfrom fruit import Fruit class Orange(Fruit): def eaten_by_animal(self, animal): if animal == "cat": raise ValueError("A cat would never do that !") super().eaten_by_animal(animal) pylint-4.0.5/doc/data/messages/d/dangerous-default-value/0000775000175000017500000000000015146021447023204 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/dangerous-default-value/good.py0000664000175000017500000000022015146021447024500 0ustar epsilonepsilondef whats_on_the_telly(penguin=None): if penguin is None: penguin = [] penguin.append("property of the zoo") return penguin pylint-4.0.5/doc/data/messages/d/dangerous-default-value/details.rst0000664000175000017500000000051115146021447025360 0ustar epsilonepsilonWith a mutable default value, with each call the default value is modified, i.e.: .. code-block:: python whats_on_the_telly() # ["property of the zoo"] whats_on_the_telly() # ["property of the zoo", "property of the zoo"] whats_on_the_telly() # ["property of the zoo", "property of the zoo", "property of the zoo"] pylint-4.0.5/doc/data/messages/d/dangerous-default-value/bad.py0000664000175000017500000000017615146021447024310 0ustar epsilonepsilondef whats_on_the_telly(penguin=[]): # [dangerous-default-value] penguin.append("property of the zoo") return penguin pylint-4.0.5/doc/data/messages/d/deprecated-typing-alias/0000775000175000017500000000000015146021447023160 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/deprecated-typing-alias/good.py0000664000175000017500000000004715146021447024463 0ustar epsilonepsilonitem_to_number_of_item: dict[str, int] pylint-4.0.5/doc/data/messages/d/deprecated-typing-alias/pylintrc0000664000175000017500000000005715146021447024751 0ustar epsilonepsilon[main] load-plugins = pylint.extensions.typing pylint-4.0.5/doc/data/messages/d/deprecated-typing-alias/bad.py0000664000175000017500000000013215146021447024254 0ustar epsilonepsilonimport typing item_to_number_of_item: typing.Dict[str, int] # [deprecated-typing-alias] pylint-4.0.5/doc/data/messages/d/deprecated-class/0000775000175000017500000000000015146021447021664 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/deprecated-class/good.py0000664000175000017500000000004515146021447023165 0ustar epsilonepsilonfrom collections.abc import Iterable pylint-4.0.5/doc/data/messages/d/deprecated-class/details.rst0000664000175000017500000000017415146021447024045 0ustar epsilonepsilonThe actual replacement needs to be studied on a case by case basis by reading the deprecation warning or the release notes. pylint-4.0.5/doc/data/messages/d/deprecated-class/bad.py0000664000175000017500000000006715146021447022767 0ustar epsilonepsilonfrom collections import Iterable # [deprecated-class] pylint-4.0.5/doc/data/messages/d/differing-type-doc/0000775000175000017500000000000015146021447022140 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/differing-type-doc/good.py0000664000175000017500000000017015146021447023440 0ustar epsilonepsilondef add(x, y): """Add two numbers. :param int x: x value. :param int y: y value. """ return x + y pylint-4.0.5/doc/data/messages/d/differing-type-doc/pylintrc0000664000175000017500000000006215146021447023725 0ustar epsilonepsilon[MAIN] load-plugins = pylint.extensions.docparams pylint-4.0.5/doc/data/messages/d/differing-type-doc/bad.py0000664000175000017500000000023315146021447023236 0ustar epsilonepsilondef add(x: int, y: int): # [differing-type-doc] """Add two numbers. :param int xy: x value. :param str y: y value. """ return x + y pylint-4.0.5/doc/data/messages/d/duplicate-value/0000775000175000017500000000000015146021447021545 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/duplicate-value/good.py0000664000175000017500000000004015146021447023041 0ustar epsilonepsiloncorrect_set = {"value1", 23, 5} pylint-4.0.5/doc/data/messages/d/duplicate-value/bad.py0000664000175000017500000000010115146021447022635 0ustar epsilonepsilonincorrect_set = {"value1", 23, 5, "value1"} # [duplicate-value] pylint-4.0.5/doc/data/messages/d/deprecated-decorator/0000775000175000017500000000000015146021447022541 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/deprecated-decorator/good.py0000664000175000017500000000015215146021447024041 0ustar epsilonepsilonimport abc class Animal: @abc.classmethod @abc.abstractmethod def breath(cls): pass pylint-4.0.5/doc/data/messages/d/deprecated-decorator/pylintrc0000664000175000017500000000003015146021447024321 0ustar epsilonepsilon[main] py-version = 3.3 pylint-4.0.5/doc/data/messages/d/deprecated-decorator/details.rst0000664000175000017500000000017415146021447024722 0ustar epsilonepsilonThe actual replacement needs to be studied on a case by case basis by reading the deprecation warning or the release notes. pylint-4.0.5/doc/data/messages/d/deprecated-decorator/bad.py0000664000175000017500000000016415146021447023642 0ustar epsilonepsilonimport abc class Animal: @abc.abstractclassmethod # [deprecated-decorator] def breath(cls): pass pylint-4.0.5/doc/data/messages/d/deprecated-argument/0000775000175000017500000000000015146021447022401 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/deprecated-argument/good.py0000664000175000017500000000000715146021447023700 0ustar epsilonepsilonint(1) pylint-4.0.5/doc/data/messages/d/deprecated-argument/pylintrc0000664000175000017500000000000015146021447024156 0ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/deprecated-argument/details.rst0000664000175000017500000000017415146021447024562 0ustar epsilonepsilonThe actual replacement needs to be studied on a case by case basis by reading the deprecation warning or the release notes. pylint-4.0.5/doc/data/messages/d/deprecated-argument/bad.py0000664000175000017500000000004215146021447023475 0ustar epsilonepsilonint(x=1) # [deprecated-argument] pylint-4.0.5/doc/data/messages/d/deprecated-attribute/0000775000175000017500000000000015146021447022562 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/deprecated-attribute/good.py0000664000175000017500000000013215146021447024060 0ustar epsilonepsilonfrom configparser import ParsingError err = ParsingError("filename") source = err.source pylint-4.0.5/doc/data/messages/d/deprecated-attribute/details.rst0000664000175000017500000000017415146021447024743 0ustar epsilonepsilonThe actual replacement needs to be studied on a case by case basis by reading the deprecation warning or the release notes. pylint-4.0.5/doc/data/messages/d/deprecated-attribute/bad.py0000664000175000017500000000016615146021447023665 0ustar epsilonepsilonfrom configparser import ParsingError err = ParsingError("filename") source = err.filename # [deprecated-attribute] pylint-4.0.5/doc/data/messages/d/duplicate-argument-name/0000775000175000017500000000000015146021447023171 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/duplicate-argument-name/good.py0000664000175000017500000000006015146021447024467 0ustar epsilonepsilondef get_fruits(apple, banana, orange): pass pylint-4.0.5/doc/data/messages/d/duplicate-argument-name/bad.py0000664000175000017500000000011415146021447024265 0ustar epsilonepsilondef get_fruits(apple, banana, apple): # [duplicate-argument-name] pass pylint-4.0.5/doc/data/messages/d/duplicate-except/0000775000175000017500000000000015146021447021721 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/duplicate-except/good.py0000664000175000017500000000006215146021447023221 0ustar epsilonepsilontry: 1 / 0 except ZeroDivisionError: pass pylint-4.0.5/doc/data/messages/d/duplicate-except/bad.py0000664000175000017500000000015315146021447023020 0ustar epsilonepsilontry: 1 / 0 except ZeroDivisionError: pass except ZeroDivisionError: # [duplicate-except] pass pylint-4.0.5/doc/data/messages/d/duplicate-bases/0000775000175000017500000000000015146021447021526 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/duplicate-bases/good.py0000664000175000017500000000012415146021447023025 0ustar epsilonepsilonclass Animal: pass class Bird(Animal): pass class Cat(Animal): pass pylint-4.0.5/doc/data/messages/d/duplicate-bases/bad.py0000664000175000017500000000012215146021447022621 0ustar epsilonepsilonclass Animal: pass class Cat(Animal, Animal): # [duplicate-bases] pass pylint-4.0.5/doc/data/messages/d/deprecated-module/0000775000175000017500000000000015146021447022044 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/deprecated-module/good.py0000664000175000017500000000006715146021447023351 0ustar epsilonepsilonimport setuptools import whatever_replacement_you_want pylint-4.0.5/doc/data/messages/d/deprecated-module/pylintrc0000664000175000017500000000007315146021447023633 0ustar epsilonepsilon[main] py-version=3.7 deprecated-modules=whatever_you_want pylint-4.0.5/doc/data/messages/d/deprecated-module/details.rst0000664000175000017500000000017415146021447024225 0ustar epsilonepsilonThe actual replacement needs to be studied on a case by case basis by reading the deprecation warning or the release notes. pylint-4.0.5/doc/data/messages/d/deprecated-module/bad.py0000664000175000017500000000013115146021447023137 0ustar epsilonepsilonimport distutils # [deprecated-module] import whatever_you_want # [deprecated-module] pylint-4.0.5/doc/data/messages/d/deprecated-pragma/0000775000175000017500000000000015146021447022026 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/deprecated-pragma/good.py0000664000175000017500000000003615146021447023327 0ustar epsilonepsilon# pylint: disable = eval-used pylint-4.0.5/doc/data/messages/d/deprecated-pragma/bad.py0000664000175000017500000000006615146021447023130 0ustar epsilonepsilon# pylint: disable-msg=eval-used # [deprecated-pragma] pylint-4.0.5/doc/data/messages/d/duplicate-string-formatting-argument/0000775000175000017500000000000015146021447025727 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/duplicate-string-formatting-argument/good.py0000664000175000017500000000047715146021447027241 0ustar epsilonepsilon# pylint: disable=missing-docstring, consider-using-f-string SEE = "see 👀" SEA = "sea 🌊" CONST = """ A sailor went to {sea}, {sea}, {sea} To {see} what he could {see}, {see}, {see} But all that he could {see}, {see}, {see} Was the bottom of the deep blue {sea}, {sea}, {sea}! """.format( sea=SEA, see=SEE ) pylint-4.0.5/doc/data/messages/d/duplicate-string-formatting-argument/bad.py0000664000175000017500000000071215146021447027027 0ustar epsilonepsilon# pylint: disable=missing-docstring, consider-using-f-string SEE = "see 👀" SEA = "sea 🌊" # +1: [duplicate-string-formatting-argument,duplicate-string-formatting-argument] CONST = """ A sailor went to {}, {}, {} To {} what he could {}, {}, {} But all that he could {}, {}, {} Was the bottom of the deep blue {}, {}, {}! """.format( SEA, SEA, SEA, SEE, SEE, SEE, SEE, SEE, SEE, SEE, SEA, SEA, SEA, ) pylint-4.0.5/doc/data/messages/d/dict-init-mutate/0000775000175000017500000000000015146021447021642 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/dict-init-mutate/good.py0000664000175000017500000000005215146021447023141 0ustar epsilonepsilonfruit_prices = {"apple": 1, "banana": 10} pylint-4.0.5/doc/data/messages/d/dict-init-mutate/pylintrc0000664000175000017500000000007015146021447023426 0ustar epsilonepsilon[MAIN] load-plugins=pylint.extensions.dict_init_mutate, pylint-4.0.5/doc/data/messages/d/dict-init-mutate/bad.py0000664000175000017500000000013615146021447022742 0ustar epsilonepsilonfruit_prices = {} # [dict-init-mutate] fruit_prices["apple"] = 1 fruit_prices["banana"] = 10 pylint-4.0.5/doc/data/messages/d/differing-param-doc/0000775000175000017500000000000015146021447022257 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/differing-param-doc/good.py0000664000175000017500000000017015146021447023557 0ustar epsilonepsilondef add(x, y): """Add two numbers. :param int x: x value. :param int y: y value. """ return x + y pylint-4.0.5/doc/data/messages/d/differing-param-doc/pylintrc0000664000175000017500000000006215146021447024044 0ustar epsilonepsilon[MAIN] load-plugins = pylint.extensions.docparams pylint-4.0.5/doc/data/messages/d/differing-param-doc/bad.py0000664000175000017500000000022115146021447023352 0ustar epsilonepsilondef add(x, y): # [differing-param-doc] """Add two numbers. :param int x: x value. :param int z: z value. """ return x + y pylint-4.0.5/doc/data/messages/d/docstring-first-line-empty/0000775000175000017500000000000015146021447023663 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/docstring-first-line-empty/good.py0000664000175000017500000000044015146021447025163 0ustar epsilonepsilondef foo(): """Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book """ pylint-4.0.5/doc/data/messages/d/docstring-first-line-empty/pylintrc0000664000175000017500000000006115146021447025447 0ustar epsilonepsilon[MAIN] load-plugins = pylint.extensions.docstyle pylint-4.0.5/doc/data/messages/d/docstring-first-line-empty/bad.py0000664000175000017500000000050515146021447024763 0ustar epsilonepsilondef foo(): # [docstring-first-line-empty] """ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book """ pylint-4.0.5/doc/data/messages/d/duplicate-key/0000775000175000017500000000000015146021447021221 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/duplicate-key/good.py0000664000175000017500000000007715146021447022527 0ustar epsilonepsilontest_score = {"Mathematics": 85, "Biology": 90, "History": 75} pylint-4.0.5/doc/data/messages/d/duplicate-key/bad.py0000664000175000017500000000012615146021447022320 0ustar epsilonepsilontest_score = {"Mathematics": 85, "Biology": 90, "Mathematics": 75} # [duplicate-key] pylint-4.0.5/doc/data/messages/d/duplicate-key/related.rst0000664000175000017500000000027215146021447023374 0ustar epsilonepsilon- `Python Dictionaries `_ - `Mapping Types — dict `_ pylint-4.0.5/doc/data/messages/d/declare-non-slot/0000775000175000017500000000000015146021447021627 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/d/declare-non-slot/good.py0000664000175000017500000000012315146021447023125 0ustar epsilonepsilonclass Student: __slots__ = ("name", "surname") name: str surname: str pylint-4.0.5/doc/data/messages/d/declare-non-slot/bad.py0000664000175000017500000000013715146021447022730 0ustar epsilonepsilonclass Student: __slots__ = ("name",) name: str surname: str # [declare-non-slot] pylint-4.0.5/doc/data/messages/p/0000775000175000017500000000000015146021447016475 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/pointless-statement/0000775000175000017500000000000015146021447022517 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/pointless-statement/good.py0000664000175000017500000000004415146021447024017 0ustar epsilonepsilonNUMBERS = [1, 2, 3] print(NUMBERS) pylint-4.0.5/doc/data/messages/p/pointless-statement/bad.py0000664000175000017500000000004315146021447023614 0ustar epsilonepsilon[1, 2, 3] # [pointless-statement] pylint-4.0.5/doc/data/messages/p/pointless-string-statement/0000775000175000017500000000000015146021447024023 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/pointless-string-statement/good.py0000664000175000017500000000017115146021447025324 0ustar epsilonepsilon"""This is a docstring which describes the module""" # This is comment which describes a particular part of the module. pylint-4.0.5/doc/data/messages/p/pointless-string-statement/bad.py0000664000175000017500000000016415146021447025124 0ustar epsilonepsilon"""This is a docstring which describes the module""" """This is not a docstring""" # [pointless-string-statement] pylint-4.0.5/doc/data/messages/p/pointless-string-statement/related.rst0000664000175000017500000000022015146021447026167 0ustar epsilonepsilon- `Discussion thread re: docstrings on assignments `_ pylint-4.0.5/doc/data/messages/p/protected-access/0000775000175000017500000000000015146021447021725 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/protected-access/good.py0000664000175000017500000000017715146021447023234 0ustar epsilonepsilonclass Worm: def __swallow(self): pass def eat(self): return self.__swallow() jim = Worm() jim.eat() pylint-4.0.5/doc/data/messages/p/protected-access/bad.py0000664000175000017500000000014715146021447023027 0ustar epsilonepsilonclass Worm: def __swallow(self): pass jim = Worm() jim.__swallow() # [protected-access] pylint-4.0.5/doc/data/messages/p/property-with-parameters/0000775000175000017500000000000015146021447023473 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/property-with-parameters/good.py0000664000175000017500000000032315146021447024773 0ustar epsilonepsilonclass Worm: @property def bore(self): """Property accessed with '.bore'.""" pass def bore_with_depth(depth): """Function called with .bore_with_depth(depth).""" pass pylint-4.0.5/doc/data/messages/p/property-with-parameters/bad.py0000664000175000017500000000014015146021447024566 0ustar epsilonepsilonclass Worm: @property def bore(self, depth): # [property-with-parameters] pass pylint-4.0.5/doc/data/messages/p/possibly-unused-variable/0000775000175000017500000000000015146021447023425 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/possibly-unused-variable/good.py0000664000175000017500000000021015146021447024720 0ustar epsilonepsilondef choose_fruits(fruits): current_locals = locals() print(fruits) color = "red" print(color) return current_locals pylint-4.0.5/doc/data/messages/p/possibly-unused-variable/bad.py0000664000175000017500000000016115146021447024523 0ustar epsilonepsilondef choose_fruits(fruits): print(fruits) color = "red" # [possibly-unused-variable] return locals() pylint-4.0.5/doc/data/messages/p/prefer-typing-namedtuple/0000775000175000017500000000000015146021447023424 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/prefer-typing-namedtuple/good.py0000664000175000017500000000016215146021447024725 0ustar epsilonepsilonfrom typing import NamedTuple class Philosophy(NamedTuple): goodness: str truth: bool beauty: float pylint-4.0.5/doc/data/messages/p/prefer-typing-namedtuple/pylintrc0000664000175000017500000000006315146021447025212 0ustar epsilonepsilon[MAIN] load-plugins = pylint.extensions.code_style pylint-4.0.5/doc/data/messages/p/prefer-typing-namedtuple/bad.py0000664000175000017500000000021715146021447024524 0ustar epsilonepsilonfrom collections import namedtuple Philosophy = namedtuple( # [prefer-typing-namedtuple] "Philosophy", ("goodness", "truth", "beauty") ) pylint-4.0.5/doc/data/messages/p/prefer-typing-namedtuple/related.rst0000664000175000017500000000013115146021447025571 0ustar epsilonepsilon- `typing.NamedTuple `_ pylint-4.0.5/doc/data/messages/p/positional-only-arguments-expected/0000775000175000017500000000000015146021447025437 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/positional-only-arguments-expected/good.py0000664000175000017500000000013715146021447026742 0ustar epsilonepsilondef cube(n, /): """Takes in a number n, returns the cube of n""" return n**3 cube(2) pylint-4.0.5/doc/data/messages/p/positional-only-arguments-expected/bad.py0000664000175000017500000000021115146021447026531 0ustar epsilonepsilondef cube(n, /): """Takes in a number n, returns the cube of n""" return n**3 cube(n=2) # [positional-only-arguments-expected] pylint-4.0.5/doc/data/messages/p/positional-only-arguments-expected/related.rst0000664000175000017500000000006015146021447027605 0ustar epsilonepsilon- `PEP 570 `_ pylint-4.0.5/doc/data/messages/p/potential-index-error/0000775000175000017500000000000015146021447022730 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/potential-index-error/good.py0000664000175000017500000000002415146021447024226 0ustar epsilonepsilonprint([1, 2, 3][2]) pylint-4.0.5/doc/data/messages/p/potential-index-error/bad.py0000664000175000017500000000005715146021447024032 0ustar epsilonepsilonprint([1, 2, 3][3]) # [potential-index-error] pylint-4.0.5/doc/data/messages/p/preferred-module/0000775000175000017500000000000015146021447021736 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/preferred-module/good.py0000664000175000017500000000002015146021447023230 0ustar epsilonepsilonimport requests pylint-4.0.5/doc/data/messages/p/preferred-module/pylintrc0000664000175000017500000000005515146021447023525 0ustar epsilonepsilon[IMPORTS] preferred-modules=urllib:requests, pylint-4.0.5/doc/data/messages/p/preferred-module/bad.py0000664000175000017500000000004415146021447023034 0ustar epsilonepsilonimport urllib # [preferred-module] pylint-4.0.5/doc/data/messages/p/parse-error/0000775000175000017500000000000015146021447020736 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/parse-error/details.rst0000664000175000017500000000014315146021447023113 0ustar epsilonepsilonThis is a message linked to an internal problem in pylint. There's nothing to change in your code. pylint-4.0.5/doc/data/messages/p/pointless-exception-statement/0000775000175000017500000000000015146021447024513 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/pointless-exception-statement/good.py0000664000175000017500000000004415146021447026013 0ustar epsilonepsilonraise Exception("This will raise.") pylint-4.0.5/doc/data/messages/p/pointless-exception-statement/bad.py0000664000175000017500000000011715146021447025612 0ustar epsilonepsilonException("This exception is a statement.") # [pointless-exception-statement] pylint-4.0.5/doc/data/messages/p/possibly-used-before-assignment/0000775000175000017500000000000015146021447024705 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/p/possibly-used-before-assignment/good.py0000664000175000017500000000016015146021447026204 0ustar epsilonepsilondef check_lunchbox(items: list[str]): empty = False if not items: empty = True print(empty) pylint-4.0.5/doc/data/messages/p/possibly-used-before-assignment/details.rst0000664000175000017500000000306015146021447027063 0ustar epsilonepsilonYou can use ``assert_never`` to mark exhaustive choices: .. sourcecode:: python from typing import assert_never def handle_date_suffix(suffix): if suffix == "d": ... elif suffix == "m": ... elif suffix == "y": ... else: assert_never(suffix) if suffix in "dmy": handle_date_suffix(suffix) Or, instead of `assert_never()`, you can call a function with a return annotation of `Never` or `NoReturn`. Unlike in the general case, where by design pylint ignores type annotations and does its own static analysis, here, pylint treats these special annotations like a disable comment. Pylint currently allows repeating the same test like this, even though this lets some error cases through, as pylint does not assess the intervening code: .. sourcecode:: python if guarded(): var = 1 # what if code here affects the result of guarded()? if guarded(): print(var) But this exception is limited to the repeating the exact same test. This warns: .. sourcecode:: python if guarded(): var = 1 if guarded() or other_condition: print(var) # [possibly-used-before-assignment] If you find this surprising, consider that pylint, as a static analysis tool, does not know if ``guarded()`` is deterministic or talks to a database. For variables (e.g. ``guarded`` versus ``guarded()``), this is less of an issue, so in this case, ``possibly-used-before-assignment`` acts more like a future-proofing style preference than an error, per se. pylint-4.0.5/doc/data/messages/p/possibly-used-before-assignment/bad.py0000664000175000017500000000020315146021447026000 0ustar epsilonepsilondef check_lunchbox(items: list[str]): if not items: empty = True print(empty) # [possibly-used-before-assignment] pylint-4.0.5/doc/data/messages/c/0000775000175000017500000000000015146021447016460 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-math-not-float/0000775000175000017500000000000015146021447023116 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-math-not-float/good.py0000664000175000017500000000003515146021447024416 0ustar epsilonepsilonimport math swag = math.inf pylint-4.0.5/doc/data/messages/c/consider-math-not-float/pylintrc0000664000175000017500000000006115146021447024702 0ustar epsilonepsilon[MAIN] load-plugins=pylint.extensions.code_style pylint-4.0.5/doc/data/messages/c/consider-math-not-float/details.rst0000664000175000017500000000222415146021447025275 0ustar epsilonepsilonThis is an extension check because the typing advantage could be fixed. Regarding performance, float("nan") and float("inf") are slower than their counterpart math.inf and math.nan by a factor of 4 after the initial import of math. .. code-block:: python import math import timeit time_math_inf = timeit.timeit('math.nan', globals=globals(), number=10**8) print(f'math.nan: {time_math_inf:.2f} seconds') import timeit time_inf_str = timeit.timeit('float("nan")', number=10**8) print(f'float("nan"): {time_inf_str:.2f} seconds') Result:: math.nan: 1.24 seconds float("nan"): 5.15 seconds But if we take the initial import into account it's worse. .. code-block:: python import timeit time_math_inf = timeit.timeit('import math;math.nan', globals=globals(), number=10**8) print(f'math.nan: {time_math_inf:.2f} seconds') import timeit time_inf_str = timeit.timeit('float("nan")', number=10**8) print(f'float("nan"): {time_inf_str:.2f} seconds') Result:: math.nan: 9.08 seconds float("nan"): 5.33 seconds So the decision depends on how and how often you need to use it and what matter to you. pylint-4.0.5/doc/data/messages/c/consider-math-not-float/bad.py0000664000175000017500000000006115146021447024213 0ustar epsilonepsilonswag = float("inf") # [consider-math-not-float] pylint-4.0.5/doc/data/messages/c/contextmanager-generator-missing-cleanup/0000775000175000017500000000000015146021447026557 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/contextmanager-generator-missing-cleanup/good.py0000664000175000017500000000221115146021447030055 0ustar epsilonepsilonimport contextlib @contextlib.contextmanager def good_cm_except(): contextvar = "acquired context" print("good cm enter") try: yield contextvar except GeneratorExit: print("good cm exit") def genfunc_with_cm(): with good_cm_except() as context: yield context * 2 def genfunc_with_discard(): with good_cm_except(): yield "discarded" @contextlib.contextmanager def good_cm_yield_none(): print("good cm enter") yield print("good cm exit") def genfunc_with_none_yield(): with good_cm_yield_none() as var: print(var) yield "constant yield" @contextlib.contextmanager def good_cm_finally(): contextvar = "acquired context" print("good cm enter") try: yield contextvar finally: print("good cm exit") def good_cm_finally_genfunc(): with good_cm_finally() as context: yield context * 2 @contextlib.contextmanager def good_cm_no_cleanup(): contextvar = "acquired context" print("cm enter") yield contextvar def good_cm_no_cleanup_genfunc(): with good_cm_no_cleanup() as context: yield context * 2 pylint-4.0.5/doc/data/messages/c/contextmanager-generator-missing-cleanup/details.rst0000664000175000017500000000250215146021447030735 0ustar epsilonepsilonInstantiating and using a contextmanager inside a generator function can result in unexpected behavior if there is an expectation that the context is only available for the generator function. In the case that the generator is not closed or destroyed then the context manager is held suspended as is. This message warns on the generator function instead of the contextmanager function because the ways to use a contextmanager are many. A contextmanager can be used as a decorator (which immediately has ``__enter__``/``__exit__`` applied) and the use of ``as ...`` or discard of the return value also implies whether the context needs cleanup or not. So for this message, warning the invoker of the contextmanager is important. The check can create false positives if ``yield`` is used inside an ``if-else`` block without custom cleanup. Use ``pylint: disable`` for these. .. code-block:: python from contextlib import contextmanager @contextmanager def good_cm_no_cleanup(): contextvar = "acquired context" print("cm enter") if some_condition: yield contextvar else: yield contextvar def good_cm_no_cleanup_genfunc(): # pylint: disable-next=contextmanager-generator-missing-cleanup with good_cm_no_cleanup() as context: yield context * 2 pylint-4.0.5/doc/data/messages/c/contextmanager-generator-missing-cleanup/bad.py0000664000175000017500000000043015146021447027654 0ustar epsilonepsilonimport contextlib @contextlib.contextmanager def cm(): contextvar = "acquired context" print("cm enter") yield contextvar print("cm exit") def genfunc_with_cm(): with cm() as context: # [contextmanager-generator-missing-cleanup] yield context * 2 pylint-4.0.5/doc/data/messages/c/contextmanager-generator-missing-cleanup/related.rst0000664000175000017500000000030015146021447030722 0ustar epsilonepsilon- `Rationale `_ - `CPython Issue `_ pylint-4.0.5/doc/data/messages/c/consider-using-max-builtin/0000775000175000017500000000000015146021447023640 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-max-builtin/good.py0000664000175000017500000000002115146021447025133 0ustar epsilonepsilonprint(max(1, 2)) pylint-4.0.5/doc/data/messages/c/consider-using-max-builtin/bad.py0000664000175000017500000000022615146021447024740 0ustar epsilonepsilondef get_max(value1, value2): if value1 < value2: # [consider-using-max-builtin] value1 = value2 return value1 print(get_max(1, 2)) pylint-4.0.5/doc/data/messages/c/consider-using-ternary/0000775000175000017500000000000015146021447023073 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-ternary/good.py0000664000175000017500000000005115146021447024371 0ustar epsilonepsilonx, y = 1, 2 maximum = x if x >= y else y pylint-4.0.5/doc/data/messages/c/consider-using-ternary/bad.py0000664000175000017500000000010415146021447024166 0ustar epsilonepsilonx, y = 1, 2 maximum = x >= y and x or y # [consider-using-ternary] pylint-4.0.5/doc/data/messages/c/consider-using-dict-comprehension/0000775000175000017500000000000015146021447025201 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-dict-comprehension/good.py0000664000175000017500000000012215146021447026476 0ustar epsilonepsilonNUMBERS = [1, 2, 3] DOUBLED_NUMBERS = {number: number * 2 for number in NUMBERS} pylint-4.0.5/doc/data/messages/c/consider-using-dict-comprehension/details.rst0000664000175000017500000000022315146021447027355 0ustar epsilonepsilonpyupgrade_ or ruff_ can fix this issue automatically. .. _pyupgrade: https://github.com/asottile/pyupgrade .. _ruff: https://docs.astral.sh/ruff/ pylint-4.0.5/doc/data/messages/c/consider-using-dict-comprehension/bad.py0000664000175000017500000000020415146021447026275 0ustar epsilonepsilonNUMBERS = [1, 2, 3] # +1: [consider-using-dict-comprehension] DOUBLED_NUMBERS = dict([(number, number * 2) for number in NUMBERS]) pylint-4.0.5/doc/data/messages/c/consider-using-sys-exit/0000775000175000017500000000000015146021447023174 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-sys-exit/good.py0000664000175000017500000000017115146021447024475 0ustar epsilonepsilonimport sys if __name__ == "__main__": user = input("Enter user name: ") print(f"Hello, {user}") sys.exit(0) pylint-4.0.5/doc/data/messages/c/consider-using-sys-exit/bad.py0000664000175000017500000000020615146021447024272 0ustar epsilonepsilonif __name__ == "__main__": user = input("Enter user name: ") print(f"Hello, {user}") exit(0) # [consider-using-sys-exit] pylint-4.0.5/doc/data/messages/c/consider-refactoring-into-while-condition/0000775000175000017500000000000015146021447026630 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-refactoring-into-while-condition/good.py0000664000175000017500000000025715146021447030136 0ustar epsilonepsilonfruit_basket = ["apple", "orange", "banana", "cherry", "guava"] while len(fruit_basket) != 0: fruit = fruit_basket.pop() print(f"We removed {fruit} from the basket") pylint-4.0.5/doc/data/messages/c/consider-refactoring-into-while-condition/pylintrc0000664000175000017500000000012015146021447030410 0ustar epsilonepsilon[MAIN] load-plugins=pylint.extensions.consider_refactoring_into_while_condition pylint-4.0.5/doc/data/messages/c/consider-refactoring-into-while-condition/bad.py0000664000175000017500000000037115146021447027731 0ustar epsilonepsilonfruit_basket = ["apple", "orange", "banana", "cherry", "guava"] while True: # [consider-refactoring-into-while-condition] if len(fruit_basket) == 0: break fruit = fruit_basket.pop() print(f"We removed {fruit} from the basket") pylint-4.0.5/doc/data/messages/c/cell-var-from-loop/0000775000175000017500000000000015146021447022075 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/cell-var-from-loop/bad.py0000664000175000017500000000114315146021447023174 0ustar epsilonepsilondef teacher_greeting(names): greetings = [] for name in names: def greet(): # do something print(f"Hello, {name}!") # [cell-var-from-loop] if name.isalpha(): greetings.append(greet) for greet in greetings: # the "name" variable is evaluated when the function is called here, # which is the last value it had in the loop - "Not-A-Name" greet() teacher_greeting(["Graham", "John", "Terry", "Eric", "Terry", "Michael"]) # "Hello, Michael!" # "Hello, Michael!" # "Hello, Michael!" # "Hello, Michael!" # "Hello, Michael!" pylint-4.0.5/doc/data/messages/c/cell-var-from-loop/related.rst0000664000175000017500000000016415146021447024250 0ustar epsilonepsilon- `Stackoverflow discussion `_ pylint-4.0.5/doc/data/messages/c/cell-var-from-loop/good/0000775000175000017500000000000015146021447023025 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/cell-var-from-loop/good/functools.partial.py0000664000175000017500000000116315146021447027047 0ustar epsilonepsilonimport functools def teacher_greeting(names): greetings = [] for name in names: if name.isalpha(): # "name" is evaluated when the partial is created here, so this # does not do lazy evaluation greetings.append(functools.partial(print, f"Hello, {name}!")) for greet in greetings: # `partial`s are called like functions, but you've already passed the # arguments to them greet() teacher_greeting(["Graham", "John", "Terry", "Eric", "Terry", "Michael"]) # "Hello, Graham!" # "Hello, John!" # "Hello, Eric!" # "Hello, Terry!" # "Hello, Michael!" pylint-4.0.5/doc/data/messages/c/cell-var-from-loop/good/new_function.py0000664000175000017500000000064115146021447026076 0ustar epsilonepsilondef teacher_greeting(names): def greet(name): # do something print(f"Hello, {name}!") for name in names: if name.isalpha(): # we're passing the value of "name" to the function here greet(name) teacher_greeting(["Graham", "John", "Terry", "Eric", "Terry", "Michael"]) # "Hello, Graham!" # "Hello, John!" # "Hello, Eric!" # "Hello, Terry!" # "Hello, Michael!" pylint-4.0.5/doc/data/messages/c/consider-using-min-builtin/0000775000175000017500000000000015146021447023636 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-min-builtin/good.py0000664000175000017500000000002115146021447025131 0ustar epsilonepsilonprint(min(1, 2)) pylint-4.0.5/doc/data/messages/c/consider-using-min-builtin/bad.py0000664000175000017500000000022615146021447024736 0ustar epsilonepsilondef get_min(value1, value2): if value1 > value2: # [consider-using-min-builtin] value1 = value2 return value1 print(get_min(1, 2)) pylint-4.0.5/doc/data/messages/c/consider-using-in/0000775000175000017500000000000015146021447022015 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-in/good.py0000664000175000017500000000011415146021447023313 0ustar epsilonepsilondef fruit_is_round(fruit): return fruit in {"apple", "orange", "melon"} pylint-4.0.5/doc/data/messages/c/consider-using-in/bad.py0000664000175000017500000000017615146021447023121 0ustar epsilonepsilondef fruit_is_round(fruit): # +1: [consider-using-in] return fruit == "apple" or fruit == "orange" or fruit == "melon" pylint-4.0.5/doc/data/messages/c/consider-using-namedtuple-or-dataclass/0000775000175000017500000000000015146021447026120 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-namedtuple-or-dataclass/good.py0000664000175000017500000000066615146021447027432 0ustar epsilonepsilonfrom typing import NamedTuple class FelidaeCharacteristics(NamedTuple): tail_length_cm: int paws: int eyes: int hat: str | None FELIDAES = { "The queen's cymric, fragile furry friend": FelidaeCharacteristics( tail_length_cm=1, paws=4, eyes=2, hat="Elizabethan collar" ), "Rackat the red, terror of the sea": FelidaeCharacteristics( tail_length_cm=21, paws=3, eyes=1, hat="Red Hat" ), } pylint-4.0.5/doc/data/messages/c/consider-using-namedtuple-or-dataclass/pylintrc0000664000175000017500000000006115146021447027704 0ustar epsilonepsilon[MAIN] load-plugins=pylint.extensions.code_style pylint-4.0.5/doc/data/messages/c/consider-using-namedtuple-or-dataclass/bad.py0000664000175000017500000000054415146021447027223 0ustar epsilonepsilonFELIDAES = { # [consider-using-namedtuple-or-dataclass] "The queen's cymric, fragile furry friend": { "tail_length_cm": 1, "paws": 4, "eyes": 2, "Elizabethan collar": 1, }, "Rackat the red, terror of the sea": { "tail_length_cm": 13, "paws": 3, "eyes": 1, "Red Hat": 1, }, } pylint-4.0.5/doc/data/messages/c/consider-using-dict-items/0000775000175000017500000000000015146021447023451 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-dict-items/good.py0000664000175000017500000000030615146021447024752 0ustar epsilonepsilonORCHESTRA = { "violin": "strings", "oboe": "woodwind", "tuba": "brass", "gong": "percussion", } for instrument, section in ORCHESTRA.items(): print(f"{instrument}: {section}") pylint-4.0.5/doc/data/messages/c/consider-using-dict-items/bad.py0000664000175000017500000000034215146021447024550 0ustar epsilonepsilonORCHESTRA = { "violin": "strings", "oboe": "woodwind", "tuba": "brass", "gong": "percussion", } for instrument in ORCHESTRA: # [consider-using-dict-items] print(f"{instrument}: {ORCHESTRA[instrument]}") pylint-4.0.5/doc/data/messages/c/confusing-consecutive-elif/0000775000175000017500000000000015146021447023715 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/confusing-consecutive-elif/good.py0000664000175000017500000000102615146021447025216 0ustar epsilonepsilon# Option 1: add explicit 'else' def myfunc(shall_continue: bool, shall_exit: bool): if shall_continue: if input("Are you sure?") == "y": print("Moving on.") else: pass elif shall_exit: print("Exiting.") # Option 2: extract function def user_confirmation(): if input("Are you sure?") == "y": print("Moving on.") def myfunc2(shall_continue: bool, shall_exit: bool): if shall_continue: user_confirmation() elif shall_exit: print("Exiting.") pylint-4.0.5/doc/data/messages/c/confusing-consecutive-elif/pylintrc0000664000175000017500000000006515146021447025505 0ustar epsilonepsilon[MAIN] load-plugins=pylint.extensions.confusing_elif pylint-4.0.5/doc/data/messages/c/confusing-consecutive-elif/details.rst0000664000175000017500000000027315146021447026076 0ustar epsilonepsilonCreating a function for the nested conditional, or adding an explicit ``else`` in the indented ``if`` statement, even if it only contains a ``pass`` statement, can help clarify the code. pylint-4.0.5/doc/data/messages/c/confusing-consecutive-elif/bad.py0000664000175000017500000000034415146021447025016 0ustar epsilonepsilondef myfunc(shall_continue: bool, shall_exit: bool): if shall_continue: if input("Are you sure?") == "y": print("Moving on.") elif shall_exit: # [confusing-consecutive-elif] print("Exiting.") pylint-4.0.5/doc/data/messages/c/consider-using-augmented-assign/0000775000175000017500000000000015146021447024642 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-augmented-assign/good.py0000664000175000017500000000001515146021447026140 0ustar epsilonepsilonx = 1 x += 1 pylint-4.0.5/doc/data/messages/c/consider-using-augmented-assign/pylintrc0000664000175000017500000000013015146021447026423 0ustar epsilonepsilon[MAIN] load-plugins=pylint.extensions.code_style enable=consider-using-augmented-assign pylint-4.0.5/doc/data/messages/c/consider-using-augmented-assign/bad.py0000664000175000017500000000006515146021447025743 0ustar epsilonepsilonx = 1 x = x + 1 # [consider-using-augmented-assign] pylint-4.0.5/doc/data/messages/c/consider-using-assignment-expr/0000775000175000017500000000000015146021447024533 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-assignment-expr/good.py0000664000175000017500000000005115146021447026031 0ustar epsilonepsilonif apples := 2: print("God apples!") pylint-4.0.5/doc/data/messages/c/consider-using-assignment-expr/pylintrc0000664000175000017500000000010015146021447026311 0ustar epsilonepsilon[MAIN] py-version=3.8 load-plugins=pylint.extensions.code_style pylint-4.0.5/doc/data/messages/c/consider-using-assignment-expr/bad.py0000664000175000017500000000012415146021447025630 0ustar epsilonepsilonapples = 2 if apples: # [consider-using-assignment-expr] print("God apples!") pylint-4.0.5/doc/data/messages/c/consider-using-tuple/0000775000175000017500000000000015146021447022540 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-tuple/good.py0000664000175000017500000000004115146021447024035 0ustar epsilonepsilonfor i in (1, 2, 3): print(i) pylint-4.0.5/doc/data/messages/c/consider-using-tuple/pylintrc0000664000175000017500000000006115146021447024324 0ustar epsilonepsilon[MAIN] load-plugins=pylint.extensions.code_style pylint-4.0.5/doc/data/messages/c/consider-using-tuple/bad.py0000664000175000017500000000007315146021447023640 0ustar epsilonepsilonfor i in [1, 2, 3]: # [consider-using-tuple] print(i) pylint-4.0.5/doc/data/messages/c/consider-using-generator/0000775000175000017500000000000015146021447023375 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-generator/good.py0000664000175000017500000000025415146021447024700 0ustar epsilonepsilonlist(0 for y in list(range(10))) tuple(0 for y in list(range(10))) sum(y**2 for y in list(range(10))) max(y**2 for y in list(range(10))) min(y**2 for y in list(range(10))) pylint-4.0.5/doc/data/messages/c/consider-using-generator/details.rst0000664000175000017500000000050215146021447025551 0ustar epsilonepsilonRemoving ``[]`` inside calls that can use containers or generators should be considered for performance reasons since a generator will have an upfront cost to pay. The performance will be better if you are working with long lists or sets. For ``max``, ``min`` and ``sum`` using a generator is also recommended by pep289. pylint-4.0.5/doc/data/messages/c/consider-using-generator/bad.py0000664000175000017500000000051415146021447024475 0ustar epsilonepsilonlist([0 for y in list(range(10))]) # [consider-using-generator] tuple([0 for y in list(range(10))]) # [consider-using-generator] sum([y**2 for y in list(range(10))]) # [consider-using-generator] max([y**2 for y in list(range(10))]) # [consider-using-generator] min([y**2 for y in list(range(10))]) # [consider-using-generator] pylint-4.0.5/doc/data/messages/c/consider-using-generator/related.rst0000664000175000017500000000044415146021447025551 0ustar epsilonepsilon- `PEP 289 `_ - `Benchmark and discussion for any/all/list/tuple `_ - `Benchmark and discussion for sum/max/min `_ pylint-4.0.5/doc/data/messages/c/catching-non-exception/0000775000175000017500000000000015146021447023024 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/catching-non-exception/good.py0000664000175000017500000000011715146021447024325 0ustar epsilonepsilonclass FooError(Exception): pass try: 1 / 0 except FooError: pass pylint-4.0.5/doc/data/messages/c/catching-non-exception/bad.py0000664000175000017500000000014015146021447024117 0ustar epsilonepsilonclass FooError: pass try: 1 / 0 except FooError: # [catching-non-exception] pass pylint-4.0.5/doc/data/messages/c/consider-using-from-import/0000775000175000017500000000000015146021447023662 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-from-import/good.py0000664000175000017500000000002415146021447025160 0ustar epsilonepsilonfrom os import path pylint-4.0.5/doc/data/messages/c/consider-using-from-import/bad.py0000664000175000017500000000006715146021447024765 0ustar epsilonepsilonimport os.path as path # [consider-using-from-import] pylint-4.0.5/doc/data/messages/c/consider-using-f-string/0000775000175000017500000000000015146021447023140 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-f-string/good.py0000664000175000017500000000013615146021447024442 0ustar epsilonepsilonmenu = ("eggs", "spam", 42.4) f_string_order = f"{menu[0]} and {menu[1]}: {menu[2]:0.2f} ¤" pylint-4.0.5/doc/data/messages/c/consider-using-f-string/details.rst0000664000175000017500000000051115146021447025314 0ustar epsilonepsilonFormatted string literals (f-strings) give a concise, consistent syntax that can replace most use cases for the ``%`` formatting operator, ``str.format()`` and ``string.Template``. F-strings also perform better than alternatives; see `this tweet `_ for a simple example. pylint-4.0.5/doc/data/messages/c/consider-using-f-string/bad.py0000664000175000017500000000114115146021447024235 0ustar epsilonepsilonfrom string import Template menu = ("eggs", "spam", 42.4) old_order = "%s and %s: %.2f ¤" % menu # [consider-using-f-string] beginner_order = menu[0] + " and " + menu[1] + ": " + str(menu[2]) + " ¤" joined_order = " and ".join(menu[:2]) # +1: [consider-using-f-string] format_order = "{} and {}: {:0.2f} ¤".format(menu[0], menu[1], menu[2]) # +1: [consider-using-f-string] named_format_order = "{eggs} and {spam}: {price:0.2f} ¤".format( eggs=menu[0], spam=menu[1], price=menu[2] ) template_order = Template("$eggs and $spam: $price ¤").substitute( eggs=menu[0], spam=menu[1], price=menu[2] ) pylint-4.0.5/doc/data/messages/c/consider-using-join/0000775000175000017500000000000015146021447022346 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-join/good.py0000664000175000017500000000005315146021447023646 0ustar epsilonepsilonprint("".join(["apple", "pear", "peach"])) pylint-4.0.5/doc/data/messages/c/consider-using-join/bad.py0000664000175000017500000000033315146021447023445 0ustar epsilonepsilondef fruits_to_string(fruits): formatted_fruit = "" for fruit in fruits: formatted_fruit += fruit # [consider-using-join] return formatted_fruit print(fruits_to_string(["apple", "pear", "peach"])) pylint-4.0.5/doc/data/messages/c/consider-using-alias/0000775000175000017500000000000015146021447022500 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-alias/good.py0000664000175000017500000000007315146021447024002 0ustar epsilonepsilonimport typing cats: typing.cast(dict[str, int], "string") pylint-4.0.5/doc/data/messages/c/consider-using-alias/pylintrc0000664000175000017500000000012215146021447024262 0ustar epsilonepsilon[main] load-plugins = pylint.extensions.typing py-version = 3.7 runtime-typing=no pylint-4.0.5/doc/data/messages/c/consider-using-alias/bad.py0000664000175000017500000000010515146021447023574 0ustar epsilonepsilonimport typing cats: typing.Dict[str, int] # [consider-using-alias] pylint-4.0.5/doc/data/messages/c/confusing-with-statement/0000775000175000017500000000000015146021447023426 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/confusing-with-statement/good.py0000664000175000017500000000017115146021447024727 0ustar epsilonepsilonwith open("file.txt", "w", encoding="utf8") as fh1: with open("file.txt", "w", encoding="utf8") as fh2: pass pylint-4.0.5/doc/data/messages/c/confusing-with-statement/bad.py0000664000175000017500000000011715146021447024525 0ustar epsilonepsilonwith open("file.txt", "w") as fh1, fh2: # [confusing-with-statement] pass pylint-4.0.5/doc/data/messages/c/config-parse-error/0000775000175000017500000000000015146021447022164 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/config-parse-error/details.rst0000664000175000017500000000011315146021447024336 0ustar epsilonepsilonThis is a message linked to a problem in your configuration not your code. pylint-4.0.5/doc/data/messages/c/consider-iterating-dictionary/0000775000175000017500000000000015146021447024415 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-iterating-dictionary/good.py0000664000175000017500000000012615146021447025716 0ustar epsilonepsilonFRUITS = {"apple": 1, "pear": 5, "peach": 10} for fruit in FRUITS: print(fruit) pylint-4.0.5/doc/data/messages/c/consider-iterating-dictionary/bad.py0000664000175000017500000000020015146021447025505 0ustar epsilonepsilonFRUITS = {"apple": 1, "pear": 5, "peach": 10} for fruit in FRUITS.keys(): # [consider-iterating-dictionary] print(fruit) pylint-4.0.5/doc/data/messages/c/consider-using-enumerate/0000775000175000017500000000000015146021447023374 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-enumerate/good.py0000664000175000017500000000015415146021447024676 0ustar epsilonepsilonseasons = ["Spring", "Summer", "Fall", "Winter"] for i, season in enumerate(seasons): print(i, season) pylint-4.0.5/doc/data/messages/c/consider-using-enumerate/bad.py0000664000175000017500000000020715146021447024473 0ustar epsilonepsilonseasons = ["Spring", "Summer", "Fall", "Winter"] for i in range(len(seasons)): # [consider-using-enumerate] print(i, seasons[i]) pylint-4.0.5/doc/data/messages/c/consider-alternative-union-syntax/0000775000175000017500000000000015146021447025254 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-alternative-union-syntax/good.py0000664000175000017500000000015115146021447026553 0ustar epsilonepsilondef forecast(temp: int | float, unit: str | None) -> None: print(f'Temperature: {temp}{unit or ""}') pylint-4.0.5/doc/data/messages/c/consider-alternative-union-syntax/pylintrc0000664000175000017500000000005715146021447027045 0ustar epsilonepsilon[MAIN] load-plugins = pylint.extensions.typing pylint-4.0.5/doc/data/messages/c/consider-alternative-union-syntax/details.rst0000664000175000017500000000124415146021447027434 0ustar epsilonepsilonUsing the shorthand syntax for union types is |recommended over the typing module|__. This is consistent with the broader recommendation to prefer built-in types over imports (for example, using ``list`` instead of the now-deprecated ``typing.List``). ``typing.Optional`` can also cause confusion in annotated function arguments, since an argument annotated as ``Optional`` is still a *required* argument when a default value is not set. Explicitly annotating such arguments with ``type | None`` makes the intention clear. .. |recommended over the typing module| replace:: recommended over the ``typing`` module __ https://docs.python.org/3/library/typing.html#typing.Union pylint-4.0.5/doc/data/messages/c/consider-alternative-union-syntax/bad.py0000664000175000017500000000036015146021447026353 0ustar epsilonepsilonfrom typing import Optional, Union def forecast( temp: Union[int, float], # [consider-alternative-union-syntax] unit: Optional[str], # [consider-alternative-union-syntax] ) -> None: print(f'Temperature: {temp}{unit or ""}') pylint-4.0.5/doc/data/messages/c/condition-evals-to-constant/0000775000175000017500000000000015146021447024025 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/condition-evals-to-constant/good.py0000664000175000017500000000007715146021447025333 0ustar epsilonepsilondef is_a_fruit(fruit): return fruit in {"apple", "orange"} pylint-4.0.5/doc/data/messages/c/condition-evals-to-constant/bad.py0000664000175000017500000000015615146021447025127 0ustar epsilonepsilondef is_a_fruit(fruit): return bool(fruit in {"apple", "orange"} or True) # [condition-evals-to-constant] pylint-4.0.5/doc/data/messages/c/c-extension-no-member/0000775000175000017500000000000015146021447022573 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/c-extension-no-member/good.py0000664000175000017500000000007315146021447024075 0ustar epsilonepsilon# This is a placeholder for correct code for this message. pylint-4.0.5/doc/data/messages/c/c-extension-no-member/details.rst0000664000175000017500000000037515146021447024757 0ustar epsilonepsilon``c-extension-no-member`` is an informational variant of ``no-member`` to encourage allowing introspection of C extensions as described in the `page `_ for ``no-member``. pylint-4.0.5/doc/data/messages/c/consider-merging-isinstance/0000775000175000017500000000000015146021447024052 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-merging-isinstance/good.py0000664000175000017500000000014715146021447025356 0ustar epsilonepsilonfrom typing import Any def is_number(value: Any) -> bool: return isinstance(value, (int, float)) pylint-4.0.5/doc/data/messages/c/consider-merging-isinstance/bad.py0000664000175000017500000000024215146021447025150 0ustar epsilonepsilonfrom typing import Any def is_number(value: Any) -> bool: # +1: [consider-merging-isinstance] return isinstance(value, int) or isinstance(value, float) pylint-4.0.5/doc/data/messages/c/comparison-with-callable/0000775000175000017500000000000015146021447023340 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/comparison-with-callable/good.py0000664000175000017500000000025615146021447024645 0ustar epsilonepsilondef function_returning_a_fruit() -> str: return "orange" def is_an_orange(fruit: str = "apple"): # apple == orange return fruit == function_returning_a_fruit() pylint-4.0.5/doc/data/messages/c/comparison-with-callable/bad.py0000664000175000017500000000037315146021447024443 0ustar epsilonepsilondef function_returning_a_fruit() -> str: return "orange" def is_an_orange(fruit: str = "apple"): # apple == return fruit == function_returning_a_fruit # [comparison-with-callable] pylint-4.0.5/doc/data/messages/c/continue-in-finally/0000775000175000017500000000000015146021447022344 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/continue-in-finally/good.py0000664000175000017500000000014115146021447023642 0ustar epsilonepsilonwhile True: try: pass except ValueError: pass else: continue pylint-4.0.5/doc/data/messages/c/continue-in-finally/bad.py0000664000175000017500000000013115146021447023437 0ustar epsilonepsilonwhile True: try: pass finally: continue # [continue-in-finally] pylint-4.0.5/doc/data/messages/c/continue-in-finally/related.rst0000664000175000017500000000033115146021447024513 0ustar epsilonepsilon- `Python 3 docs 'finally' clause `_ - `PEP 765 - Disallow return/break/continue that exit a finally block `_ pylint-4.0.5/doc/data/messages/c/consider-using-set-comprehension/0000775000175000017500000000000015146021447025051 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-set-comprehension/good.py0000664000175000017500000000014615146021447026354 0ustar epsilonepsilonNUMBERS = [1, 2, 2, 3, 4, 4] UNIQUE_EVEN_NUMBERS = {number for number in NUMBERS if number % 2 == 0} pylint-4.0.5/doc/data/messages/c/consider-using-set-comprehension/details.rst0000664000175000017500000000022315146021447027225 0ustar epsilonepsilonpyupgrade_ or ruff_ can fix this issue automatically. .. _pyupgrade: https://github.com/asottile/pyupgrade .. _ruff: https://docs.astral.sh/ruff/ pylint-4.0.5/doc/data/messages/c/consider-using-set-comprehension/bad.py0000664000175000017500000000022415146021447026147 0ustar epsilonepsilonNUMBERS = [1, 2, 2, 3, 4, 4] # +1: [consider-using-set-comprehension] UNIQUE_EVEN_NUMBERS = set([number for number in NUMBERS if number % 2 == 0]) pylint-4.0.5/doc/data/messages/c/chained-comparison/0000775000175000017500000000000015146021447022223 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/chained-comparison/good.py0000664000175000017500000000011215146021447023517 0ustar epsilonepsilona = int(input()) b = int(input()) c = int(input()) if a < b < c: pass pylint-4.0.5/doc/data/messages/c/chained-comparison/bad.py0000664000175000017500000000015015146021447023317 0ustar epsilonepsilona = int(input()) b = int(input()) c = int(input()) if a < b and b < c: # [chained-comparison] pass pylint-4.0.5/doc/data/messages/c/cyclic-import/0000775000175000017500000000000015146021447021236 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/cyclic-import/good.py0000664000175000017500000000021315146021447022534 0ustar epsilonepsilondef count_to_one(): return 1 def count_to_two(): return count_to_one() + 1 def count_to_three(): return count_to_two() + 1 pylint-4.0.5/doc/data/messages/c/cyclic-import/details.rst0000664000175000017500000000026315146021447023416 0ustar epsilonepsilonThe good code is just an example. There are various strategies to resolving cyclic imports and the best choice relies heavily on the context of the code and the affected modules. pylint-4.0.5/doc/data/messages/c/cyclic-import/bad/0000775000175000017500000000000015146021447021764 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/cyclic-import/bad/__init__.py0000664000175000017500000000000015146021447024063 0ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/cyclic-import/bad/bad.py0000664000175000017500000000017315146021447023065 0ustar epsilonepsilondef count_to_one(): return 1 def count_to_three(): from .bad2 import count_to_two return count_to_two() + 1 pylint-4.0.5/doc/data/messages/c/cyclic-import/bad/bad2.py0000664000175000017500000000014515146021447023146 0ustar epsilonepsilonfrom .bad import count_to_one # [cyclic-import] def count_to_two(): return count_to_one() + 1 pylint-4.0.5/doc/data/messages/c/consider-using-get/0000775000175000017500000000000015146021447022166 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-get/good.py0000664000175000017500000000014415146021447023467 0ustar epsilonepsilonknights = {"Gallahad": "the pure", "Robin": "the brave"} description = knights.get("Gallahad", "") pylint-4.0.5/doc/data/messages/c/consider-using-get/bad.py0000664000175000017500000000025515146021447023270 0ustar epsilonepsilonknights = {"Gallahad": "the pure", "Robin": "the brave"} if "Gallahad" in knights: # [consider-using-get] DESCRIPTION = knights["Gallahad"] else: DESCRIPTION = "" pylint-4.0.5/doc/data/messages/c/consider-using-any-or-all/0000775000175000017500000000000015146021447023362 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-any-or-all/pylintrc0000664000175000017500000000006215146021447025147 0ustar epsilonepsilon[MAIN] load-plugins=pylint.extensions.for_any_all pylint-4.0.5/doc/data/messages/c/consider-using-any-or-all/bad/0000775000175000017500000000000015146021447024110 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-any-or-all/bad/any_even.py0000664000175000017500000000031215146021447026262 0ustar epsilonepsilondef any_even(items): """Return True if the list contains any even numbers""" for item in items: # [consider-using-any-or-all] if item % 2 == 0: return True return False pylint-4.0.5/doc/data/messages/c/consider-using-any-or-all/bad/all_even.py0000664000175000017500000000031615146021447026247 0ustar epsilonepsilondef all_even(items): """Return True if the list contains all even numbers""" for item in items: # [consider-using-any-or-all] if not item % 2 == 0: return False return True pylint-4.0.5/doc/data/messages/c/consider-using-any-or-all/good/0000775000175000017500000000000015146021447024312 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-any-or-all/good/any_even.py0000664000175000017500000000020115146021447026461 0ustar epsilonepsilondef any_even(items): """Return True if the list contains any even numbers""" return any(item % 2 == 0 for item in items) pylint-4.0.5/doc/data/messages/c/consider-using-any-or-all/good/all_even.py0000664000175000017500000000020115146021447026442 0ustar epsilonepsilondef all_even(items): """Return True if the list contains all even numbers""" return all(item % 2 == 0 for item in items) pylint-4.0.5/doc/data/messages/c/class-variable-slots-conflict/0000775000175000017500000000000015146021447024311 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/class-variable-slots-conflict/good.py0000664000175000017500000000037515146021447025620 0ustar epsilonepsilonclass Person: __slots__ = ("_age", "name") def __init__(self, age, name): self._age = age self.name = name @property def age(self): return self._age def say_hi(self): print(f"Hi, I'm {self.name}.") pylint-4.0.5/doc/data/messages/c/class-variable-slots-conflict/bad.py0000664000175000017500000000057415146021447025417 0ustar epsilonepsilonclass Person: # +1: [class-variable-slots-conflict, class-variable-slots-conflict, class-variable-slots-conflict] __slots__ = ("age", "name", "say_hi") name = None def __init__(self, age, name): self.age = age self.name = name @property def age(self): return self.age def say_hi(self): print(f"Hi, I'm {self.name}.") pylint-4.0.5/doc/data/messages/c/consider-using-with/0000775000175000017500000000000015146021447022362 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-with/good.py0000664000175000017500000000012115146021447023656 0ustar epsilonepsilonwith open("apple.txt", "r", encoding="utf8") as file: contents = file.read() pylint-4.0.5/doc/data/messages/c/consider-using-with/details.rst0000664000175000017500000000077615146021447024553 0ustar epsilonepsilonCalling ``write()`` without using the ``with`` keyword or calling ``close()`` might result in the arguments of ``write()`` not being completely written to the disk, even if the program exits successfully. This message applies to callables of Python's stdlib which can be replaced by a ``with`` statement. It is suppressed in the following cases: - the call is located inside a context manager - the call result is returned from the enclosing function - the call result is used in a ``with`` statement itself pylint-4.0.5/doc/data/messages/c/consider-using-with/related.rst0000664000175000017500000000052415146021447024535 0ustar epsilonepsilon- `Python doc: Reading and writing files `_ - `PEP 343 `_ - `Context managers in Python `_ by John Lekberg - `Rationale `_ pylint-4.0.5/doc/data/messages/c/consider-using-with/bad/0000775000175000017500000000000015146021447023110 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-using-with/bad/close.py0000664000175000017500000000015415146021447024567 0ustar epsilonepsilonfile = open("apple.txt", "r", encoding="utf8") # [consider-using-with] contents = file.read() file.close() pylint-4.0.5/doc/data/messages/c/consider-using-with/bad/not_even_close.py0000664000175000017500000000012315146021447026460 0ustar epsilonepsiloncontents = open("apple.txt", "r", encoding="utf8").read() # [consider-using-with] pylint-4.0.5/doc/data/messages/c/consider-swap-variables/0000775000175000017500000000000015146021447023204 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-swap-variables/good.py0000664000175000017500000000003115146021447024500 0ustar epsilonepsilona = 1 b = 2 a, b = b, a pylint-4.0.5/doc/data/messages/c/consider-swap-variables/bad.py0000664000175000017500000000010215146021447024275 0ustar epsilonepsilona = 1 b = 2 temp = a # [consider-swap-variables] a = b b = temp pylint-4.0.5/doc/data/messages/c/comparison-of-constants/0000775000175000017500000000000015146021447023246 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/comparison-of-constants/good.py0000664000175000017500000000012215146021447024543 0ustar epsilonepsilondef is_the_answer(meaning_of_life: int) -> bool: return meaning_of_life == 42 pylint-4.0.5/doc/data/messages/c/comparison-of-constants/bad.py0000664000175000017500000000011615146021447024344 0ustar epsilonepsilondef is_the_answer() -> bool: return 42 == 42 # [comparison-of-constants] pylint-4.0.5/doc/data/messages/c/consider-ternary-expression/0000775000175000017500000000000015146021447024145 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/consider-ternary-expression/good.py0000664000175000017500000000006515146021447025450 0ustar epsilonepsilonx, y = input(), input() maximum = x if x >= y else y pylint-4.0.5/doc/data/messages/c/consider-ternary-expression/pylintrc0000664000175000017500000000010215146021447025725 0ustar epsilonepsilon[MAIN] load-plugins=pylint.extensions.consider_ternary_expression pylint-4.0.5/doc/data/messages/c/consider-ternary-expression/bad.py0000664000175000017500000000015215146021447025243 0ustar epsilonepsilonx, y = input(), input() if x >= y: # [consider-ternary-expression] maximum = x else: maximum = y pylint-4.0.5/doc/data/messages/c/comparison-with-itself/0000775000175000017500000000000015146021447023067 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/c/comparison-with-itself/good.py0000664000175000017500000000012015146021447024362 0ustar epsilonepsilondef is_an_orange(fruit): an_orange = "orange" return an_orange == fruit pylint-4.0.5/doc/data/messages/c/comparison-with-itself/bad.py0000664000175000017500000000015015146021447024163 0ustar epsilonepsilondef is_an_orange(fruit): an_orange = "orange" return fruit == fruit # [comparison-with-itself] pylint-4.0.5/doc/data/messages/t/0000775000175000017500000000000015146021447016501 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-few-public-methods/0000775000175000017500000000000015146021447022776 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-few-public-methods/bad.py0000664000175000017500000000042015146021447024072 0ustar epsilonepsilonclass Worm: # [too-few-public-methods] def __init__(self, name: str, fruit_of_residence: Fruit): self.name = name self.fruit_of_residence = fruit_of_residence def bore(self): print(f"{self.name} is boring into {self.fruit_of_residence}") pylint-4.0.5/doc/data/messages/t/too-few-public-methods/good/0000775000175000017500000000000015146021447023726 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-few-public-methods/good/function.py0000664000175000017500000000013115146021447026120 0ustar epsilonepsilondef bore(fruit: Fruit, worm_name: str): print(f"{worm_name} is boring into {fruit}") pylint-4.0.5/doc/data/messages/t/too-few-public-methods/good/larger_api.py0000664000175000017500000000050015146021447026400 0ustar epsilonepsilonclass Worm: def __init__(self, name: str, fruit_of_residence: Fruit): self.name = name self.fruit_of_residence = fruit_of_residence def bore(self): print(f"{self.name} is boring into {self.fruit_of_residence}") def wiggle(self): print(f"{self.name} wiggle around wormily.") pylint-4.0.5/doc/data/messages/t/too-few-public-methods/good/dataclass_and_function.py0000664000175000017500000000027715146021447030774 0ustar epsilonepsilonimport dataclasses @dataclasses.dataclass class Worm: name: str fruit_of_residence: Fruit def bore(worm: Worm): print(f"{worm.name} is boring into {worm.fruit_of_residence}") pylint-4.0.5/doc/data/messages/t/trailing-comma-tuple/0000775000175000017500000000000015146021447022533 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/trailing-comma-tuple/good.py0000664000175000017500000000005515146021447024035 0ustar epsilonepsilonCOMPASS = ("north", "south", "east", "west") pylint-4.0.5/doc/data/messages/t/trailing-comma-tuple/bad.py0000664000175000017500000000010615146021447023630 0ustar epsilonepsilonCOMPASS = "north", "south", "east", "west", # [trailing-comma-tuple] pylint-4.0.5/doc/data/messages/t/typevar-double-variance/0000775000175000017500000000000015146021447023231 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/typevar-double-variance/good.py0000664000175000017500000000016615146021447024536 0ustar epsilonepsilonfrom typing import TypeVar T_co = TypeVar("T_co", covariant=True) T_contra = TypeVar("T_contra", contravariant=True) pylint-4.0.5/doc/data/messages/t/typevar-double-variance/bad.py0000664000175000017500000000015615146021447024333 0ustar epsilonepsilonfrom typing import TypeVar T = TypeVar("T", covariant=True, contravariant=True) # [typevar-double-variance] pylint-4.0.5/doc/data/messages/t/too-many-locals/0000775000175000017500000000000015146021447021517 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-locals/good.py0000664000175000017500000000267115146021447023027 0ustar epsilonepsilonfrom typing import NamedTuple from childhood import Child, Sweet class SweetDistrubutionCharacteristics(NamedTuple): number_of_sweets: int number_of_sweet_per_child: int number_of_children: int @property def sweets_given(self): return self.number_of_sweet_per_child * self.number_of_children def handle_sweets(infos): children = [Child(info) for info in infos] characteristics = SweetDistrubutionCharacteristics(87, 5, len(children)) _allocate_sweets_to_children(children, characteristics) financial_impact = _assess_financial_impact(characteristics) print(f"{children} ate {financial_impact}") def _allocate_sweets_to_children( children, characteristics: SweetDistrubutionCharacteristics ) -> None: sweets = [Sweet() * characteristics.number_of_sweets] for child in children: child.give(sweets[characteristics.number_of_sweet_per_child :]) def _assess_financial_impact(characteristics: SweetDistrubutionCharacteristics) -> str: time_to_eat_sweet = 54 money = 45.0 price_of_sweet = 0.42 cost_of_children = characteristics.sweets_given * price_of_sweet remaining_money = money - cost_of_children time_it_took_assuming_parallel_eating = ( time_to_eat_sweet * characteristics.number_of_sweet_per_child ) return ( f"{cost_of_children}¤ of sweets in " f"{time_it_took_assuming_parallel_eating}, you still have {remaining_money}" ) pylint-4.0.5/doc/data/messages/t/too-many-locals/pylintrc0000664000175000017500000000003115146021447023300 0ustar epsilonepsilon[design] max-locals = 11 pylint-4.0.5/doc/data/messages/t/too-many-locals/details.rst0000664000175000017500000000036615146021447023703 0ustar epsilonepsilonHaving too many locals may indicate that you're doing too much in a function and that classes regrouping some attributes could be created. Maybe operations could be separated in multiple functions. Are all your variables really closely related ? pylint-4.0.5/doc/data/messages/t/too-many-locals/bad.py0000664000175000017500000000167215146021447022625 0ustar epsilonepsilonfrom childhood import Child, Sweet def handle_sweets(infos): # [too-many-locals] # Create children children = [Child(info) for info in infos] number_of_sweets = 87 sweets = [Sweet() * number_of_sweets] number_of_sweet_per_child = 5 money = 45.0 sweets_given = 0 time_to_eat_sweet = 54 price_of_sweet = 0.42 # distribute sweet for child in children: sweets_given += number_of_sweet_per_child child.give(sweets[number_of_sweet_per_child:]) # calculate prices cost_of_children = sweets_given * price_of_sweet # Calculate remaining money remaining_money = money - cost_of_children # Calculate time it took time_it_took_assuming_parallel_eating = ( time_to_eat_sweet * number_of_sweet_per_child ) print( f"{children} ate {cost_of_children}¤ of sweets in {time_it_took_assuming_parallel_eating}, " f"you still have {remaining_money}" ) pylint-4.0.5/doc/data/messages/t/too-many-arguments/0000775000175000017500000000000015146021447022247 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-arguments/good.py0000664000175000017500000000040615146021447023551 0ustar epsilonepsilonfrom dataclasses import dataclass @dataclass class ThreeDChessPiece: x: int y: int z: int type: str def three_d_chess_move( white: ThreeDChessPiece, black: ThreeDChessPiece, blue: ThreeDChessPiece, current_player, ): pass pylint-4.0.5/doc/data/messages/t/too-many-arguments/bad.py0000664000175000017500000000036415146021447023352 0ustar epsilonepsilondef three_d_chess_move( # [too-many-arguments] x_white, y_white, z_white, piece_white, x_black, y_black, z_black, piece_black, x_blue, y_blue, z_blue, piece_blue, current_player, ): pass pylint-4.0.5/doc/data/messages/t/too-many-branches/0000775000175000017500000000000015146021447022027 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-branches/good.py0000664000175000017500000000035415146021447023333 0ustar epsilonepsilondef num_to_word(x): return { 0: "zero", 1: "one", 2: "two", 3: "three", 4: "four", 5: "five", 6: "six", 7: "seven", 8: "eight", 9: "nine", }.get(x) pylint-4.0.5/doc/data/messages/t/too-many-branches/pylintrc0000664000175000017500000000002715146021447023615 0ustar epsilonepsilon[main] max-branches=10 pylint-4.0.5/doc/data/messages/t/too-many-branches/bad.py0000664000175000017500000000071515146021447023132 0ustar epsilonepsilondef num_to_word(x): # [too-many-branches] if x == 0: return "zero" elif x == 1: return "one" elif x == 2: return "two" elif x == 3: return "three" elif x == 4: return "four" elif x == 5: return "five" elif x == 6: return "six" elif x == 7: return "seven" elif x == 8: return "eight" elif x == 9: return "nine" else: return None pylint-4.0.5/doc/data/messages/t/too-many-positional-sub-patterns/0000775000175000017500000000000015146021447025050 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-positional-sub-patterns/good.py0000664000175000017500000000043515146021447026354 0ustar epsilonepsilonclass Book: __match_args__ = ("title", "year") def __init__(self, title, year, author): self.title = title self.year = year self.author = author def func(item: Book): match item: case Book("title", 2000, author="author"): ... pylint-4.0.5/doc/data/messages/t/too-many-positional-sub-patterns/bad.py0000664000175000017500000000047415146021447026155 0ustar epsilonepsilonclass Book: __match_args__ = ("title", "year") def __init__(self, title, year, author): self.title = title self.year = year self.author = author def func(item: Book): match item: case Book("title", 2000, "author"): # [too-many-positional-sub-patterns] ... pylint-4.0.5/doc/data/messages/t/too-many-positional-sub-patterns/related.rst0000664000175000017500000000014315146021447027220 0ustar epsilonepsilon- `Python documentation `_ pylint-4.0.5/doc/data/messages/t/truncated-format-string/0000775000175000017500000000000015146021447023264 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/truncated-format-string/good.py0000664000175000017500000000005615146021447024567 0ustar epsilonepsilonPARG_2 = 1 print(f"strange format {PARG_2}") pylint-4.0.5/doc/data/messages/t/truncated-format-string/bad.py0000664000175000017500000000011515146021447024361 0ustar epsilonepsilonPARG_2 = 1 print("strange format %2" % PARG_2) # [truncated-format-string] pylint-4.0.5/doc/data/messages/t/typevar-name-mismatch/0000775000175000017500000000000015146021447022714 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/typevar-name-mismatch/good.py0000664000175000017500000000005515146021447024216 0ustar epsilonepsilonfrom typing import TypeVar T = TypeVar("T") pylint-4.0.5/doc/data/messages/t/typevar-name-mismatch/bad.py0000664000175000017500000000011015146021447024004 0ustar epsilonepsilonfrom typing import TypeVar X = TypeVar("T") # [typevar-name-mismatch] pylint-4.0.5/doc/data/messages/t/trailing-newlines/0000775000175000017500000000000015146021447022134 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/trailing-newlines/good.py0000664000175000017500000000001715146021447023434 0ustar epsilonepsilonprint("apple") pylint-4.0.5/doc/data/messages/t/trailing-newlines/bad.py0000664000175000017500000000012615146021447023233 0ustar epsilonepsilonprint("apple") # The file ends with 2 lines that are empty # +1: [trailing-newlines] pylint-4.0.5/doc/data/messages/t/too-many-star-expressions/0000775000175000017500000000000015146021447023573 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-star-expressions/good.py0000664000175000017500000000007415146021447025076 0ustar epsilonepsilon*sirius_and_arcturus, vega = ["Sirius", "Arcturus", "Vega"] pylint-4.0.5/doc/data/messages/t/too-many-star-expressions/bad.py0000664000175000017500000000013015146021447024665 0ustar epsilonepsilon*stars, *constellations = ["Sirius", "Arcturus", "Vega"] # [too-many-star-expressions] pylint-4.0.5/doc/data/messages/t/typevar-name-incorrect-variance/0000775000175000017500000000000015146021447024665 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/typevar-name-incorrect-variance/good.py0000664000175000017500000000005515146021447026167 0ustar epsilonepsilonfrom typing import TypeVar T = TypeVar("T") pylint-4.0.5/doc/data/messages/t/typevar-name-incorrect-variance/details.rst0000664000175000017500000000017315146021447027045 0ustar epsilonepsilonWhen naming type vars, only use a ``_co`` suffix when indicating covariance or ``_contra`` when indicating contravariance. pylint-4.0.5/doc/data/messages/t/typevar-name-incorrect-variance/bad.py0000664000175000017500000000013015146021447025757 0ustar epsilonepsilonfrom typing import TypeVar T_co = TypeVar("T_co") # [typevar-name-incorrect-variance] pylint-4.0.5/doc/data/messages/t/too-many-instance-attributes/0000775000175000017500000000000015146021447024232 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-instance-attributes/good.py0000664000175000017500000000070415146021447025535 0ustar epsilonepsilonimport dataclasses @dataclasses.dataclass class Worm: name: str type: str color: str class Fruit: def __init__(self): self.name = "Little Apple" self.color = "Bright red" self.vitamins = ["A", "B1"] self.antioxidants = None self.worms = [ Worm(name="Jimmy", type="Codling Moths", color="light brown"), Worm(name="Kim", type="Apple maggot", color="Whitish"), ] pylint-4.0.5/doc/data/messages/t/too-many-instance-attributes/bad.py0000664000175000017500000000104015146021447025325 0ustar epsilonepsilonclass Fruit: # [too-many-instance-attributes] def __init__(self): # max of 7 attributes by default, can be configured self.worm_name = "Jimmy" self.worm_type = "Codling Moths" self.worm_color = "light brown" self.fruit_name = "Little Apple" self.fruit_color = "Bright red" self.fruit_vitamins = ["A", "B1"] self.fruit_antioxidants = None self.secondary_worm_name = "Kim" self.secondary_worm_type = "Apple maggot" self.secondary_worm_color = "Whitish" pylint-4.0.5/doc/data/messages/t/too-few-format-args/0000775000175000017500000000000015146021447022301 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-few-format-args/good.py0000664000175000017500000000011315146021447023576 0ustar epsilonepsilonprint("Today is {0}, so tomorrow will be {1}".format("Monday", "Tuesday")) pylint-4.0.5/doc/data/messages/t/too-few-format-args/bad.py0000664000175000017500000000013115146021447023374 0ustar epsilonepsilonprint("Today is {0}, so tomorrow will be {1}".format("Monday")) # [too-few-format-args] pylint-4.0.5/doc/data/messages/t/too-few-format-args/related.rst0000664000175000017500000000012515146021447024451 0ustar epsilonepsilon- `String Formatting `_ pylint-4.0.5/doc/data/messages/t/too-many-ancestors/0000775000175000017500000000000015146021447022243 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-ancestors/good.py0000664000175000017500000000106215146021447023544 0ustar epsilonepsilonclass Animal: beaver_tailed: bool can_swim: bool has_beak: bool has_fur: bool has_vertebrae: bool lays_egg: bool protected_specie: bool venomous: bool class Invertebrate(Animal): has_vertebrae = False class Vertebrate(Animal): has_vertebrae = True class Mammal(Vertebrate): has_beak = False has_fur = True lays_egg = False venomous = False class Playtypus(Mammal): beaver_tailed = True can_swim = True has_beak = True lays_egg = True protected_specie = True venomous = True pylint-4.0.5/doc/data/messages/t/too-many-ancestors/bad.py0000664000175000017500000000105215146021447023341 0ustar epsilonepsilonclass Animal: ... class BeakyAnimal(Animal): ... class FurryAnimal(Animal): ... class Swimmer(Animal): ... class EggLayer(Animal): ... class VenomousAnimal(Animal): ... class ProtectedSpecie(Animal): ... class BeaverTailedAnimal(Animal): ... class Vertebrate(Animal): ... # max of 7 by default, can be configured # each edge of a diamond inheritance counts class Playtypus( # [too-many-ancestors] BeakyAnimal, FurryAnimal, Swimmer, EggLayer, VenomousAnimal, ProtectedSpecie, BeaverTailedAnimal, Vertebrate, ): pass pylint-4.0.5/doc/data/messages/t/too-complex/0000775000175000017500000000000015146021447020747 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-complex/good.py0000664000175000017500000000153115146021447022251 0ustar epsilonepsilonFRUIT_PRICES = { "apple": 1.1, "pear": 0.8, "banana": 1.2, "mango": 3.5, "peach": 0.5, "melon": 4.9, "orange": 2.0, "strawberry": 2.5, "mandarin": 2.3, "plum": 0.5, "watermelon": 6.4, } DISCOUNTED_FRUITS = ["apple", "watermelon"] def fifty_percent_off(whole): return (float(whole)) * 50 / 100 def get_price(fruit): full_price = FRUIT_PRICES.get(fruit) if fruit in DISCOUNTED_FRUITS: return fifty_percent_off(full_price) else: return full_price def display_fruit_and_price(fruits): for fruit in fruits: print(f"{fruit} ${get_price(fruit) :.2f}") def get_total(fruits): return sum(get_price(f) for f in fruits) fruits_to_buy = ["apple", "orange", "watermelon"] display_fruit_and_price(fruits_to_buy) print(f"Total price is ${get_total(fruits_to_buy):.2f}") pylint-4.0.5/doc/data/messages/t/too-complex/pylintrc0000664000175000017500000000005615146021447022537 0ustar epsilonepsilon[main] load-plugins=pylint.extensions.mccabe pylint-4.0.5/doc/data/messages/t/too-complex/bad.py0000664000175000017500000000232615146021447022052 0ustar epsilonepsilondef fifty_percent_off(whole): return (float(whole)) * 50 / 100 def calculate_sum_and_display_price_of_fruits(*fruits): # [too-complex] # McCabe rating is 13 here (by default 10) shopping_list = [] if "apple" in fruits: v = fifty_percent_off(1.1) shopping_list.append(v) if "pear" in fruits: shopping_list.append(0.8) if "banana" in fruits: shopping_list.append(1.2) if "mango" in fruits: shopping_list.append(3.5) if "peach" in fruits: shopping_list.append(0.5) if "melon" in fruits: shopping_list.append(4.9) if "orange" in fruits: shopping_list.append(2.0) if "strawberry" in fruits: shopping_list.append(2.5) if "mandarin" in fruits: shopping_list.append(2.3) if "plum" in fruits: shopping_list.append(0.5) if "watermelon" in fruits: v = fifty_percent_off(6.4) shopping_list.append(v) combine = zip(fruits, shopping_list) for i in combine: print(f"{i[0]} ${i[1]:.2f}") total = sum(shopping_list) print(f"Total price is ${total:.2f}") fruits_to_buy = ["apple", "orange", "watermelon"] calculate_sum_and_display_price_of_fruits(*fruits_to_buy) pylint-4.0.5/doc/data/messages/t/too-many-positional-arguments/0000775000175000017500000000000015146021447024426 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-positional-arguments/good.py0000664000175000017500000000116315146021447025731 0ustar epsilonepsilondef calculate_drag_force(*, velocity, area, density, drag_coefficient): """This function is 'Keyword only' for all args due to the '*'.""" return 0.5 * drag_coefficient * density * area * velocity**2 # This is now impossible to do and will raise a TypeError: # drag_force = calculate_drag_force(30, 2.5, 1.225, 0.47) # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # TypeError: calculate_drag_force() takes 0 positional arguments but 4 were given # And this is the only way to call 'calculate_drag_force' drag_force = calculate_drag_force( velocity=30, area=2.5, density=1.225, drag_coefficient=0.47 ) pylint-4.0.5/doc/data/messages/t/too-many-positional-arguments/pylintrc0000664000175000017500000000004415146021447026213 0ustar epsilonepsilon[DESIGN] max-positional-arguments=3 pylint-4.0.5/doc/data/messages/t/too-many-positional-arguments/details.rst0000664000175000017500000000107615146021447026611 0ustar epsilonepsilonGood function signatures don’t have many positional parameters. For almost all interfaces, comprehensibility suffers beyond a handful of arguments. Positional arguments work well for cases where the use cases are self-evident, such as unittest's ``assertEqual(first, second, "assert msg")`` or ``zip(fruits, vegetables)``. There are a few exceptions where four or more positional parameters make sense, for example ``rgba(1.0, 0.5, 0.3, 1.0)``, because it uses a very well-known and well-established convention, and using keywords all the time would be a waste of time. pylint-4.0.5/doc/data/messages/t/too-many-positional-arguments/bad.py0000664000175000017500000000046715146021447025535 0ustar epsilonepsilon# +1: [too-many-positional-arguments] def calculate_drag_force(velocity, area, density, drag_coefficient): """Each argument is positional-or-keyword unless a `/` or `*` is present.""" return 0.5 * drag_coefficient * density * area * velocity**2 drag_force = calculate_drag_force(30, 2.5, 1.225, 0.47) pylint-4.0.5/doc/data/messages/t/too-many-positional-arguments/related.rst0000664000175000017500000000015315146021447026577 0ustar epsilonepsilon- `Special parameters in python `_ pylint-4.0.5/doc/data/messages/t/too-many-nested-blocks/0000775000175000017500000000000015146021447022777 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-nested-blocks/good.py0000664000175000017500000000034515146021447024303 0ustar epsilonepsilondef correct_fruits(fruits): if len(fruits) > 1 and "apple" in fruits and "orange" in fruits: count = fruits["orange"] if count % 2 and "kiwi" in fruits and count == 2: return True return False pylint-4.0.5/doc/data/messages/t/too-many-nested-blocks/bad.py0000664000175000017500000000054115146021447024077 0ustar epsilonepsilondef correct_fruits(fruits): if len(fruits) > 1: # [too-many-nested-blocks] if "apple" in fruits: if "orange" in fruits: count = fruits["orange"] if count % 2: if "kiwi" in fruits: if count == 2: return True return False pylint-4.0.5/doc/data/messages/t/too-many-format-args/0000775000175000017500000000000015146021447022464 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-format-args/good.py0000664000175000017500000000011315146021447023761 0ustar epsilonepsilonprint("Today is {0}, so tomorrow will be {1}".format("Monday", "Tuesday")) pylint-4.0.5/doc/data/messages/t/too-many-format-args/bad.py0000664000175000017500000000016515146021447023566 0ustar epsilonepsilon# +1: [too-many-format-args] print("Today is {0}, so tomorrow will be {1}".format("Monday", "Tuesday", "Wednesday")) pylint-4.0.5/doc/data/messages/t/too-many-format-args/related.rst0000664000175000017500000000012515146021447024634 0ustar epsilonepsilon- `String Formatting `_ pylint-4.0.5/doc/data/messages/t/too-many-lines/0000775000175000017500000000000015146021447021354 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-lines/pylintrc0000664000175000017500000000003315146021447023137 0ustar epsilonepsilon[main] max-module-lines=15 pylint-4.0.5/doc/data/messages/t/too-many-lines/details.rst0000664000175000017500000000200515146021447023530 0ustar epsilonepsilonWhen a module has too many lines it can make it difficult to read and understand. There might be performance issue while editing the file because the IDE must parse more code. You need more expertise to navigate the file properly (go to a particular line when debugging, or search for a specific code construct, instead of navigating by clicking and scrolling) This measure is a proxy for higher cyclomatic complexity that you might not be calculating if you're not using ``load-plugins=pylint.extensions.mccabe,``. Cyclomatic complexity is slower to compute, but also a more fine grained measure than raw SLOC. In particular, you can't make the code less readable by making a very complex one liner if you're using cyclomatic complexity. The example simplify the code, but it's not always possible. Most of the time bursting the file by creating a package with the same API is the only solution. Anticipating and creating the file from the get go will permit to have the same end result with a better version control history. pylint-4.0.5/doc/data/messages/t/too-many-lines/bad.py0000664000175000017500000000064415146021447022460 0ustar epsilonepsilondef is_palindrome(string): # [too-many-lines] left_pos = 0 right_pos = len(string) - 1 while right_pos >= left_pos: if not string[left_pos] == string[right_pos]: return False left_pos += 1 right_pos -= 1 return True def main(): print(is_palindrome("aza")) print(is_palindrome("racecar")) print(is_palindrome("trigger")) print(is_palindrome("ogre")) pylint-4.0.5/doc/data/messages/t/too-many-lines/good/0000775000175000017500000000000015146021447022304 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-lines/good/main.py0000664000175000017500000000022415146021447023600 0ustar epsilonepsilonfrom is_palindrome import is_palindrome def main(): for string in ["aza", "racecar", "trigger", "ogre"]: print(is_palindrome(string)) pylint-4.0.5/doc/data/messages/t/too-many-lines/good/is_palindrome.py0000664000175000017500000000007515146021447025505 0ustar epsilonepsilondef is_palindrome(string): return string == string[::-1] pylint-4.0.5/doc/data/messages/t/too-many-lines/good/__init__.py0000664000175000017500000000014315146021447024413 0ustar epsilonepsilon__all__ = ["is_palindrome", "main"] from is_palindrome import is_palindrome from main import main pylint-4.0.5/doc/data/messages/t/too-many-boolean-expressions/0000775000175000017500000000000015146021447024241 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-boolean-expressions/good.py0000664000175000017500000000016315146021447025543 0ustar epsilonepsilondef can_be_divided_by_two_and_are_not_zero(x, y, z): if all(i and i % 2 == 0 for i in [x, y, z]): pass pylint-4.0.5/doc/data/messages/t/too-many-boolean-expressions/bad.py0000664000175000017500000000040015146021447025333 0ustar epsilonepsilondef can_be_divided_by_two_and_are_not_zero(x, y, z): # Maximum number of boolean expressions in an if statement (by default 5) # +1: [too-many-boolean-expressions] if (x and y and z) and (x % 2 == 0 and y % 2 == 0 and z % 2 == 0): pass pylint-4.0.5/doc/data/messages/t/too-many-public-methods/0000775000175000017500000000000015146021447023161 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-public-methods/good.py0000664000175000017500000000125215146021447024463 0ustar epsilonepsilonclass LaserBeam: def __init__(self): pass def fire(self): pass def activate_super(self): pass def destroy_planet(self): pass class Shield: def deploy(self): pass class Missile: def launch(self): pass class SpaceInvaders: def __init__(self): self.laser = LaserBeam() self.shield = Shield() self.missile = Missile() def summon_mothership(self): pass def destroy_planet(self): pass def teleport(self): pass def invoke_aliens(self): pass def invade_earth(self): pass def takeover_galaxy(self): pass pylint-4.0.5/doc/data/messages/t/too-many-public-methods/pylintrc0000664000175000017500000000003415146021447024745 0ustar epsilonepsilon[main] max-public-methods=7 pylint-4.0.5/doc/data/messages/t/too-many-public-methods/details.rst0000664000175000017500000000053115146021447025337 0ustar epsilonepsilonHaving too many public methods is an indication that you might not be respecting the Single-responsibility principle (S of SOLID). The class should have only one reason to change, but in the example the spaceship has at least 4 persons that could ask for change to it (laser manager, shield manager, missile manager, teleportation officer...). pylint-4.0.5/doc/data/messages/t/too-many-public-methods/bad.py0000664000175000017500000000102015146021447024252 0ustar epsilonepsilonclass SpaceInvaders: # [too-many-public-methods] def __init__(self): pass def fire_laser_beam(self): pass def deploy_shield(self): pass def launch_missile(self): pass def activate_super_laser(self): pass def summon_mothership(self): pass def destroy_planet(self): pass def teleport(self): pass def invoke_aliens(self): pass def invade_earth(self): pass def takeover_galaxy(self): pass pylint-4.0.5/doc/data/messages/t/too-many-public-methods/related.rst0000664000175000017500000000014515146021447025333 0ustar epsilonepsilon- `Single-responsibility principle `_ pylint-4.0.5/doc/data/messages/t/try-except-raise/0000775000175000017500000000000015146021447021706 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/try-except-raise/details.rst0000664000175000017500000000107015146021447024063 0ustar epsilonepsilonThere is a legitimate use case for re-raising immediately. E.g. with the following inheritance tree:: +-- ArithmeticError +-- FloatingPointError +-- OverflowError +-- ZeroDivisionError The following code shows valid case for re-raising exception immediately:: def execute_calculation(a, b): try: return some_calculation(a, b) except ZeroDivisionError: raise except ArithmeticError: return float('nan') The pylint is able to detect this case and does not produce error. pylint-4.0.5/doc/data/messages/t/try-except-raise/bad.py0000664000175000017500000000011615146021447023004 0ustar epsilonepsilontry: 1 / 0 except ZeroDivisionError as e: # [try-except-raise] raise pylint-4.0.5/doc/data/messages/t/try-except-raise/good/0000775000175000017500000000000015146021447022636 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/try-except-raise/good/remove_try_except.py0000664000175000017500000000006215146021447026751 0ustar epsilonepsilon# The try except might be removed entirely: 1 / 0 pylint-4.0.5/doc/data/messages/t/try-except-raise/good/specialized_exception.py0000664000175000017500000000024715146021447027565 0ustar epsilonepsilon# Another more detailed exception can be raised: try: 1 / 0 except ZeroDivisionError as e: raise ValueError("The area of the rectangle cannot be zero") from e pylint-4.0.5/doc/data/messages/t/too-many-return-statements/0000775000175000017500000000000015146021447023746 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-return-statements/good.py0000664000175000017500000000031015146021447025242 0ustar epsilonepsilonNUMBERS_TO_STRINGS = { 1: "one", 2: "two", 3: "three", 4: "four", 5: "five", 6: "six", 7: "seven", } def to_string(x): return f"This is {NUMBERS_TO_STRINGS.get(x)}." pylint-4.0.5/doc/data/messages/t/too-many-return-statements/bad.py0000664000175000017500000000064015146021447025046 0ustar epsilonepsilondef to_string(x): # [too-many-return-statements] # max of 6 by default, can be configured if x == 1: return "This is one." if x == 2: return "This is two." if x == 3: return "This is three." if x == 4: return "This is four." if x == 5: return "This is five." if x == 6: return "This is six." if x == 7: return "This is seven." pylint-4.0.5/doc/data/messages/t/too-many-try-statements/0000775000175000017500000000000015146021447023245 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-try-statements/good.py0000664000175000017500000000027415146021447024552 0ustar epsilonepsilonFRUITS = {"apple": 1, "orange": 10} def pick_fruit(name): try: count = FRUITS[name] except KeyError: return count += 1 print(f"Got fruit count {count}") pylint-4.0.5/doc/data/messages/t/too-many-try-statements/pylintrc0000664000175000017500000000007015146021447025031 0ustar epsilonepsilon[MAIN] load-plugins=pylint.extensions.broad_try_clause, pylint-4.0.5/doc/data/messages/t/too-many-try-statements/bad.py0000664000175000017500000000034015146021447024342 0ustar epsilonepsilonFRUITS = {"apple": 1, "orange": 10} def pick_fruit(name): try: # [too-many-try-statements] count = FRUITS[name] count += 1 print(f"Got fruit count {count}") except KeyError: return pylint-4.0.5/doc/data/messages/t/too-many-function-args/0000775000175000017500000000000015146021447023021 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-function-args/good.py0000664000175000017500000000020615146021447024321 0ustar epsilonepsilonclass Fruit: def __init__(self, color, name): self.color = color self.name = name apple = Fruit("red", "apple") pylint-4.0.5/doc/data/messages/t/too-many-function-args/bad.py0000664000175000017500000000021615146021447024120 0ustar epsilonepsilonclass Fruit: def __init__(self, color): self.color = color apple = Fruit("red", "apple", [1, 2, 3]) # [too-many-function-args] pylint-4.0.5/doc/data/messages/t/trailing-whitespace/0000775000175000017500000000000015146021447022444 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/trailing-whitespace/good.py0000664000175000017500000000001715146021447023744 0ustar epsilonepsilonprint("Hello") pylint-4.0.5/doc/data/messages/t/trailing-whitespace/bad.py0000664000175000017500000000015415146021447023544 0ustar epsilonepsilonprint("Hello") # [trailing-whitespace] # ^^^ trailing whitespaces pylint-4.0.5/doc/data/messages/t/too-many-statements/0000775000175000017500000000000015146021447022431 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/t/too-many-statements/good.py0000664000175000017500000000165415146021447023741 0ustar epsilonepsilonimport random def distribute_candies(children: list[Child], candies_per_child: int): total_candies = len(children) * candies_per_child eaten_candies = 0 for child in children: eaten_candies += _distribute_candies_to_child(candies_per_child, child) return eaten_candies, total_candies def _distribute_candies_to_child(candies_per_child: int, child: Child): # If a child eat more than 1 candies they're going to eat all # the candies for sure eaten_for_child = random.choices([0, 1, candies_per_child]) print(f"Child {child} gets {candies_per_child} candies and eat {eaten_for_child}") remaining_candies_for_children = child.eat_candies(eaten_for_child) if remaining_candies_for_children == 0: print(f"All the candies have been devoured by {child.name}!") else: print(f"{child.name} still have {remaining_candies_for_children} candies left.") return eaten_for_child pylint-4.0.5/doc/data/messages/t/too-many-statements/pylintrc0000664000175000017500000000003215146021447024213 0ustar epsilonepsilon[DESIGN] max-statements=7 pylint-4.0.5/doc/data/messages/t/too-many-statements/bad.py0000664000175000017500000000302015146021447023524 0ustar epsilonepsilonimport random def distribute_candies( # [too-many-statements] children: list[Child], candies_per_child: int ): # This function is a masterpiece of code that embodies the epitome of efficiency # it's also an essential part of a high-priority project with extremely tight deadlines # and there is absolutely no time to refactor it to make it more concise. # The lead developer on the project, who has decades of experience, # has personally reviewed this implementation and deemed it good enough as it is. # The person writing this code has a demanding job and multiple responsibilities, # and simply does not have the luxury of spending time making this code more readable. total_candies = len(children) * candies_per_child eaten_candies = 0 # Counting candies given to each child for child in children: # If a child eat more than 1 candies they're going to eat all # the candies for sure eaten_for_child = random.choices([0, 1, candies_per_child]) print( f"Child {child} gets {candies_per_child} candies and eat {eaten_for_child}" ) remaining_candies_for_children = child.eat_candies(eaten_for_child) if remaining_candies_for_children == 0: print(f"All the candies have been devoured by {child.name}!") else: print( f"{child.name} still have {remaining_candies_for_children} candies left." ) eaten_candies += eaten_for_child return eaten_candies, total_candies pylint-4.0.5/doc/data/messages/l/0000775000175000017500000000000015146021447016471 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/l/line-too-long/0000775000175000017500000000000015146021447021154 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/l/line-too-long/good.py0000664000175000017500000000020415146021447022452 0ustar epsilonepsilonFRUIT = [ "apricot", "blackcurrant", "cantaloupe", "dragon fruit", "elderberry", "fig", "grapefruit", ] pylint-4.0.5/doc/data/messages/l/line-too-long/pylintrc0000664000175000017500000000003315146021447022737 0ustar epsilonepsilon[MAIN] max-line-length=100 pylint-4.0.5/doc/data/messages/l/line-too-long/details.rst0000664000175000017500000000065515146021447023341 0ustar epsilonepsilonPragma controls such as ``# pylint: disable=all`` are not counted toward line length for the purposes of this message. If you attempt to disable this message via ``# pylint: disable=line-too-long`` in a module with no code, you may receive a message for ``useless-suppression``. This is a false positive of ``useless-suppression`` we can't easily fix. See https://github.com/pylint-dev/pylint/issues/3368 for more information. pylint-4.0.5/doc/data/messages/l/line-too-long/bad.py0000664000175000017500000000017515146021447022257 0ustar epsilonepsilon# +1: [line-too-long] FRUIT = ["apricot", "blackcurrant", "cantaloupe", "dragon fruit", "elderberry", "fig", "grapefruit", ] pylint-4.0.5/doc/data/messages/l/logging-format-interpolation/0000775000175000017500000000000015146021447024272 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/l/logging-format-interpolation/good.py0000664000175000017500000000011415146021447025570 0ustar epsilonepsilonimport logging import sys logging.error("Python version: %s", sys.version) pylint-4.0.5/doc/data/messages/l/logging-format-interpolation/details.rst0000664000175000017500000000025115146021447026447 0ustar epsilonepsilonAnother reasonable option is to use f-string. If you want to do that, you need to enable ``logging-format-interpolation`` and disable ``logging-fstring-interpolation``. pylint-4.0.5/doc/data/messages/l/logging-format-interpolation/bad.py0000664000175000017500000000017015146021447025370 0ustar epsilonepsilonimport logging import sys # +1: [logging-format-interpolation] logging.error("Python version: {}".format(sys.version)) pylint-4.0.5/doc/data/messages/l/logging-format-interpolation/related.rst0000664000175000017500000000027715146021447026452 0ustar epsilonepsilon- `logging variable data `_ - `Rationale for the message on stackoverflow `_ pylint-4.0.5/doc/data/messages/l/logging-format-truncated/0000775000175000017500000000000015146021447023374 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/l/logging-format-truncated/good.py0000664000175000017500000000011615146021447024674 0ustar epsilonepsilonimport logging import sys logging.warning("Python version: %s", sys.version) pylint-4.0.5/doc/data/messages/l/logging-format-truncated/bad.py0000664000175000017500000000015315146021447024473 0ustar epsilonepsilonimport logging import sys logging.warning("Python version: %", sys.version) # [logging-format-truncated] pylint-4.0.5/doc/data/messages/l/logging-unsupported-format/0000775000175000017500000000000015146021447023773 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/l/logging-unsupported-format/good.py0000664000175000017500000000007215146021447025274 0ustar epsilonepsilonimport logging logging.info("%s %s !", "Hello", "World") pylint-4.0.5/doc/data/messages/l/logging-unsupported-format/bad.py0000664000175000017500000000013215146021447025067 0ustar epsilonepsilonimport logging logging.info("%s %y !", "Hello", "World") # [logging-unsupported-format] pylint-4.0.5/doc/data/messages/l/logging-too-many-args/0000775000175000017500000000000015146021447022612 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/l/logging-too-many-args/good.py0000664000175000017500000000017415146021447024116 0ustar epsilonepsilonimport logging try: function() except Exception as e: logging.error("%s error occurred: %s", type(e), e) raise pylint-4.0.5/doc/data/messages/l/logging-too-many-args/bad.py0000664000175000017500000000022415146021447023710 0ustar epsilonepsilonimport logging try: function() except Exception as e: logging.error("Error occurred: %s", type(e), e) # [logging-too-many-args] raise pylint-4.0.5/doc/data/messages/l/logging-fstring-interpolation/0000775000175000017500000000000015146021447024456 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/l/logging-fstring-interpolation/good.py0000664000175000017500000000011415146021447025754 0ustar epsilonepsilonimport logging import sys logging.error("Python version: %s", sys.version) pylint-4.0.5/doc/data/messages/l/logging-fstring-interpolation/details.rst0000664000175000017500000000015315146021447026634 0ustar epsilonepsilonThis message permits to allow f-string in logging and still be warned of ``logging-format-interpolation``. pylint-4.0.5/doc/data/messages/l/logging-fstring-interpolation/bad.py0000664000175000017500000000015615146021447025560 0ustar epsilonepsilonimport logging import sys logging.error(f"Python version: {sys.version}") # [logging-fstring-interpolation] pylint-4.0.5/doc/data/messages/l/logging-fstring-interpolation/related.rst0000664000175000017500000000023615146021447026631 0ustar epsilonepsilon- `logging variable data `_ - `Rationale `_ pylint-4.0.5/doc/data/messages/l/lost-exception/0000775000175000017500000000000015146021447021446 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/l/lost-exception/good.py0000664000175000017500000000053215146021447022750 0ustar epsilonepsilonclass FasterThanTheSpeedOfLightError(ZeroDivisionError): def __init__(self): super().__init__("You can't go faster than the speed of light !") def calculate_speed(distance: float, time: float) -> float: try: return distance / time except ZeroDivisionError as e: raise FasterThanTheSpeedOfLightError() from e pylint-4.0.5/doc/data/messages/l/lost-exception/bad.py0000664000175000017500000000062415146021447022550 0ustar epsilonepsilonclass FasterThanTheSpeedOfLightError(ZeroDivisionError): def __init__(self): super().__init__("You can't go faster than the speed of light !") def calculate_speed(distance: float, time: float) -> float: try: return distance / time except ZeroDivisionError as e: raise FasterThanTheSpeedOfLightError() from e finally: return 299792458 # [lost-exception] pylint-4.0.5/doc/data/messages/l/logging-too-few-args/0000775000175000017500000000000015146021447022427 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/l/logging-too-few-args/good.py0000664000175000017500000000017415146021447023733 0ustar epsilonepsilonimport logging try: function() except Exception as e: logging.error("%s error occurred: %s", type(e), e) raise pylint-4.0.5/doc/data/messages/l/logging-too-few-args/bad.py0000664000175000017500000000021515146021447023525 0ustar epsilonepsilonimport logging try: function() except Exception as e: logging.error("%s error occurred: %s", e) # [logging-too-few-args] raise pylint-4.0.5/doc/data/messages/l/logging-not-lazy/0000775000175000017500000000000015146021447021672 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/l/logging-not-lazy/good.py0000664000175000017500000000016015146021447023171 0ustar epsilonepsilonimport logging try: function() except Exception as e: logging.error("Error occurred: %s", e) raise pylint-4.0.5/doc/data/messages/l/logging-not-lazy/details.rst0000664000175000017500000000023615146021447024052 0ustar epsilonepsilonAnother reasonable option is to use f-strings. If you want to do that, you need to enable ``logging-not-lazy`` and disable ``logging-fstring-interpolation``. pylint-4.0.5/doc/data/messages/l/logging-not-lazy/bad.py0000664000175000017500000000020715146021447022771 0ustar epsilonepsilonimport logging try: function() except Exception as e: logging.error("Error occurred: %s" % e) # [logging-not-lazy] raise pylint-4.0.5/doc/data/messages/l/logging-not-lazy/related.rst0000664000175000017500000000027715146021447024052 0ustar epsilonepsilon- `Logging variable data `_ - `Rationale for the message on stackoverflow `_ pylint-4.0.5/doc/data/messages/l/locally-disabled/0000775000175000017500000000000015146021447021675 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/l/locally-disabled/good.py0000664000175000017500000000031115146021447023172 0ustar epsilonepsilondef wizard_spells(spell_book): for spell in spell_book: print(f"Abracadabra! {spell}.") spell_list = ["Levitation", "Invisibility", "Fireball", "Teleportation"] wizard_spells(spell_list) pylint-4.0.5/doc/data/messages/l/locally-disabled/bad.py0000664000175000017500000000040415146021447022773 0ustar epsilonepsilondef wizard_spells(spell_book): # pylint: disable=maybe-no-member # [locally-disabled] for spell in spell_book: print(f"Abracadabra! {spell}.") spell_list = ["Levitation", "Invisibility", "Fireball", "Teleportation"] wizard_spells(spell_list) pylint-4.0.5/doc/data/messages/l/literal-comparison/0000775000175000017500000000000015146021447022275 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/l/literal-comparison/good.py0000664000175000017500000000006615146021447023601 0ustar epsilonepsilondef is_an_orange(fruit): return fruit == "orange" pylint-4.0.5/doc/data/messages/l/literal-comparison/bad.py0000664000175000017500000000011615146021447023373 0ustar epsilonepsilondef is_an_orange(fruit): return fruit is "orange" # [literal-comparison] pylint-4.0.5/doc/data/messages/l/literal-comparison/related.rst0000664000175000017500000000014315146021447024445 0ustar epsilonepsilon- `Comparison operations in Python `_ pylint-4.0.5/doc/data/messages/b/0000775000175000017500000000000015146021447016457 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/break-in-finally/0000775000175000017500000000000015146021447021603 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/break-in-finally/good.py0000664000175000017500000000013615146021447023105 0ustar epsilonepsilonwhile True: try: pass except ValueError: pass else: break pylint-4.0.5/doc/data/messages/b/break-in-finally/bad.py0000664000175000017500000000012315146021447022677 0ustar epsilonepsilonwhile True: try: pass finally: break # [break-in-finally] pylint-4.0.5/doc/data/messages/b/break-in-finally/related.rst0000664000175000017500000000033115146021447023752 0ustar epsilonepsilon- `Python 3 docs 'finally' clause `_ - `PEP 765 - Disallow return/break/continue that exit a finally block `_ pylint-4.0.5/doc/data/messages/b/bad-plugin-value/0000775000175000017500000000000015146021447021613 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-plugin-value/details.rst0000664000175000017500000000062415146021447023774 0ustar epsilonepsilonOne of your pylint plugins cannot be loaded. There's nothing to change in your code, but your pylint configuration or installation has an issue. For example, there might be a typo. The following config:: [MAIN] load-plugins = pylint.extensions.bad_biultin Should be:: [MAIN] load-plugins = pylint.extensions.bad_builtin Or the plugin you added is not importable in your environment. pylint-4.0.5/doc/data/messages/b/boolean-datetime/0000775000175000017500000000000015146021447021670 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/boolean-datetime/good.py0000664000175000017500000000031415146021447023170 0ustar epsilonepsilonimport datetime time_now_utc = datetime.datetime.now(tz=datetime.UTC).time() if time_now_utc > datetime.time(6, 0): print("Daytime!") if time_now_utc < datetime.time(6, 0): print("Nighttime!") pylint-4.0.5/doc/data/messages/b/boolean-datetime/pylintrc0000664000175000017500000000002615146021447023455 0ustar epsilonepsilon[main] py-version=3.4 pylint-4.0.5/doc/data/messages/b/boolean-datetime/bad.py0000664000175000017500000000025215146021447022767 0ustar epsilonepsilonimport datetime if datetime.time(): # [boolean-datetime] print("It is time.") if datetime.datetime.now().time(): # [boolean-datetime] print("Now or never.") pylint-4.0.5/doc/data/messages/b/boolean-datetime/related.rst0000664000175000017500000000007515146021447024044 0ustar epsilonepsilon- `Python bug tracker `_ pylint-4.0.5/doc/data/messages/b/bad-format-string-key/0000775000175000017500000000000015146021447022565 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-format-string-key/good.py0000664000175000017500000000006115146021447024064 0ustar epsilonepsilonprint("%(one)d, %(two)d" % {"one": 1, "two": 2}) pylint-4.0.5/doc/data/messages/b/bad-format-string-key/details.rst0000664000175000017500000000060515146021447024745 0ustar epsilonepsilonThis check only works for old-style string formatting using the '%' operator. This check only works if the dictionary with the values to be formatted is defined inline. Passing a variable will not trigger the check as the other keys in this dictionary may be used in other contexts, while an inline defined dictionary is clearly only intended to hold the values that should be formatted. pylint-4.0.5/doc/data/messages/b/bad-format-string-key/bad.py0000664000175000017500000000007715146021447023671 0ustar epsilonepsilonprint("%(one)d" % {"one": 1, 2: 2}) # [bad-format-string-key] pylint-4.0.5/doc/data/messages/b/bad-chained-comparison/0000775000175000017500000000000015146021447022746 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-chained-comparison/related.rst0000664000175000017500000000013415146021447025116 0ustar epsilonepsilon- `Comparison Chaining `_ pylint-4.0.5/doc/data/messages/b/bad-chained-comparison/bad/0000775000175000017500000000000015146021447023474 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-chained-comparison/bad/xor.py0000664000175000017500000000033615146021447024660 0ustar epsilonepsilondef xor_check(*, left=None, right=None): if left is None != right is None: # [bad-chained-comparison] raise ValueError( "Either both left= and right= need to be provided or none should." ) pylint-4.0.5/doc/data/messages/b/bad-chained-comparison/bad/parrot.py0000664000175000017500000000037615146021447025363 0ustar epsilonepsilonshop = { # animal: (specie, descriptions) "parrot": ("Norvegian blue", ("restin'", "remarkable", "beautiful plumage")), } if "parrot" in shop is "restin'": # [bad-chained-comparison] print("Hellooooo, Pooolllllyyy ! WAAAAKEEY, WAKKEEEY !") pylint-4.0.5/doc/data/messages/b/bad-chained-comparison/good/0000775000175000017500000000000015146021447023676 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-chained-comparison/good/xor.py0000664000175000017500000000030615146021447025057 0ustar epsilonepsilondef xor_check(*, left=None, right=None): if (left is None) != (right is None): raise ValueError( "Either both left= and right= need to be provided or none should." ) pylint-4.0.5/doc/data/messages/b/bad-chained-comparison/good/parrot.py0000664000175000017500000000037015146021447025557 0ustar epsilonepsilonshop = { # animal: (specie, descriptions) "parrot": ("Norvegian blue", ("restin'", "remarkable", "beautiful plumage")), } if "parrot" in shop and "restin'" in shop["parrot"][1]: print("Hellooooo, Pooolllllyyy ! WAAAAKEEY, WAKKEEEY !") pylint-4.0.5/doc/data/messages/b/broad-exception-raised/0000775000175000017500000000000015146021447023007 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/broad-exception-raised/good.py0000664000175000017500000000022215146021447024305 0ustar epsilonepsilondef small_apple(apple, length): if len(apple) < length: raise ValueError("Apple is too small!") print(f"{apple} is proper size.") pylint-4.0.5/doc/data/messages/b/broad-exception-raised/bad.py0000664000175000017500000000025515146021447024111 0ustar epsilonepsilondef small_apple(apple, length): if len(apple) < length: raise Exception("Apple is too small!") # [broad-exception-raised] print(f"{apple} is proper size.") pylint-4.0.5/doc/data/messages/b/broad-exception-raised/related.rst0000664000175000017500000000015015146021447025155 0ustar epsilonepsilon- `Programming recommendation in PEP8 `_ pylint-4.0.5/doc/data/messages/b/bad-staticmethod-argument/0000775000175000017500000000000015146021447023513 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-staticmethod-argument/good.py0000664000175000017500000000007715146021447025021 0ustar epsilonepsilonclass Wolf: @staticmethod def eat(sheep): pass pylint-4.0.5/doc/data/messages/b/bad-staticmethod-argument/bad.py0000664000175000017500000000013515146021447024612 0ustar epsilonepsilonclass Wolf: @staticmethod def eat(self): # [bad-staticmethod-argument] pass pylint-4.0.5/doc/data/messages/b/bad-configuration-section/0000775000175000017500000000000015146021447023514 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-configuration-section/details.rst0000664000175000017500000000023715146021447025675 0ustar epsilonepsilonThis error was raised when we encountered an unexpected value type in a toml configuration between pylint 2.12 and pylint 2.14 (before the argparse refactor). pylint-4.0.5/doc/data/messages/b/bad-string-format-type/0000775000175000017500000000000015146021447022756 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-string-format-type/good.py0000664000175000017500000000002015146021447024250 0ustar epsilonepsilonprint("%d" % 1) pylint-4.0.5/doc/data/messages/b/bad-string-format-type/details.rst0000664000175000017500000000027315146021447025137 0ustar epsilonepsilonThis check is currently only active for "old-style" string formatting as seen in the examples. See `Issue #6085 `_ for more information. pylint-4.0.5/doc/data/messages/b/bad-string-format-type/bad.py0000664000175000017500000000005615146021447024057 0ustar epsilonepsilonprint("%d" % "1") # [bad-string-format-type] pylint-4.0.5/doc/data/messages/b/bad-string-format-type/related.rst0000664000175000017500000000017715146021447025135 0ustar epsilonepsilon- `Format String Syntax `_ - `PyFormat `_ pylint-4.0.5/doc/data/messages/b/bad-format-character/0000775000175000017500000000000015146021447022425 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-format-character/good.py0000664000175000017500000000004415146021447023725 0ustar epsilonepsilonprint("%s %s" % ("hello", "world")) pylint-4.0.5/doc/data/messages/b/bad-format-character/details.rst0000664000175000017500000000027315146021447024606 0ustar epsilonepsilonThis check is currently only active for "old-style" string formatting as seen in the examples. See `Issue #6085 `_ for more information. pylint-4.0.5/doc/data/messages/b/bad-format-character/bad.py0000664000175000017500000000007615146021447023530 0ustar epsilonepsilonprint("%s %z" % ("hello", "world")) # [bad-format-character] pylint-4.0.5/doc/data/messages/b/bad-format-character/related.rst0000664000175000017500000000017715146021447024604 0ustar epsilonepsilon- `Format String Syntax `_ - `PyFormat `_ pylint-4.0.5/doc/data/messages/b/bad-mcs-method-argument/0000775000175000017500000000000015146021447023063 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-mcs-method-argument/good.py0000664000175000017500000000006215146021447024363 0ustar epsilonepsilonclass Meta(type): def func(cls): pass pylint-4.0.5/doc/data/messages/b/bad-mcs-method-argument/bad.py0000664000175000017500000000012015146021447024154 0ustar epsilonepsilonclass Meta(type): def func(some): # [bad-mcs-method-argument] pass pylint-4.0.5/doc/data/messages/b/bad-mcs-classmethod-argument/0000775000175000017500000000000015146021447024111 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-mcs-classmethod-argument/good.py0000664000175000017500000000010215146021447025404 0ustar epsilonepsilonclass Meta(type): @classmethod def foo(mcs): pass pylint-4.0.5/doc/data/messages/b/bad-mcs-classmethod-argument/bad.py0000664000175000017500000000014515146021447025211 0ustar epsilonepsilonclass Meta(type): @classmethod def foo(some): # [bad-mcs-classmethod-argument] pass pylint-4.0.5/doc/data/messages/b/bad-format-string/0000775000175000017500000000000015146021447021777 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-format-string/good.py0000664000175000017500000000005215146021447023276 0ustar epsilonepsilonprint("{a[0]} + {a[1]}".format(a=[0, 1])) pylint-4.0.5/doc/data/messages/b/bad-format-string/bad.py0000664000175000017500000000007715146021447023103 0ustar epsilonepsilonprint("{a[0] + a[1]}".format(a=[0, 1])) # [bad-format-string] pylint-4.0.5/doc/data/messages/b/bad-format-string/related.rst0000664000175000017500000000017715146021447024156 0ustar epsilonepsilon- `Format String Syntax `_ - `PyFormat `_ pylint-4.0.5/doc/data/messages/b/broken-noreturn/0000775000175000017500000000000015146021447021611 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/broken-noreturn/good.py0000664000175000017500000000023215146021447023110 0ustar epsilonepsilonfrom typing import NoReturn def exploding_apple(apple) -> NoReturn: print(f"{apple} is about to explode") raise Exception("{apple} exploded !") pylint-4.0.5/doc/data/messages/b/broken-noreturn/pylintrc0000664000175000017500000000007415146021447023401 0ustar epsilonepsilon[main] py-version=3.7 load-plugins=pylint.extensions.typing pylint-4.0.5/doc/data/messages/b/broken-noreturn/bad.py0000664000175000017500000000023115146021447022705 0ustar epsilonepsilonfrom typing import NoReturn, Union def exploding_apple(apple) -> Union[None, NoReturn]: # [broken-noreturn] print(f"{apple} is about to explode") pylint-4.0.5/doc/data/messages/b/bad-classmethod-argument/0000775000175000017500000000000015146021447023331 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-classmethod-argument/good.py0000664000175000017500000000011615146021447024631 0ustar epsilonepsilonclass Klass: @classmethod def get_instance(cls): return cls() pylint-4.0.5/doc/data/messages/b/bad-classmethod-argument/bad.py0000664000175000017500000000015615146021447024433 0ustar epsilonepsilonclass Klass: @classmethod def get_instance(self): # [bad-classmethod-argument] return self() pylint-4.0.5/doc/data/messages/b/bad-reversed-sequence/0000775000175000017500000000000015146021447022630 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-reversed-sequence/good.py0000664000175000017500000000002715146021447024131 0ustar epsilonepsilonreversed([1, 2, 3, 4]) pylint-4.0.5/doc/data/messages/b/bad-reversed-sequence/bad.py0000664000175000017500000000006215146021447023726 0ustar epsilonepsilonreversed({1, 2, 3, 4}) # [bad-reversed-sequence] pylint-4.0.5/doc/data/messages/b/bidirectional-unicode/0000775000175000017500000000000015146021447022713 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bidirectional-unicode/good.py0000664000175000017500000000003415146021447024212 0ustar epsilonepsilonexample = "x[U+2194]" * 100 pylint-4.0.5/doc/data/messages/b/bidirectional-unicode/bad.py0000664000175000017500000000011615146021447024011 0ustar epsilonepsilon# +1: [bidirectional-unicode] example = "x‏" * 100 # "‏x" is assigned pylint-4.0.5/doc/data/messages/b/bad-super-call/0000775000175000017500000000000015146021447021252 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-super-call/good.py0000664000175000017500000000020215146021447022546 0ustar epsilonepsilonclass Animal: pass class Tree: pass class Cat(Animal): def __init__(self): super(Animal, self).__init__() pylint-4.0.5/doc/data/messages/b/bad-super-call/details.rst0000664000175000017500000000070015146021447023426 0ustar epsilonepsilonIn Python 2.7, ``super()`` has to be called with its own class and ``self`` as arguments (``super(Cat, self)``), which can lead to a mix up of parent and child class in the code. In Python 3 the recommended way is to call ``super()`` without arguments (see also ``super-with-arguments``). One exception is calling ``super()`` on a non-direct parent class. This can be used to get a method other than the default method returned by the ``mro()``. pylint-4.0.5/doc/data/messages/b/bad-super-call/bad.py0000664000175000017500000000027315146021447022354 0ustar epsilonepsilonclass Animal: pass class Tree: pass class Cat(Animal): def __init__(self): super(Tree, self).__init__() # [bad-super-call] super(Animal, self).__init__() pylint-4.0.5/doc/data/messages/b/bad-super-call/related.rst0000664000175000017500000000013015146021447023416 0ustar epsilonepsilon- `Documentation for super() `_ pylint-4.0.5/doc/data/messages/b/bad-open-mode/0000775000175000017500000000000015146021447021066 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-open-mode/good.py0000664000175000017500000000014715146021447022372 0ustar epsilonepsilondef open_and_get_content(file_path): with open(file_path, "r") as file: return file.read() pylint-4.0.5/doc/data/messages/b/bad-open-mode/bad.py0000664000175000017500000000017415146021447022170 0ustar epsilonepsilondef open_and_get_content(file_path): with open(file_path, "rwx") as file: # [bad-open-mode] return file.read() pylint-4.0.5/doc/data/messages/b/bad-exception-cause/0000775000175000017500000000000015146021447022277 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-exception-cause/good.py0000664000175000017500000000031215146021447023575 0ustar epsilonepsilondef divide(x, y): result = 0 try: result = x / y except ZeroDivisionError as exc: raise ValueError(f"Division by zero when dividing {x} by {y} !") from exc return result pylint-4.0.5/doc/data/messages/b/bad-exception-cause/bad.py0000664000175000017500000000035215146021447023377 0ustar epsilonepsilondef divide(x, y): result = 0 try: result = x / y except ZeroDivisionError: # +1: [bad-exception-cause] raise ValueError(f"Division by zero when dividing {x} by {y} !") from result return result pylint-4.0.5/doc/data/messages/b/bad-exception-cause/related.rst0000664000175000017500000000032315146021447024447 0ustar epsilonepsilon- `The raise statement `_ - `Explicit Exception Chaining `_ per PEP 3134 pylint-4.0.5/doc/data/messages/b/bad-indentation/0000775000175000017500000000000015146021447021517 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-indentation/good.py0000664000175000017500000000003515146021447023017 0ustar epsilonepsilonif input(): print("yes") pylint-4.0.5/doc/data/messages/b/bad-indentation/details.rst0000664000175000017500000000012715146021447023676 0ustar epsilonepsilonThe option ``--indent-string`` can be used to set the indentation unit for this check. pylint-4.0.5/doc/data/messages/b/bad-indentation/bad.py0000664000175000017500000000006115146021447022614 0ustar epsilonepsilonif input(): print('yes') # [bad-indentation] pylint-4.0.5/doc/data/messages/b/bad-inline-option/0000775000175000017500000000000015146021447021767 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-inline-option/good.py0000664000175000017500000000004015146021447023263 0ustar epsilonepsilon# pylint: disable=line-too-long pylint-4.0.5/doc/data/messages/b/bad-inline-option/bad.py0000664000175000017500000000007015146021447023064 0ustar epsilonepsilon# 2:[bad-inline-option] # pylint: disable line-too-long pylint-4.0.5/doc/data/messages/b/bad-builtin/0000775000175000017500000000000015146021447020651 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-builtin/good.py0000664000175000017500000000006415146021447022153 0ustar epsilonepsilonnumbers = [2 * x for x in [1, 2, 3]] print(numbers) pylint-4.0.5/doc/data/messages/b/bad-builtin/pylintrc0000664000175000017500000000006415146021447022440 0ustar epsilonepsilon[MAIN] load-plugins = pylint.extensions.bad_builtin pylint-4.0.5/doc/data/messages/b/bad-builtin/bad.py0000664000175000017500000000012015146021447021742 0ustar epsilonepsilonnumbers = list(map(lambda x: 2 * x, [1, 2, 3])) # [bad-builtin] print(numbers) pylint-4.0.5/doc/data/messages/b/bare-except/0000775000175000017500000000000015146021447020656 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bare-except/good.py0000664000175000017500000000014115146021447022154 0ustar epsilonepsilontry: import platform_specific_module except ImportError: platform_specific_module = None pylint-4.0.5/doc/data/messages/b/bare-except/details.rst0000664000175000017500000000057015146021447023037 0ustar epsilonepsilonA good rule of thumb is to limit use of bare ‘except’ clauses to two cases: - If the exception handler will be printing out or logging the traceback; at least the user will be aware that an error has occurred. - If the code needs to do some cleanup work, but then lets the exception propagate upwards with raise. ``try...finally`` can be a better way to handle this case. pylint-4.0.5/doc/data/messages/b/bare-except/bad.py0000664000175000017500000000014615146021447021757 0ustar epsilonepsilontry: import platform_specific_module except: # [bare-except] platform_specific_module = None pylint-4.0.5/doc/data/messages/b/bare-except/related.rst0000664000175000017500000000043515146021447023032 0ustar epsilonepsilon- `Programming recommendation in PEP8 `_ - `PEP 760 – No More Bare Excepts (Rejected) `_ - `Discussion about PEP 760 `_ pylint-4.0.5/doc/data/messages/b/bad-file-encoding/0000775000175000017500000000000015146021447021706 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-file-encoding/good.py0000664000175000017500000000000015146021447023176 0ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-file-encoding/bad.py0000664000175000017500000000005015146021447023001 0ustar epsilonepsilon# coding: latin_1 # [bad-file-encoding] pylint-4.0.5/doc/data/messages/b/broad-exception-caught/0000775000175000017500000000000015146021447023013 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/broad-exception-caught/good.py0000664000175000017500000000014115146021447024311 0ustar epsilonepsilontry: import platform_specific_module except ImportError: platform_specific_module = None pylint-4.0.5/doc/data/messages/b/broad-exception-caught/details.rst0000664000175000017500000000037615146021447025200 0ustar epsilonepsilonFor example, you're trying to import a library with required system dependencies and you catch everything instead of only import errors, you will miss the error message telling you, that your code could work if you had installed the system dependencies. pylint-4.0.5/doc/data/messages/b/broad-exception-caught/bad.py0000664000175000017500000000017315146021447024114 0ustar epsilonepsilontry: import platform_specific_module except Exception: # [broad-exception-caught] platform_specific_module = None pylint-4.0.5/doc/data/messages/b/broad-exception-caught/related.rst0000664000175000017500000000016615146021447025170 0ustar epsilonepsilon- `Should I always specify an exception type in 'except' statements? `_ pylint-4.0.5/doc/data/messages/b/bad-thread-instantiation/0000775000175000017500000000000015146021447023334 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-thread-instantiation/good.py0000664000175000017500000000020615146021447024634 0ustar epsilonepsilonimport threading def thread_target(n): print(n**2) thread = threading.Thread(target=thread_target, args=(10,)) thread.start() pylint-4.0.5/doc/data/messages/b/bad-thread-instantiation/bad.py0000664000175000017500000000022015146021447024426 0ustar epsilonepsilonimport threading def thread_target(n): print(n**2) thread = threading.Thread(lambda: None) # [bad-thread-instantiation] thread.start() pylint-4.0.5/doc/data/messages/b/bad-dunder-name/0000775000175000017500000000000015146021447021402 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-dunder-name/good.py0000664000175000017500000000014015146021447022677 0ustar epsilonepsilonclass Apples: def __init__(self): pass def hello(self): print("hello") pylint-4.0.5/doc/data/messages/b/bad-dunder-name/pylintrc0000664000175000017500000000005515146021447023171 0ustar epsilonepsilon[MAIN] load-plugins=pylint.extensions.dunder pylint-4.0.5/doc/data/messages/b/bad-dunder-name/bad.py0000664000175000017500000000021415146021447022477 0ustar epsilonepsilonclass Apples: def _init_(self): # [bad-dunder-name] pass def __hello__(self): # [bad-dunder-name] print("hello") pylint-4.0.5/doc/data/messages/b/bad-docstring-quotes/0000775000175000017500000000000015146021447022515 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-docstring-quotes/good.py0000664000175000017500000000005315146021447024015 0ustar epsilonepsilondef foo(): """Docstring.""" return pylint-4.0.5/doc/data/messages/b/bad-docstring-quotes/pylintrc0000664000175000017500000000005715146021447024306 0ustar epsilonepsilon[main] load-plugins=pylint.extensions.docstyle pylint-4.0.5/doc/data/messages/b/bad-docstring-quotes/details.rst0000664000175000017500000000014415146021447024673 0ustar epsilonepsilonFrom `PEP 257`: "For consistency, always use ``"""triple double quotes"""`` around docstrings." pylint-4.0.5/doc/data/messages/b/bad-docstring-quotes/bad.py0000664000175000017500000000010115146021447023605 0ustar epsilonepsilondef foo(): # [bad-docstring-quotes] "Docstring." return pylint-4.0.5/doc/data/messages/b/bad-docstring-quotes/related.rst0000664000175000017500000000013115146021447024662 0ustar epsilonepsilon- `PEP 257 – Docstring Conventions `_ pylint-4.0.5/doc/data/messages/b/bad-str-strip-call/0000775000175000017500000000000015146021447022063 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-str-strip-call/details.rst0000664000175000017500000000076515146021447024252 0ustar epsilonepsilonA common misconception is that ``str.strip('Hello')`` removes the *substring* ``'Hello'`` from the beginning and end of the string. This is **not** the case. From the `documentation `_: > The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped Duplicated characters in the ``str.strip`` call, besides not having any effect on the actual result, may indicate this misunderstanding. pylint-4.0.5/doc/data/messages/b/bad-str-strip-call/related.rst0000664000175000017500000000016315146021447024235 0ustar epsilonepsilon- Documentation: `str.strip([chars]) `_ pylint-4.0.5/doc/data/messages/b/bad-str-strip-call/bad/0000775000175000017500000000000015146021447022611 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-str-strip-call/bad/hello_world.py0000664000175000017500000000010415146021447025470 0ustar epsilonepsilon"Hello World".strip("Hello") # [bad-str-strip-call] # >>> ' World' pylint-4.0.5/doc/data/messages/b/bad-str-strip-call/bad/remove_abc_from_both_side.py0000664000175000017500000000010715146021447030326 0ustar epsilonepsilon"abcbc def bacabc".strip("abcbc ") # [bad-str-strip-call] # >>> 'def' pylint-4.0.5/doc/data/messages/b/bad-str-strip-call/good/0000775000175000017500000000000015146021447023013 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-str-strip-call/good/hello_world.py0000664000175000017500000000005315146021447025675 0ustar epsilonepsilon"Hello World".strip("Helo") # >>> ' World' pylint-4.0.5/doc/data/messages/b/bad-str-strip-call/good/remove_abc_from_both_side.py0000664000175000017500000000005515146021447030532 0ustar epsilonepsilon"abcbc def bacabc".strip("abc ") # >>> 'def' pylint-4.0.5/doc/data/messages/b/bare-name-capture-pattern/0000775000175000017500000000000015146021447023422 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bare-name-capture-pattern/good.py0000664000175000017500000000050215146021447024721 0ustar epsilonepsilonfrom enum import Enum class Color(Enum): RED = 0 GREEN = 1 BLUE = 2 def func(color: Color) -> None: match color: case Color.RED: print("I see red!") case Color.GREEN: print("Grass is green") case Color.BLUE: print("I'm feeling the blues :(") pylint-4.0.5/doc/data/messages/b/bare-name-capture-pattern/bad.py0000664000175000017500000000045015146021447024521 0ustar epsilonepsilonred = 0 green = 1 blue = 2 def func(color): match color: case red: # [bare-name-capture-pattern] print("I see red!") case green: # [bare-name-capture-pattern] print("Grass is green") case blue: print("I'm feeling the blues :(") pylint-4.0.5/doc/data/messages/b/bare-name-capture-pattern/related.rst0000664000175000017500000000012615146021447025573 0ustar epsilonepsilon- `PEP 636 `_ pylint-4.0.5/doc/data/messages/b/binary-op-exception/0000775000175000017500000000000015146021447022353 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/binary-op-exception/good.py0000664000175000017500000000010015146021447023644 0ustar epsilonepsilontry: 1 / 0 except (ZeroDivisionError, ValueError): pass pylint-4.0.5/doc/data/messages/b/binary-op-exception/bad.py0000664000175000017500000000013115146021447023446 0ustar epsilonepsilontry: 1 / 0 except ZeroDivisionError or ValueError: # [binary-op-exception] pass pylint-4.0.5/doc/data/messages/b/broken-collections-callable/0000775000175000017500000000000015146021447024010 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/broken-collections-callable/good.py0000664000175000017500000000013315146021447025307 0ustar epsilonepsilonfrom typing import Callable, Optional def func() -> Optional[Callable[[int], None]]: ... pylint-4.0.5/doc/data/messages/b/broken-collections-callable/pylintrc0000664000175000017500000000007415146021447025600 0ustar epsilonepsilon[main] py-version=3.9 load-plugins=pylint.extensions.typing pylint-4.0.5/doc/data/messages/b/broken-collections-callable/bad.py0000664000175000017500000000023315146021447025106 0ustar epsilonepsilonfrom collections.abc import Callable from typing import Optional def func() -> Optional[Callable[[int], None]]: # [broken-collections-callable] ... pylint-4.0.5/doc/data/messages/b/broken-collections-callable/related.rst0000664000175000017500000000006415146021447026162 0ustar epsilonepsilon- `bpo-42965 `_ pylint-4.0.5/doc/data/messages/b/bad-except-order/0000775000175000017500000000000015146021447021604 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/b/bad-except-order/good.py0000664000175000017500000000012515146021447023104 0ustar epsilonepsilontry: print(int(input())) except TypeError: raise except Exception: raise pylint-4.0.5/doc/data/messages/b/bad-except-order/bad.py0000664000175000017500000000032715146021447022706 0ustar epsilonepsilontry: print(int(input())) except Exception: raise except TypeError: # [bad-except-order] # This block cannot be reached since TypeError exception # is caught by previous exception handler. raise pylint-4.0.5/doc/data/messages/o/0000775000175000017500000000000015146021447016474 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/o/overridden-final-method/0000775000175000017500000000000015146021447023202 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/o/overridden-final-method/good.py0000664000175000017500000000024415146021447024504 0ustar epsilonepsilonfrom typing import final class Animal: @final def can_breathe(self): return True class Cat(Animal): def can_purr(self): return True pylint-4.0.5/doc/data/messages/o/overridden-final-method/pylintrc0000664000175000017500000000002615146021447024767 0ustar epsilonepsilon[MAIN] py-version=3.8 pylint-4.0.5/doc/data/messages/o/overridden-final-method/details.rst0000664000175000017500000000006615146021447025363 0ustar epsilonepsilonThe message can't be emitted when using Python < 3.8. pylint-4.0.5/doc/data/messages/o/overridden-final-method/bad.py0000664000175000017500000000027515146021447024306 0ustar epsilonepsilonfrom typing import final class Animal: @final def can_breathe(self): return True class Cat(Animal): def can_breathe(self): # [overridden-final-method] pass pylint-4.0.5/doc/data/messages/o/overridden-final-method/related.rst0000664000175000017500000000006115146021447025351 0ustar epsilonepsilon- `PEP 591 `_ pylint-4.0.5/doc/data/messages/o/overlapping-except/0000775000175000017500000000000015146021447022310 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/o/overlapping-except/pylintrc0000664000175000017500000000007615146021447024102 0ustar epsilonepsilon[MAIN] load-plugins=pylint.extensions.overlapping_exceptions, pylint-4.0.5/doc/data/messages/o/overlapping-except/bad.py0000664000175000017500000000027615146021447023415 0ustar epsilonepsilondef divide_x_by_y(x: float, y: float): try: print(x / y) except (ArithmeticError, FloatingPointError) as e: # [overlapping-except] print(f"There was an issue: {e}") pylint-4.0.5/doc/data/messages/o/overlapping-except/related.rst0000664000175000017500000000014115146021447024456 0ustar epsilonepsilon- `Exception hierarchy `_ pylint-4.0.5/doc/data/messages/o/overlapping-except/good/0000775000175000017500000000000015146021447023240 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/o/overlapping-except/good/only_generic.py0000664000175000017500000000033315146021447026266 0ustar epsilonepsilondef divide_x_by_y(x: float, y: float): try: print(x / y) except ArithmeticError as e: print( f"There was an OverflowError, a ZeroDivisionError or a FloatingPointError: {e}" ) pylint-4.0.5/doc/data/messages/o/overlapping-except/good/less_generic_first.py0000664000175000017500000000051115146021447027460 0ustar epsilonepsilondef divide_x_by_y(x: float, y: float): try: print(x / y) except FloatingPointError as e: print(f"There was a FloatingPointError: {e}") except ArithmeticError as e: # FloatingPointError were already caught at this point print(f"There was an OverflowError or a ZeroDivisionError: {e}") pylint-4.0.5/doc/data/messages/g/0000775000175000017500000000000015146021447016464 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/g/global-variable-not-assigned/0000775000175000017500000000000015146021447024100 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/g/global-variable-not-assigned/good.py0000664000175000017500000000013315146021447025377 0ustar epsilonepsilonTOMATO = "black cherry" def update_tomato(): global TOMATO TOMATO = "moneymaker" pylint-4.0.5/doc/data/messages/g/global-variable-not-assigned/bad.py0000664000175000017500000000016515146021447025202 0ustar epsilonepsilonTOMATO = "black cherry" def update_tomato(): global TOMATO # [global-variable-not-assigned] print(TOMATO) pylint-4.0.5/doc/data/messages/g/global-statement/0000775000175000017500000000000015146021447021726 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/g/global-statement/good.py0000664000175000017500000000011315146021447023223 0ustar epsilonepsilonvar = 1 def foo(): print(var) return 10 var = foo() print(var) pylint-4.0.5/doc/data/messages/g/global-statement/bad.py0000664000175000017500000000015115146021447023023 0ustar epsilonepsilonvar = 1 def foo(): global var # [global-statement] var = 10 print(var) foo() print(var) pylint-4.0.5/doc/data/messages/g/global-variable-undefined/0000775000175000017500000000000015146021447023446 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/g/global-variable-undefined/good.py0000664000175000017500000000013315146021447024745 0ustar epsilonepsilonTOMATO = "black cherry" def update_tomato(): global TOMATO TOMATO = "moneymaker" pylint-4.0.5/doc/data/messages/g/global-variable-undefined/bad.py0000664000175000017500000000014015146021447024541 0ustar epsilonepsilondef update_tomato(): global TOMATO # [global-variable-undefined] TOMATO = "moneymaker" pylint-4.0.5/doc/data/messages/g/global-at-module-level/0000775000175000017500000000000015146021447022716 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/g/global-at-module-level/good.py0000664000175000017500000000001315146021447024212 0ustar epsilonepsilonprice = 25 pylint-4.0.5/doc/data/messages/g/global-at-module-level/bad.py0000664000175000017500000000006415146021447024016 0ustar epsilonepsilonprice = 25 global price # [global-at-module-level] pylint-4.0.5/doc/data/messages/g/global-at-module-level/related.rst0000664000175000017500000000051115146021447025065 0ustar epsilonepsilon- `Official Python FAQ - global and local `_ - `PEP 3104 - Access to Names in Outer Scopes `_ - `Python global statement `_ pylint-4.0.5/doc/data/messages/f/0000775000175000017500000000000015146021447016463 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/format-combined-specification/0000775000175000017500000000000015146021447024347 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/format-combined-specification/bad.py0000664000175000017500000000011415146021447025443 0ustar epsilonepsilonprint("{} {1}".format("hello", "world")) # [format-combined-specification] pylint-4.0.5/doc/data/messages/f/format-combined-specification/good/0000775000175000017500000000000015146021447025277 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/format-combined-specification/good/index_formatting.py0000664000175000017500000000005215146021447031207 0ustar epsilonepsilonprint("{0} {1}".format("hello", "world")) pylint-4.0.5/doc/data/messages/f/format-combined-specification/good/order_formatting.py0000664000175000017500000000005015146021447031211 0ustar epsilonepsilonprint("{} {}".format("hello", "world")) pylint-4.0.5/doc/data/messages/f/file-ignored/0000775000175000017500000000000015146021447021027 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/file-ignored/good.py0000664000175000017500000000000015146021447022317 0ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/file-ignored/details.rst0000664000175000017500000000011515146021447023203 0ustar epsilonepsilonThere's no checks at all for a file if it starts by ``# pylint: skip-file``. pylint-4.0.5/doc/data/messages/f/file-ignored/bad.py0000664000175000017500000000005115146021447022123 0ustar epsilonepsilon# pylint: skip-file # -1: [file-ignored] pylint-4.0.5/doc/data/messages/f/format-string-without-interpolation/0000775000175000017500000000000015146021447025645 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/format-string-without-interpolation/good.py0000664000175000017500000000003615146021447027146 0ustar epsilonepsilonprint("number: {}".format(1)) pylint-4.0.5/doc/data/messages/f/format-string-without-interpolation/bad.py0000664000175000017500000000010315146021447026737 0ustar epsilonepsilonprint("number".format(1)) # [format-string-without-interpolation] pylint-4.0.5/doc/data/messages/f/format-needs-mapping/0000775000175000017500000000000015146021447022500 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/format-needs-mapping/good.py0000664000175000017500000000005015146021447023775 0ustar epsilonepsilonprint("%(x)d %(y)d" % {"x": 1, "y": 2}) pylint-4.0.5/doc/data/messages/f/format-needs-mapping/bad.py0000664000175000017500000000007015146021447023575 0ustar epsilonepsilonprint("%(x)d %(y)d" % [1, 2]) # [format-needs-mapping] pylint-4.0.5/doc/data/messages/f/fixme/0000775000175000017500000000000015146021447017573 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/fixme/details.rst0000664000175000017500000000031315146021447021747 0ustar epsilonepsilonYou can use regular expressions and the ``notes-rgx`` option to create some constraints for this message. See `the following issue `_ for some examples. pylint-4.0.5/doc/data/messages/f/fixme/bad.py0000664000175000017500000000006415146021447020673 0ustar epsilonepsilon# TODO: We should fix this at some point # [fixme] pylint-4.0.5/doc/data/messages/f/fixme/good/0000775000175000017500000000000015146021447020523 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/fixme/good/fixed.py0000664000175000017500000000006215146021447022172 0ustar epsilonepsilon# The issue was fixed: no longer need the comment pylint-4.0.5/doc/data/messages/f/fixme/good/bug_tracker.py0000664000175000017500000000010515146021447023361 0ustar epsilonepsilon# The issue was added to the bug tracker: no longer need the comment pylint-4.0.5/doc/data/messages/f/fixme/good/no_fix.py0000664000175000017500000000007415146021447022360 0ustar epsilonepsilon# We no longer want to fix this: no longer need the comment pylint-4.0.5/doc/data/messages/f/function-redefined/0000775000175000017500000000000015146021447022233 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/function-redefined/good.py0000664000175000017500000000003215146021447023530 0ustar epsilonepsilondef get_email(): pass pylint-4.0.5/doc/data/messages/f/function-redefined/bad.py0000664000175000017500000000011615146021447023331 0ustar epsilonepsilondef get_email(): pass def get_email(): # [function-redefined] pass pylint-4.0.5/doc/data/messages/f/fatal/0000775000175000017500000000000015146021447017552 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/fatal/details.rst0000664000175000017500000000014315146021447021727 0ustar epsilonepsilonThis is a message linked to an internal problem in pylint. There's nothing to change in your code. pylint-4.0.5/doc/data/messages/f/forgotten-debug-statement/0000775000175000017500000000000015146021447023560 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/forgotten-debug-statement/good.py0000664000175000017500000000042515146021447025063 0ustar epsilonepsilondef find_the_treasure(clues): for clue in clues: if "treasure" in clue: return True return False treasure_hunt = [ "Dead Man's Chest", "X marks the spot", "The treasure is buried near the palm tree", ] find_the_treasure(treasure_hunt) pylint-4.0.5/doc/data/messages/f/forgotten-debug-statement/bad.py0000664000175000017500000000053115146021447024657 0ustar epsilonepsilonimport pdb def find_the_treasure(clues): for clue in clues: pdb.set_trace() # [forgotten-debug-statement] if "treasure" in clue: return True return False treasure_hunt = [ "Dead Man's Chest", "X marks the spot", "The treasure is buried near the palm tree", ] find_the_treasure(treasure_hunt) pylint-4.0.5/doc/data/messages/f/f-string-without-interpolation/0000775000175000017500000000000015146021447024602 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/f/f-string-without-interpolation/good.py0000664000175000017500000000005215146021447026101 0ustar epsilonepsilonx = 1 y = 2 print(f"{x} + {y} = {x + y}") pylint-4.0.5/doc/data/messages/f/f-string-without-interpolation/bad.py0000664000175000017500000000011015146021447025672 0ustar epsilonepsilonx = 1 y = 2 print(f"x + y = x + y") # [f-string-without-interpolation] pylint-4.0.5/doc/data/messages/i/0000775000175000017500000000000015146021447016466 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-slots-object/0000775000175000017500000000000015146021447022522 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-slots-object/good.py0000664000175000017500000000006215146021447024022 0ustar epsilonepsilonclass Person: __slots__ = ("name", "surname") pylint-4.0.5/doc/data/messages/i/invalid-slots-object/bad.py0000664000175000017500000000010415146021447023615 0ustar epsilonepsilonclass Person: __slots__ = ("name", 3) # [invalid-slots-object] pylint-4.0.5/doc/data/messages/i/invalid-slots-object/related.rst0000664000175000017500000000013415146021447024672 0ustar epsilonepsilon- `Documentation for __slots__ `_ pylint-4.0.5/doc/data/messages/i/invalid-slice-step/0000775000175000017500000000000015146021447022162 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-slice-step/good.py0000664000175000017500000000005515146021447023464 0ustar epsilonepsilonLETTERS = ["a", "b", "c", "d"] LETTERS[::2] pylint-4.0.5/doc/data/messages/i/invalid-slice-step/bad.py0000664000175000017500000000010515146021447023256 0ustar epsilonepsilonLETTERS = ["a", "b", "c", "d"] LETTERS[::0] # [invalid-slice-step] pylint-4.0.5/doc/data/messages/i/implicit-str-concat/0000775000175000017500000000000015146021447022353 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/implicit-str-concat/details.rst0000664000175000017500000000211415146021447024530 0ustar epsilonepsilonBy default, detection of implicit string concatenation of line jumps is disabled. Hence the following code will not trigger this rule: .. code-block:: python SEQ = ('a', 'b' 'c') In order to detect this case, you must enable `check-str-concat-over-line-jumps`: .. code-block:: toml [STRING_CONSTANT] check-str-concat-over-line-jumps = true However, the drawback of this setting is that it will trigger false positive for string parameters passed on multiple lines in function calls: .. code-block:: python warnings.warn( "rotate() is deprecated and will be removed in a future release. " "Use the rotation() context manager instead.", DeprecationWarning, stacklevel=3, ) No message will be emitted, though, if you clarify the wanted concatenation with parentheses: .. code-block:: python warnings.warn( ( "rotate() is deprecated and will be removed in a future release. " "Use the rotation() context manager instead." ), DeprecationWarning, stacklevel=3, ) pylint-4.0.5/doc/data/messages/i/implicit-str-concat/bad/0000775000175000017500000000000015146021447023101 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/implicit-str-concat/bad/open.py0000664000175000017500000000011615146021447024412 0ustar epsilonepsilonwith open("hello.txt" "r") as f: # [implicit-str-concat] print(f.read()) pylint-4.0.5/doc/data/messages/i/implicit-str-concat/bad/list.py0000664000175000017500000000004715146021447024427 0ustar epsilonepsilonx = ["a" "b"] # [implicit-str-concat] pylint-4.0.5/doc/data/messages/i/implicit-str-concat/good/0000775000175000017500000000000015146021447023303 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/implicit-str-concat/good/open.py0000664000175000017500000000006615146021447024620 0ustar epsilonepsilonwith open("hello.txt", "r") as f: print(f.read()) pylint-4.0.5/doc/data/messages/i/implicit-str-concat/good/list.py0000664000175000017500000000001715146021447024626 0ustar epsilonepsilonx = ["a", "b"] pylint-4.0.5/doc/data/messages/i/inherit-non-class/0000775000175000017500000000000015146021447022023 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/inherit-non-class/good.py0000664000175000017500000000006215146021447023323 0ustar epsilonepsilonclass Fruit: def __bool__(self): pass pylint-4.0.5/doc/data/messages/i/inherit-non-class/bad.py0000664000175000017500000000006315146021447023122 0ustar epsilonepsilonclass Fruit(bool): # [inherit-non-class] pass pylint-4.0.5/doc/data/messages/i/invalid-all-format/0000775000175000017500000000000015146021447022150 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-all-format/good.py0000664000175000017500000000004115146021447023445 0ustar epsilonepsilon__all__ = ("CONST",) CONST = 42 pylint-4.0.5/doc/data/messages/i/invalid-all-format/bad.py0000664000175000017500000000006615146021447023252 0ustar epsilonepsilon__all__ = "CONST" # [invalid-all-format] CONST = 42 pylint-4.0.5/doc/data/messages/i/import-outside-toplevel/0000775000175000017500000000000015146021447023302 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/import-outside-toplevel/good.py0000664000175000017500000000010515146021447024600 0ustar epsilonepsilonimport sys def print_python_version(): print(sys.version_info) pylint-4.0.5/doc/data/messages/i/import-outside-toplevel/bad.py0000664000175000017500000000014515146021447024402 0ustar epsilonepsilondef print_python_version(): import sys # [import-outside-toplevel] print(sys.version_info) pylint-4.0.5/doc/data/messages/i/invalid-getnewargs-returned/0000775000175000017500000000000015146021447024106 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-getnewargs-returned/good.py0000664000175000017500000000017515146021447025413 0ustar epsilonepsilonclass CustomGetNewArgs: """__getnewargs__ returns """ def __getnewargs__(self): return (1, 2) pylint-4.0.5/doc/data/messages/i/invalid-getnewargs-returned/bad.py0000664000175000017500000000022515146021447025205 0ustar epsilonepsilonclass CustomGetNewArgs: """__getnewargs__ returns an integer""" def __getnewargs__(self): # [invalid-getnewargs-returned] return 1 pylint-4.0.5/doc/data/messages/i/import-error/0000775000175000017500000000000015146021447021127 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/import-error/good.py0000664000175000017500000000003115146021447022423 0ustar epsilonepsilonfrom pathlib import Path pylint-4.0.5/doc/data/messages/i/import-error/details.rst0000664000175000017500000000030015146021447023277 0ustar epsilonepsilonThis can happen if you're importing a package that is not installed in your environment, or if you made a typo. The solution is to install the package via pip/setup.py/wheel or fix the typo. pylint-4.0.5/doc/data/messages/i/import-error/bad.py0000664000175000017500000000005215146021447022224 0ustar epsilonepsilonfrom patlib import Path # [import-error] pylint-4.0.5/doc/data/messages/i/implicit-flag-alias/0000775000175000017500000000000015146021447022276 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/implicit-flag-alias/good.py0000664000175000017500000000014615146021447023601 0ustar epsilonepsilonfrom enum import IntFlag class FilePermissions(IntFlag): READ = 1 WRITE = 2 EXECUTE = 4 pylint-4.0.5/doc/data/messages/i/implicit-flag-alias/bad.py0000664000175000017500000000017715146021447023403 0ustar epsilonepsilonfrom enum import IntFlag class FilePermissions(IntFlag): READ = 1 WRITE = 2 EXECUTE = 3 # [implicit-flag-alias] pylint-4.0.5/doc/data/messages/i/import-private-name/0000775000175000017500000000000015146021447022366 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/import-private-name/good.py0000664000175000017500000000031115146021447023663 0ustar epsilonepsilon"""Private import can be used as type annotations.""" from argparse import _SubParsersAction def add_sub_parser(sub_parsers: _SubParsersAction): sub_parsers.add_parser("my_subparser") # ... pylint-4.0.5/doc/data/messages/i/import-private-name/pylintrc0000664000175000017500000000006715146021447024160 0ustar epsilonepsilon[main] load-plugins = pylint.extensions.private_import pylint-4.0.5/doc/data/messages/i/import-private-name/details.rst0000664000175000017500000000020315146021447024540 0ustar epsilonepsilonUsing private imports expose you to unexpected breaking changes for any version bump of your dependencies, even in patch versions. pylint-4.0.5/doc/data/messages/i/import-private-name/bad.py0000664000175000017500000000033715146021447023471 0ustar epsilonepsilonfrom argparse import _AttributeHolder, _SubParsersAction # [import-private-name] attr_holder = _AttributeHolder() def add_sub_parser(sub_parsers: _SubParsersAction): sub_parsers.add_parser("my_subparser") # ... pylint-4.0.5/doc/data/messages/i/invalid-character-esc/0000775000175000017500000000000015146021447022616 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-character-esc/good.py0000664000175000017500000000004715146021447024121 0ustar epsilonepsilonSTRING = "Valid escape character \x1b" pylint-4.0.5/doc/data/messages/i/invalid-character-esc/bad.py0000664000175000017500000000010115146021447023706 0ustar epsilonepsilonSTRING = "Invalid escape character " # [invalid-character-esc] pylint-4.0.5/doc/data/messages/i/invalid-hash-returned/0000775000175000017500000000000015146021447022663 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-hash-returned/good.py0000664000175000017500000000013615146021447024165 0ustar epsilonepsilonclass CustomHash: """__hash__ returns `int`""" def __hash__(self): return 19 pylint-4.0.5/doc/data/messages/i/invalid-hash-returned/bad.py0000664000175000017500000000017015146021447023761 0ustar epsilonepsilonclass CustomHash: """__hash__ returns dict""" def __hash__(self): # [invalid-hash-returned] return {} pylint-4.0.5/doc/data/messages/i/invalid-unicode-codec/0000775000175000017500000000000015146021447022613 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-unicode-codec/details.rst0000664000175000017500000000012015146021447024763 0ustar epsilonepsilonThis message is a placeholder for a potential future issue with unicode codecs. pylint-4.0.5/doc/data/messages/i/invalid-match-args-definition/0000775000175000017500000000000015146021447024266 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-match-args-definition/good.py0000664000175000017500000000021515146021447025566 0ustar epsilonepsilonclass Book: __match_args__ = ("title", "year") def __init__(self, title, year): self.title = title self.year = year pylint-4.0.5/doc/data/messages/i/invalid-match-args-definition/bad.py0000664000175000017500000000026015146021447025364 0ustar epsilonepsilonclass Book: __match_args__ = ["title", "year"] # [invalid-match-args-definition] def __init__(self, title, year): self.title = title self.year = year pylint-4.0.5/doc/data/messages/i/invalid-match-args-definition/related.rst0000664000175000017500000000021215146021447026433 0ustar epsilonepsilon- `Python documentation `_ pylint-4.0.5/doc/data/messages/i/invalid-slots/0000775000175000017500000000000015146021447021256 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-slots/good.py0000664000175000017500000000005615146021447022561 0ustar epsilonepsilonclass Person: __slots__ = ("name", "age") pylint-4.0.5/doc/data/messages/i/invalid-slots/bad.py0000664000175000017500000000006415146021447022356 0ustar epsilonepsilonclass Person: # [invalid-slots] __slots__ = 42 pylint-4.0.5/doc/data/messages/i/invalid-length-hint-returned/0000775000175000017500000000000015146021447024161 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-length-hint-returned/good.py0000664000175000017500000000017115146021447025462 0ustar epsilonepsilonclass CustomLengthHint: """__length_hint__ returns """ def __length_hint__(self): return 10 pylint-4.0.5/doc/data/messages/i/invalid-length-hint-returned/bad.py0000664000175000017500000000022715146021447025262 0ustar epsilonepsilonclass CustomLengthHint: """__length_hint__ returns non-int""" def __length_hint__(self): # [invalid-length-hint-returned] return 3.0 pylint-4.0.5/doc/data/messages/i/invalid-str-returned/0000775000175000017500000000000015146021447022550 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-str-returned/good.py0000664000175000017500000000015115146021447024047 0ustar epsilonepsilonclass CustomStr: """__str__ returns """ def __str__(self): return "oranges" pylint-4.0.5/doc/data/messages/i/invalid-str-returned/bad.py0000664000175000017500000000016215146021447023647 0ustar epsilonepsilonclass CustomStr: """__str__ returns int""" def __str__(self): # [invalid-str-returned] return 1 pylint-4.0.5/doc/data/messages/i/import-self/0000775000175000017500000000000015146021447020727 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/import-self/details.rst0000664000175000017500000000041715146021447023110 0ustar epsilonepsilonSay you have a file called ``my_file.py``. ``import-self`` would be raised on the following code:: from my_file import a_function # [import-self] def a_function(): pass The solution would be to remove the import:: def a_function(): pass pylint-4.0.5/doc/data/messages/i/invalid-bytes-returned/0000775000175000017500000000000015146021447023066 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-bytes-returned/good.py0000664000175000017500000000016515146021447024372 0ustar epsilonepsilonclass CustomBytes: """__bytes__ returns """ def __bytes__(self): return b"some bytes" pylint-4.0.5/doc/data/messages/i/invalid-bytes-returned/bad.py0000664000175000017500000000020715146021447024165 0ustar epsilonepsilonclass CustomBytes: """__bytes__ returns """ def __bytes__(self): # [invalid-bytes-returned] return "123" pylint-4.0.5/doc/data/messages/i/isinstance-second-argument-not-valid-type/0000775000175000017500000000000015146021447026571 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/isinstance-second-argument-not-valid-type/good.py0000664000175000017500000000004615146021447030073 0ustar epsilonepsilonisinstance("apples and oranges", str) pylint-4.0.5/doc/data/messages/i/isinstance-second-argument-not-valid-type/bad.py0000664000175000017500000000012515146021447027667 0ustar epsilonepsilonisinstance("apples and oranges", hex) # [isinstance-second-argument-not-valid-type] pylint-4.0.5/doc/data/messages/i/invalid-character-nul/0000775000175000017500000000000015146021447022642 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-character-nul/good.py0000664000175000017500000000004615146021447024144 0ustar epsilonepsilonSTRING = "Valid nul terminator: \x00" pylint-4.0.5/doc/data/messages/i/invalid-character-nul/details.rst0000664000175000017500000000013315146021447025016 0ustar epsilonepsilonThere's no need to use end-of-string characters. String objects maintain their own length. pylint-4.0.5/doc/data/messages/i/invalid-character-nul/related.rst0000664000175000017500000000011715146021447025013 0ustar epsilonepsilon- `Null terminator in python `_ pylint-4.0.5/doc/data/messages/i/invalid-name/0000775000175000017500000000000015146021447021032 5ustar epsilonepsilonpylint-4.0.5/doc/data/messages/i/invalid-name/good.py0000664000175000017500000000021315146021447022330 0ustar epsilonepsilonclass Cat: def meow(self, number_of_meow): print("Meow" * number_of_meow) return number_of_meow CAT = Cat().meow(42) pylint-4.0.5/doc/data/messages/i/invalid-name/details.rst0000664000175000017500000002717715146021447023227 0ustar epsilonepsilonPylint recognizes a number of different name types internally. With a few exceptions, the type of the name is governed by the location the assignment to a name is found in, and not the type of object assigned. +--------------------+-------------------------------------------------------------------------------------------------------------+ | Name Type | Description | +====================+=============================================================================================================+ | ``module`` | Module and package names, same as the file names. | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``const`` | Module-level constants: any name defined at module level that is not bound to a class object nor reassigned.| +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``class`` | Names in ``class`` statements, as well as names bound to class objects at module level. | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``function`` | Functions, toplevel or nested in functions or methods. | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``method`` | Methods, functions defined in class bodies. Includes static and class methods. | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``attr`` | Attributes created on class instances inside methods. | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``argument`` | Arguments to any function type, including lambdas. | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``variable`` | Local variables in function scopes or module-level names that are assigned multiple times. | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``class-attribute``| Attributes defined in class bodies. | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``class-const`` | Enum constants and class variables annotated with ``Final`` | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``inlinevar`` | Loop variables in list comprehensions and generator expressions. | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``typevar`` | Type variable declared with ``TypeVar``. | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``paramspec`` | Parameter specification variable declared with ``ParamSpec``. | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``typevartuple`` | Type variable tuple declared with ``TypeVarTuple``. | +--------------------+-------------------------------------------------------------------------------------------------------------+ | ``typealias`` | Type alias declared with ``TypeAlias`` or assignments of ``Union``. | +--------------------+-------------------------------------------------------------------------------------------------------------+ Default behavior ~~~~~~~~~~~~~~~~ By default, Pylint will enforce PEP8_-suggested names. Predefined Naming Styles ~~~~~~~~~~~~~~~~~~~~~~~~ Pylint provides set of predefined naming styles. Those predefined naming styles may be used to adjust Pylint configuration to coding style used in linted project. Following predefined naming styles are available: * ``snake_case`` * ``camelCase`` * ``PascalCase`` * ``UPPER_CASE`` * ``any`` - fake style which does not enforce any limitations The following options are exposed: .. option:: --module-naming-style=