diff --git a/doc/软件设计规格说明书-基于软件工厂的群智协作贡献评估系统.doc b/doc/软件设计规格说明书-基于软件工厂的群智协作贡献评估系统.doc index 21cdc38..73986ac 100644 Binary files a/doc/软件设计规格说明书-基于软件工厂的群智协作贡献评估系统.doc and b/doc/软件设计规格说明书-基于软件工厂的群智协作贡献评估系统.doc differ diff --git a/picture/openrank用例图.vsdx b/picture/openrank用例图.vsdx index 766a49b..989a25e 100644 Binary files a/picture/openrank用例图.vsdx and b/picture/openrank用例图.vsdx differ diff --git a/picture/界面跳转图.plantuml b/picture/界面跳转图.plantuml new file mode 100644 index 0000000..b333929 --- /dev/null +++ b/picture/界面跳转图.plantuml @@ -0,0 +1,64 @@ +@startuml +skinparam dpi 180 +skinparam shadowing false +skinparam ArrowColor #00AEEF +skinparam DefaultFontName Microsoft YaHei +skinparam ArrowThickness 1.2 + +title 界面跳转图(OpenRank 可视化系统) + +[*] --> 主界面 : 进入系统 + +state 主界面 +state 开发者分析 +state 仓库概览 +state 网络图谱 +state 项目模式概览 +state 计算弹窗 +state 算法配置界面 +state "仓库详情 Modal" as 仓库详情 +state "项目 Overview (approx)" as 项目Approx +state "项目 Overview (full)" as 项目Full + +' 主界面导航 +主界面 --> 开发者分析 +主界面 --> 仓库概览 +主界面 --> 网络图谱 +主界面 --> 项目模式概览 +主界面 --> 计算弹窗 : 一键计算 + +' 计算弹窗返回刷新各视图 +计算弹窗 --> 主界面 : 提交 owner/repo +计算弹窗 --> 开发者分析 : 结果刷新 +计算弹窗 --> 仓库概览 : 结果刷新 +计算弹窗 --> 项目模式概览 : 可切换模式 + +' 仓库概览交互 +仓库概览 --> 仓库详情 : 查看详情 +仓库概览 --> 开发者分析 : 贡献分析 +仓库概览 --> 仓库概览 : 关键词/筛选 + +' 仓库详情交互 +仓库详情 --> 仓库详情 : 时间窗口/粒度 +仓库详情 --> 仓库概览 : 关闭 +仓库详情 --> 开发者分析 : 跳转贡献者 + +' 项目模式(approx/full)交互 +项目模式概览 --> 项目Approx : 选择仓库 +项目Approx --> 项目Full : 触发正式重算 +项目Full --> 项目Approx : 计算完成 替换 approx +项目Approx --> 项目Approx : 贡献者 Top/活动占比 +项目Approx --> 开发者分析 : 跳转贡献者分析 + +' 网络图谱与算法配置 +网络图谱 --> 算法配置界面 : 参数调节 +算法配置界面 --> 网络图谱 : 保存参数 +算法配置界面 --> 主界面 : 近似预览/正式重算 + +' 返回导航 +开发者分析 --> 主界面 : 返回 +仓库概览 --> 主界面 : 返回 +网络图谱 --> 主界面 : 返回 +项目模式概览 --> 主界面 : 返回 + +@enduml \ No newline at end of file diff --git a/src/pylint/pylint-main/.coveragerc b/src/pylint/pylint-main/.coveragerc new file mode 100644 index 0000000..1ba36fa --- /dev/null +++ b/src/pylint/pylint-main/.coveragerc @@ -0,0 +1,22 @@ +[paths] +source = + pylint + +[report] +include = + pylint/* +omit = + */test/* +exclude_also = + # Debug-only code + def __repr__ + + # Type checking code not executed during pytest runs + if TYPE_CHECKING: + @overload + + # Abstract methods are not executed during pytest runs + raise NotImplementedError() + + # Fallback cases which should never be executed + raise AssertionError diff --git a/src/pylint/pylint-main/.git-blame-ignore-revs b/src/pylint/pylint-main/.git-blame-ignore-revs new file mode 100644 index 0000000..39979df --- /dev/null +++ b/src/pylint/pylint-main/.git-blame-ignore-revs @@ -0,0 +1 @@ +3f2842400795ae1aaffc4ae6c35c4ef26857c239 diff --git a/src/pylint/pylint-main/.gitattributes b/src/pylint/pylint-main/.gitattributes new file mode 100644 index 0000000..5e9c937 --- /dev/null +++ b/src/pylint/pylint-main/.gitattributes @@ -0,0 +1,7 @@ +* text=auto +tests/**/functional/** -text +tests/input/** -text +tests/**/data/** -text +tests/regrtest_data/** -text +doc/data/messages/u/unexpected-line-ending-format/bad.py -text +doc/data/messages/m/mixed-line-endings/bad.py -text diff --git a/src/pylint/pylint-main/.github/CODEOWNERS b/src/pylint/pylint-main/.github/CODEOWNERS new file mode 100644 index 0000000..5083128 --- /dev/null +++ b/src/pylint/pylint-main/.github/CODEOWNERS @@ -0,0 +1,35 @@ +# Lines starting with '#' are comments. +# Each line is a file pattern followed by one or more owners. + +# These owners will be the default owners for everything in the repo. +# Right now there is not default owner to avoid spam +# * @pierre-sassoulas @DanielNoord @cdce8p @jacobtylerwalls @hippo91 + +# Order is important. The last matching pattern has the most precedence. + +### Core components + +# internal message handling +pylint/message/* @pierre-sassoulas +tests/message/* @pierre-sassoulas + +# typing +pylint/typing.py @DanielNoord + +# multiprocessing (doublethefish is not yet a contributor with write access) +# pylint/lint/parallel.py @doublethefish +# tests/test_check_parallel.py @doublethefish + +### Pyreverse +pylint/pyreverse/* @DudeNr33 +tests/pyreverse/* @DudeNr33 + +### Extensions + +# CodeStyle +pylint/extensions/code_style.* @cdce8p +tests/functional/ext/code_style/* @cdce8p + +# Typing +pylint/extensions/typing.* @cdce8p +tests/functional/ext/typing/* @cdce8p diff --git a/src/pylint/pylint-main/.github/CONTRIBUTING.md b/src/pylint/pylint-main/.github/CONTRIBUTING.md new file mode 100644 index 0000000..61adbec --- /dev/null +++ b/src/pylint/pylint-main/.github/CONTRIBUTING.md @@ -0,0 +1,2 @@ +Please read the +[contribute doc](https://pylint.readthedocs.io/en/latest/development_guide/contributor_guide/contribute.html). diff --git a/src/pylint/pylint-main/.github/FUNDING.yml b/src/pylint/pylint-main/.github/FUNDING.yml new file mode 100644 index 0000000..72e1b49 --- /dev/null +++ b/src/pylint/pylint-main/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms +tidelift: "pypi/pylint" +github: [cdce8p, DanielNoord, jacobtylerwalls,Pierre-Sassoulas] diff --git a/src/pylint/pylint-main/.github/ISSUE_TEMPLATE/BUG-REPORT.yml b/src/pylint/pylint-main/.github/ISSUE_TEMPLATE/BUG-REPORT.yml new file mode 100644 index 0000000..664f6f1 --- /dev/null +++ b/src/pylint/pylint-main/.github/ISSUE_TEMPLATE/BUG-REPORT.yml @@ -0,0 +1,108 @@ +name: 🐛 Bug report +description: Report a bug in pylint +labels: ["Needs triage :inbox_tray:"] +body: + - type: markdown + attributes: + value: | + **Thank you for wanting to report a bug in pylint!** + + ⚠ Please make sure that this [issue wasn't already requested][issue search], or already implemented in the main branch. + + + [issue search]: https://github.com/pylint-dev/pylint/issues?q=is%3Aissue+is%3Aopen+ + + - type: textarea + id: what-happened + attributes: + label: Bug description + description: + What is the bug about? Please provide the code that is causing the issue, and + configurations used if required + placeholder: | + # Please disable message unrelated to the bug + # pylint: disable=missing-docstring, + = b + 1 + render: python + validations: + required: true + - type: textarea + id: configuration + attributes: + label: Configuration + description: + Please provide the part of the configuration that is causing the bug if required + (Leave this part blank if the configuration is not relevant) + placeholder: | + # Leave this blank if the configuration is not relevant! + + [MAIN] + load-plugins= + pylint.extensions.code_style + + [MESSAGE CONTROL] + enable= + useless-suppression + + # ... + render: ini + - type: textarea + id: cmd-used + attributes: + label: Command used + description: What was the command used to invoke pylint? + placeholder: | + pylint a.py + render: shell + validations: + required: true + - type: textarea + id: current-behavior + attributes: + label: Pylint output + description: What is the current pylint output? + placeholder: | + ************* Module a + a.py:3:1: E0001: invalid syntax (, line 1) (syntax-error) + render: python + validations: + required: true + - type: textarea + id: future-behavior + attributes: + label: Expected behavior + description: + What would you expect instead? For example expected output or behavior + validations: + required: true + - type: textarea + id: python-interpreter + attributes: + label: Pylint version + description: >- + Please copy and paste the result of `pylint --version` or specify the range of + versions affected. + placeholder: | + pylint 3.3.0 + astroid 3.3.0 + Python 3.12.0 (v3.12.0:0fb18b02c8, Oct 2 2023, 09:45:56) + render: shell + validations: + required: true + - type: textarea + attributes: + label: OS / Environment + description: >- + Provide all relevant information below, e.g. OS version, terminal etc. + placeholder: Fedora 33, Cygwin, etc. + - type: textarea + id: additional-deps + attributes: + label: Additional dependencies + description: + If applicable ie, if we can't reproduce without it. Please copy and paste the + result of `pip freeze`. + placeholder: | + pandas==0.23.2 + marshmallow==3.10.0 + render: python diff --git a/src/pylint/pylint-main/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml b/src/pylint/pylint-main/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml new file mode 100644 index 0000000..b537e69 --- /dev/null +++ b/src/pylint/pylint-main/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml @@ -0,0 +1,45 @@ +name: ✨ Feature request +description: Suggest an idea for pylint +labels: ["Needs triage :inbox_tray:"] +body: + - type: markdown + attributes: + value: | + **Thank you for wanting to make a suggestion for pylint!** + + ⚠ Please make sure that [this feature wasn't already requested][issue search] or already implemented in the main branch. + + + [issue search]: https://github.com/pylint-dev/pylint/issues?q=is%3Aissue+is%3Aopen+ + + - type: textarea + id: current-problem + attributes: + label: Current problem + description: + What are you trying to do, that you are unable to achieve with pylint as it + currently stands? + placeholder: >- + I'm trying to do X and I'm missing feature Y for this to be easily achievable. + validations: + required: true + - type: textarea + id: proposed-solution + attributes: + label: Desired solution + description: A clear and concise description of what you want to happen. + placeholder: >- + When I do X, I want to achieve Y in a situation when Z. + validations: + required: true + - type: textarea + attributes: + label: Additional context + description: > + Add any other context, links, etc. about the feature here. Describe how the + feature would be used, why it is needed and what it would solve. + + **HINT:** You can paste https://gist.github.com links for larger files. + placeholder: >- + I asked on https://stackoverflow.com/... and the community advised me to do X, Y + and Z. diff --git a/src/pylint/pylint-main/.github/ISSUE_TEMPLATE/QUESTION.yml b/src/pylint/pylint-main/.github/ISSUE_TEMPLATE/QUESTION.yml new file mode 100644 index 0000000..ed26c9f --- /dev/null +++ b/src/pylint/pylint-main/.github/ISSUE_TEMPLATE/QUESTION.yml @@ -0,0 +1,49 @@ +name: 🤔 Support question +description: Questions about pylint that are not covered in the documentation +labels: ["Needs triage :inbox_tray:", "Question", "Documentation :green_book:"] +body: + - type: markdown + attributes: + value: > + **Thank you for wanting to report a problem with pylint documentation!** + + + Please fill out your suggestions below. If the problem seems straightforward, + feel free to go ahead and submit a pull request instead! + + + ⚠ Verify first that your issue is not [already reported on GitHub][issue + search]. + + 💬 If you are seeking community support, please consider [starting a discussion + on Discord][Discussions]. + + + [issue search]: + https://github.com/pylint-dev/pylint/issues?q=is%3Aissue+is%3Aopen+ + + [Discussions]: https://discord.com/invite/Egy6P8AMB5 + + - type: textarea + id: question + attributes: + label: Question + validations: + required: true + - type: textarea + id: documentation + attributes: + label: Documentation for future user + description: + Where did you expect this information to be? What do we need to add or what do + we need to reorganize? + validations: + required: true + - type: textarea + attributes: + label: Additional context + description: > + Add any other context, links, etc. about the question here. + placeholder: >- + I asked on https://stackoverflow.com/... and the community advised me to do X, Y + and Z. diff --git a/src/pylint/pylint-main/.github/ISSUE_TEMPLATE/config.yml b/src/pylint/pylint-main/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..76b1511 --- /dev/null +++ b/src/pylint/pylint-main/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: 💬 Discord + url: https://discord.com/invite/Egy6P8AMB5 + about: Astroid and pylint informal dev discussion diff --git a/src/pylint/pylint-main/.github/PULL_REQUEST_TEMPLATE.md b/src/pylint/pylint-main/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..1730a08 --- /dev/null +++ b/src/pylint/pylint-main/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,41 @@ + + +## Type of Changes + + + +| | Type | +| --- | ---------------------- | +| ✓ | :bug: Bug fix | +| ✓ | :sparkles: New feature | +| ✓ | :hammer: Refactoring | +| ✓ | :scroll: Docs | + +## Description + + + +Refs #XXXX + + + +Closes #XXXX diff --git a/src/pylint/pylint-main/.github/SECURITY.md b/src/pylint/pylint-main/.github/SECURITY.md new file mode 100644 index 0000000..bbe6fc2 --- /dev/null +++ b/src/pylint/pylint-main/.github/SECURITY.md @@ -0,0 +1 @@ +Coordinated Disclosure Plan: https://tidelift.com/security diff --git a/src/pylint/pylint-main/.github/copilot-instructions.md b/src/pylint/pylint-main/.github/copilot-instructions.md new file mode 100644 index 0000000..206765b --- /dev/null +++ b/src/pylint/pylint-main/.github/copilot-instructions.md @@ -0,0 +1,255 @@ +# Pylint Development Instructions + +Always follow these instructions first and fallback to additional search and context +gathering only if the information in these instructions is incomplete or found to be in +error. + +## Issue Label Guidelines + +Before attempting to fix any issue, check the GitHub issue labels using the GitHub API: + +- If an issue is labeled with "Astroid", "Needs astroid update", "Needs astroid + constraint", or "Needs astroid Brain 🧠", **ONLY** create regression tests +- Do **NOT** attempt to fix astroid-related issues as you cannot modify astroid from + this repository +- For astroid-related issues, focus on creating comprehensive regression tests that + reproduce the problem +- All other issues can be fixed normally following the standard development workflow + +## Development Environment Setup + +### Basic Installation + +Clone and set up pylint development environment: + +- `git clone https://github.com/pylint-dev/pylint` -- clone repository +- `cd pylint` -- enter directory +- `python3 -m venv venv` -- create virtual environment +- `source venv/bin/activate` -- activate virtual environment (Linux/Mac) +- `pip install -r requirements_test_min.txt` -- install test dependencies (~30 seconds) +- `pip install -e .` -- install pylint in editable mode (~30-60 seconds) + +### Optional Setup Steps + +- `pre-commit install` -- enable pre-commit hooks for autoformatting +- `pip install pre-commit` -- install pre-commit separately if needed + +### Astroid Development (if needed) + +If working on astroid changes: + +- `git clone https://github.com/pylint-dev/astroid.git` -- clone astroid +- `pip install -e astroid/` -- install astroid in editable mode +- `cd astroid/ && git switch my-astroid-dev-branch` -- switch to development branch + +## Running Tests + +### Core Test Commands + +- `pytest tests/test_functional.py -k test_functional` -- run functional tests (~60 + seconds, NEVER CANCEL, set timeout to 120+ seconds) +- `pytest tests/` -- run all tests (several minutes, NEVER CANCEL, set timeout to 300+ + seconds) +- `python3 -m pytest` -- run tests with local python +- `pytest tests/test_check_parallel.py -v` -- quick test file (~2 seconds) + +### Specific Test Types + +- **Functional tests:** + `pytest "tests/test_functional.py::test_functional[missing_kwoa_py3]"` -- single + functional test (~1 second) +- **Unit tests:** Located in `/tests/` directory, test specific pylint functionality +- **Configuration tests:** In `/tests/config/functional/` for testing configuration + loading +- **Primer tests:** `pytest -m primer_stdlib --primer-stdlib` -- test on stdlib for + crashes + +### Test with Coverage + +- `pytest tests/message/ --cov=pylint.message` -- run with coverage +- `coverage html` -- generate HTML coverage report + +### Tox Usage (Optional) + +- `python -m tox` -- run all tox environments +- `python -m tox -epy313` -- run Python 3.13 suite only +- `python -m tox -epylint` -- run pylint on pylint's codebase +- `python -m tox -eformatting` -- run formatting checks +- `python -m tox --recreate` -- recreate environments (recommended) +- `python -m tox -e py310 -- -k test_functional` -- run specific tests in tox + +## Documentation + +### Building Documentation + +- `make -C doc/ install-dependencies` -- install doc dependencies (~10 seconds) +- `make -C doc/ html` -- build documentation (~3 minutes, NEVER CANCEL, set timeout to + 300+ seconds) +- `make -C doc/ clean` -- clean build files when starting from scratch +- `tox -e docs` -- alternative way to build docs + +**Network dependency:** Documentation build requires internet access to fetch external +inventories. + +## Validation and Quality Checks + +### Running Pylint on Code + +- `pylint --help` -- verify pylint installation works +- `pylint --disable=all --enable=E,F pylint/` -- run pylint on itself for errors only + (~20 seconds) +- `pylint --rcfile=pylintrc --fail-on=I path/to/your/changes.py` -- standard pylint run +- `pylint --disable=all --enable=E,F,W path/to/your/changes.py` -- focus on errors and + warnings + +### Pre-commit and Formatting + +- `pre-commit run --all-files` -- run all formatting checks (requires network for + initial setup) +- **Network dependency:** pre-commit may fail in isolated environments due to hook + downloads + +### Validation Test Scenarios + +Always test your changes with these validation scenarios: + +- `echo "def badFunction(): pass" > /tmp/test_sample.py && pylint --enable=C0103 /tmp/test_sample.py` + -- should find naming issues +- `pylint --help` and `pylint --list-msgs | head -10` -- verify CLI functionality +- `pylint --help-msg=C0103` -- should show invalid-name help +- `pylint --rcfile=pylintrc --fail-on=I pylint/__init__.py` -- should get 10.00/10 + rating + +## Writing Tests + +### Functional Tests + +Located in `/tests/functional/`, consists of `.py` test files with corresponding `.txt` +expected output files: + +- Annotate lines where messages are expected: + `a, b, c = 1 # [unbalanced-tuple-unpacking]` +- Multiple messages on same line: + `a, b, c = 1.test # [unbalanced-tuple-unpacking, no-member]` +- Use offset syntax for special cases: `# +1: [singleton-comparison]` +- **Run and update:** + `python tests/test_functional.py --update-functional-output -k "test_functional[test_name]"` + +### Test File Organization + +- **New checkers:** Create `new_checker_message.py` in `/tests/functional/n/` +- **Extensions:** Place in `/tests/functional/ext/extension_name/` +- **Regression tests:** Place in `/tests/r/regression/` with `regression_` prefix +- **Configuration tests:** Place in `/tests/config/functional/` + +### Configuration Test Files + +Create `.result.json` files with configuration differences from standard config: + +```json +{ + "functional_append": { + "disable": [["a-message-to-be-added"]] + }, + "jobs": 10 +} +``` + +## Codebase Structure + +``` +pylint/ # Main package +├── checkers/ # All pylint checkers (rules implementation) +├── config/ # Configuration handling and parsing +├── message/ # Message system and formatting +├── reporters/ # Output formatters (text, json, etc.) +├── testutils/ # Testing utilities and helpers +└── extensions/ # Optional extensions and plugins + +tests/ # Test suite +├── functional/ # Functional test files (.py + .txt expected output) +├── config/functional/ # Configuration functional tests +├── r/regression/ # Regression tests +├── test_*.py # Unit tests +└── regrtest_data/ # Test data files + +doc/ # Documentation +├── user_guide/ # User documentation +├── development_guide/ # Developer and contributor documentation +│ ├── contributor_guide/ # Setup, testing, contribution guidelines +│ ├── technical_reference/ # Technical implementation details +│ └── how_tos/ # Guides for custom checkers, plugins +└── additional_tools/ # Tools documentation + +script/ # Development utility scripts +``` + +### Key Files + +- `pyproject.toml` -- Main configuration (dependencies, build, tools) +- `tox.ini` -- Multi-environment testing configuration +- `.pre-commit-config.yaml` -- Code quality checks configuration +- `pylintrc` -- Pylint's own configuration +- `requirements_test_min.txt` -- Minimal test dependencies +- `.gitignore` do not add the 'venv' inside the .gitignore, don't commit the venv in the + first place (humans add it to their global gitignore) + +## Creating New Checkers + +### Getting Started + +- `python script/get_unused_message_id_category.py` -- get next available message ID +- Study existing checkers in `pylint/checkers/` for patterns +- Read technical reference documentation in `doc/development_guide/technical_reference/` +- Use `astroid.extract_node` for AST manipulation + +### Workflow + +1. Create checker class in appropriate `pylint/checkers/` file +2. Add functional tests in `tests/functional/` +3. Search existing code for warning message to find where logic exists +4. Test with sample code to ensure functionality works + +## Pull Request Guidelines + +### Before Submitting + +- Use Python 3.8+ for development (required for latest AST parser and pre-commit hooks) +- Write comprehensive commit messages relating to tracker issues +- Keep changes small and separate consensual from opinionated changes +- Add news fragment: `towncrier create .` +- Always launch `pre-commit run -a` before committing + +### Documentation Changes + +- Document non-trivial changes +- Generate docs with `tox -e docs` +- Maintainers may label issues `skip-news` if no changelog needed + +### Contribution Credits + +- Add emails/names to `script/.contributors_aliases.json` if using multiple identities + +## Critical Timing Information + +- **NEVER CANCEL:** All operations that show "NEVER CANCEL" may take significant time +- **Full test suite:** 60+ seconds (set timeout to 120+ seconds) +- **Documentation build:** 180 seconds (set timeout to 300+ seconds) +- **Functional tests:** 60 seconds (set timeout to 120+ seconds) +- **Pylint self-check:** 20 seconds (set timeout to 60+ seconds) +- **Individual test files:** 1-15 seconds +- **Installation steps:** 30-60 seconds each + +## Environment Limitations and Workarounds + +- **Network connectivity required:** Documentation build and pre-commit setup require + internet access +- **Tox failures:** In isolated environments, use direct pytest and pip commands instead + of tox +- **Import errors in self-check:** Some import errors when running pylint on itself are + expected (git dependencies not installed) +- **Build environments:** Use direct pip/pytest commands when tox environments fail to + build + +Always validate your changes by running pylint on sample code to ensure functionality +works correctly. diff --git a/src/pylint/pylint-main/.github/dependabot.yml b/src/pylint/pylint-main/.github/dependabot.yml new file mode 100644 index 0000000..98e0f3f --- /dev/null +++ b/src/pylint/pylint-main/.github/dependabot.yml @@ -0,0 +1,21 @@ +version: 2 +updates: + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + labels: + - "dependency" + - "Skip news :mute:" + open-pull-requests-limit: 10 + rebase-strategy: "disabled" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + labels: + - "dependency" + - "Skip news :mute:" + open-pull-requests-limit: 10 + rebase-strategy: "disabled" diff --git a/src/pylint/pylint-main/.github/workflows/backport.yml b/src/pylint/pylint-main/.github/workflows/backport.yml new file mode 100644 index 0000000..4d644f4 --- /dev/null +++ b/src/pylint/pylint-main/.github/workflows/backport.yml @@ -0,0 +1,40 @@ +name: Backport +on: + pull_request_target: + types: + - closed + - labeled + +permissions: + contents: read + +jobs: + backport: + name: Backport + runs-on: ubuntu-latest + environment: + name: Backport + # Only react to merged PRs for security reasons. + # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target. + if: > + github.event.pull_request.merged && ( + github.event.action == 'closed' + || ( + github.event.action == 'labeled' + && contains(github.event.label.name, 'backport') + ) + ) + steps: + - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 + id: app-token + with: + app-id: ${{ vars.BACKPORT_APP_ID }} + private-key: ${{ secrets.PRIVATE_KEY }} + permission-contents: write # push branch to Github + permission-pull-requests: write # create PR / add comment for manual backport + permission-workflows: write # modify files in .github/workflows + - uses: pylint-dev/backport@94367840595495e101f9a31415897c05da1f08d9 # v2.1.1 + with: + github_token: ${{ steps.app-token.outputs.token }} + user_name: ${{ vars.BACKPORT_USER_NAME }} + user_email: ${{ vars.BACKPORT_USER_EMAIL }} diff --git a/src/pylint/pylint-main/.github/workflows/changelog.yml b/src/pylint/pylint-main/.github/workflows/changelog.yml new file mode 100644 index 0000000..d81d2e4 --- /dev/null +++ b/src/pylint/pylint-main/.github/workflows/changelog.yml @@ -0,0 +1,65 @@ +name: changelog + +on: + pull_request: + types: [opened, synchronize, labeled, unlabeled, reopened] + branches-ignore: + - "maintenance/**" +env: + CACHE_VERSION: 1 + KEY_PREFIX: base-venv + DEFAULT_PYTHON: "3.13" + +permissions: + contents: read + +jobs: + check-changelog: + if: contains(github.event.pull_request.labels.*.name, 'skip news :mute:') != true + name: Changelog Entry Check + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Check out code from GitHub + uses: actions/checkout@v5.0.0 + with: + # `towncrier check` runs `git diff --name-only origin/main...`, which + # needs a non-shallow clone. + fetch-depth: 0 + - name: Set up Python ${{ env.DEFAULT_PYTHON }} + id: python + uses: actions/setup-python@v6.0.0 + with: + python-version: ${{ env.DEFAULT_PYTHON }} + check-latest: true + - name: Generate partial Python venv restore key + id: generate-python-key + run: >- + echo "key=${{ env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ + hashFiles('pyproject.toml', 'requirements_test.txt', + 'requirements_test_min.txt', 'requirements_test_pre_commit.txt') }}" >> + $GITHUB_OUTPUT + - name: Restore Python virtual environment + id: cache-venv + uses: actions/cache@v4.3.0 + with: + path: venv + key: >- + ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ + steps.generate-python-key.outputs.key }} + - name: Create Python virtual environment + if: steps.cache-venv.outputs.cache-hit != 'true' + run: | + python -m venv venv + . venv/bin/activate + python -m pip install --upgrade pip + pip install --upgrade --requirement requirements_test.txt --requirement doc/requirements.txt + - name: Emit warning if news fragment is missing + env: + BASE_BRANCH: ${{ github.base_ref }} + run: | + # Fetch the pull request' base branch so towncrier will be able to + # compare the current branch with the base branch. + git fetch --no-tags origin +refs/heads/${BASE_BRANCH}:refs/remotes/origin/${BASE_BRANCH} + . venv/bin/activate + towncrier check --compare-with origin/${{ github.base_ref }} diff --git a/src/pylint/pylint-main/.github/workflows/checks.yaml b/src/pylint/pylint-main/.github/workflows/checks.yaml new file mode 100644 index 0000000..3b0cf04 --- /dev/null +++ b/src/pylint/pylint-main/.github/workflows/checks.yaml @@ -0,0 +1,160 @@ +name: Checks + +on: + push: + branches: + - main + - "maintenance/**" + pull_request: + branches: + - main + - "maintenance/**" + workflow_dispatch: + +env: + CACHE_VERSION: 3 + KEY_PREFIX: base-venv + DEFAULT_PYTHON: "3.13" + PRE_COMMIT_CACHE: ~/.cache/pre-commit + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + prepare-base: + name: Prepare base dependencies + runs-on: ubuntu-latest + timeout-minutes: 10 + outputs: + python-key: ${{ steps.generate-python-key.outputs.key }} + pre-commit-key: ${{ steps.generate-pre-commit-key.outputs.key }} + steps: + - &checkout + name: Check out code from GitHub + uses: actions/checkout@v5.0.0 + - &setup-python + name: Set up Python ${{ env.DEFAULT_PYTHON }} + id: python + uses: actions/setup-python@v6.0.0 + with: + python-version: ${{ env.DEFAULT_PYTHON }} + check-latest: true + - name: Generate partial Python venv restore key + id: generate-python-key + run: >- + echo "key=${{ env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ + hashFiles('pyproject.toml', 'requirements_test.txt', + 'requirements_test_min.txt', 'requirements_test_pre_commit.txt') }}" >> + $GITHUB_OUTPUT + - name: Restore Python virtual environment + id: cache-venv + uses: actions/cache@v4.3.0 + with: + path: venv + key: >- + ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ + steps.generate-python-key.outputs.key }} + - name: Create Python virtual environment + if: steps.cache-venv.outputs.cache-hit != 'true' + run: | + python -m venv venv + . venv/bin/activate + python -m pip install --upgrade pip + pip install --upgrade --requirement requirements_test.txt --requirement doc/requirements.txt + pip install pre-commit + - name: Generate pre-commit restore key + id: generate-pre-commit-key + run: >- + echo "key=pre-commit-${{ env.CACHE_VERSION }}-${{ + hashFiles('.pre-commit-config.yaml') }}" >> $GITHUB_OUTPUT + - name: Restore pre-commit environment + id: cache-precommit + uses: actions/cache@v4.3.0 + with: + path: ${{ env.PRE_COMMIT_CACHE }} + key: >- + ${{ runner.os }}-${{ steps.generate-pre-commit-key.outputs.key }} + - name: Install pre-commit dependencies + if: steps.cache-precommit.outputs.cache-hit != 'true' + run: | + . venv/bin/activate + pre-commit install --install-hooks + + pylint: + name: pylint + runs-on: ubuntu-latest + timeout-minutes: 10 + needs: [prepare-base] + steps: + - *checkout + - *setup-python + - &cache-restore-python + name: Restore Python virtual environment + id: cache-venv + uses: actions/cache/restore@v4.3.0 + with: + path: venv + fail-on-cache-miss: true + key: + ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ + needs.prepare-base.outputs.python-key }} + - name: Restore pre-commit environment + id: cache-precommit + uses: actions/cache/restore@v4.3.0 + with: + path: ${{ env.PRE_COMMIT_CACHE }} + fail-on-cache-miss: true + key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }} + - name: Install enchant and aspell + run: | + sudo apt-get update + sudo apt-get install enchant-2 aspell-en + - name: Run pylint checks + run: | + . venv/bin/activate + pip install . --no-deps + pip list | grep 'astroid\|pylint' + pre-commit run --hook-stage manual pylint-with-spelling --all-files + + spelling: + name: spelling tests + runs-on: ubuntu-latest + timeout-minutes: 5 + needs: [prepare-base] + steps: + - *checkout + - *setup-python + - *cache-restore-python + - name: Run spelling checks + run: | + . venv/bin/activate + pip install . --no-deps + pytest tests/ -k unittest_spelling --benchmark-disable + + documentation: + name: documentation + runs-on: ubuntu-latest + timeout-minutes: 20 + needs: [prepare-base] + steps: + - *checkout + - *setup-python + - *cache-restore-python + - name: Run checks on documentation code examples + run: | + . venv/bin/activate + tox -e test_doc + - name: Check documentation build and links + run: | + . venv/bin/activate + tox -e docs || { + echo "git diff:" ; \ + git diff ; \ + echo "End of 'git diff'" ; \ + echo "Make sure that 'tox -e docs' succeed without any modifications locally." ; \ + exit 1; \ + } diff --git a/src/pylint/pylint-main/.github/workflows/codeql-analysis.yml b/src/pylint/pylint-main/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..238f203 --- /dev/null +++ b/src/pylint/pylint-main/.github/workflows/codeql-analysis.yml @@ -0,0 +1,80 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [main] + pull_request: + # The branches below must be a subset of the branches above + branches: [main] + schedule: + - cron: "44 16 * * 4" + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + analyze: + if: + ${{ github.repository_owner == 'pylint-dev' || github.event_name != 'schedule' }} + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: ["python"] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v5.0.0 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v4 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 diff --git a/src/pylint/pylint-main/.github/workflows/primer-test.yaml b/src/pylint/pylint-main/.github/workflows/primer-test.yaml new file mode 100644 index 0000000..677add7 --- /dev/null +++ b/src/pylint/pylint-main/.github/workflows/primer-test.yaml @@ -0,0 +1,95 @@ +name: Primer + +on: + push: + branches: + - main + pull_request: + paths: + - "pylint/**" + - "tests/primer/**" + - "requirements*" + - ".github/workflows/primer-test.yaml" + branches: + - main +env: + CACHE_VERSION: 4 + KEY_PREFIX: venv + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + prepare-tests-linux: + name: prepare / ${{ matrix.python-version }} / Linux + runs-on: ubuntu-latest + timeout-minutes: 5 + strategy: + matrix: + python-version: &matrix-python-version ["3.10", "3.11", "3.12", "3.13", "3.14"] + outputs: + python-key: ${{ steps.generate-python-key.outputs.key }} + steps: + - &checkout + name: Check out code from GitHub + uses: actions/checkout@v5.0.0 + - &setup-python + name: Set up Python ${{ matrix.python-version }} + id: python + uses: actions/setup-python@v6.0.0 + with: + python-version: ${{ matrix.python-version }} + allow-prereleases: true + check-latest: true + - name: Generate partial Python venv restore key + id: generate-python-key + run: >- + echo "key=${{ env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ + hashFiles('pyproject.toml', 'requirements_test.txt', + 'requirements_test_min.txt', 'requirements_test_pre_commit.txt') }}" >> + $GITHUB_OUTPUT + - name: Restore Python virtual environment + id: cache-venv + uses: actions/cache@v4.3.0 + with: + path: venv + key: >- + ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ + steps.generate-python-key.outputs.key }} + - name: Create Python virtual environment + if: steps.cache-venv.outputs.cache-hit != 'true' + run: | + python -m venv venv + . venv/bin/activate + python -m pip install --upgrade pip + pip install --upgrade --requirement requirements_test.txt + + pytest-primer-stdlib: + name: run on stdlib / ${{ matrix.python-version }} / Linux + runs-on: ubuntu-latest + timeout-minutes: 10 + needs: prepare-tests-linux + strategy: + matrix: + python-version: *matrix-python-version + steps: + - *checkout + - *setup-python + - name: Restore Python virtual environment + id: cache-venv + uses: actions/cache/restore@v4.3.0 + with: + path: venv + fail-on-cache-miss: true + key: + ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ + needs.prepare-tests-linux.outputs.python-key }} + - name: Run pytest + run: | + . venv/bin/activate + pip install . --no-deps + pytest -m primer_stdlib --primer-stdlib -n auto -vv --benchmark-disable diff --git a/src/pylint/pylint-main/.github/workflows/primer_comment.yaml b/src/pylint/pylint-main/.github/workflows/primer_comment.yaml new file mode 100644 index 0000000..5b0f68d --- /dev/null +++ b/src/pylint/pylint-main/.github/workflows/primer_comment.yaml @@ -0,0 +1,125 @@ +# Most of this is inspired by the mypy primer +# See: https://github.com/hauntsaninja/mypy_primer +# This is the primer job that creates the comment on the PR +# It needs to trigger on workflow_run instead of pull_request +# as we need repository wide access to create a comment + +name: Primer / Comment + +on: + workflow_run: + workflows: [Primer / Run] + types: + - completed + +env: + # This needs to be the SAME as in the Main and PR job + CACHE_VERSION: 4 + KEY_PREFIX: venv-primer + # If you change this, also change PRIMER_CURRENT_INTERPRETER in + # tests/testutils/_primer/test_primer.py + DEFAULT_PYTHON: "3.13" + +permissions: + contents: read + pull-requests: write + +jobs: + primer-comment: + # Skip job if the workflow failed + if: ${{ github.event.workflow_run.conclusion == 'success' }} + name: Run + runs-on: ubuntu-latest + steps: + - name: Check out code from GitHub + uses: actions/checkout@v5.0.0 + - name: Set up Python ${{ env.DEFAULT_PYTHON }} + id: python + uses: actions/setup-python@v6.0.0 + with: + python-version: ${{ env.DEFAULT_PYTHON }} + check-latest: true + + # Restore cached Python environment + - name: Restore Python virtual environment + id: cache-venv + uses: actions/cache@v4.3.0 + with: + path: venv + key: + ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ + env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml', + 'requirements_test.txt', 'requirements_test_min.txt', + 'requirements_test_pre_commit.txt') }} + + - name: Download outputs + uses: actions/github-script@v8.0.0 + with: + script: | + // Download workflow pylint output + const fs = require('fs'); + const artifacts_workflow = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{ github.event.workflow_run.id }}, + }); + + // Get 'main' and 'PR' outputs and PR number + const artifacts = artifacts_workflow.data.artifacts.filter((artifact) => + artifact.name.startsWith(`primer_output_main_${process.env.DEFAULT_PYTHON}`) + || artifact.name.startsWith(`primer_output_pr_${process.env.DEFAULT_PYTHON}`) + || artifact.name === 'pr_number' + ); + for (const artifact of artifacts) { + const downloaded = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: artifact.id, + archive_format: "zip", + }); + fs.writeFileSync(`${artifact.name}.zip`, Buffer.from(downloaded.data)); + } + + - name: Unzip outputs + run: | + unzip primer_output_main_${{ env.DEFAULT_PYTHON }}_batch0.zip + unzip primer_output_main_${{ env.DEFAULT_PYTHON }}_batch1.zip + unzip primer_output_main_${{ env.DEFAULT_PYTHON }}_batch2.zip + unzip primer_output_main_${{ env.DEFAULT_PYTHON }}_batch3.zip + unzip primer_output_pr_${{ env.DEFAULT_PYTHON }}_batch0.zip + unzip primer_output_pr_${{ env.DEFAULT_PYTHON }}_batch1.zip + unzip primer_output_pr_${{ env.DEFAULT_PYTHON }}_batch2.zip + unzip primer_output_pr_${{ env.DEFAULT_PYTHON }}_batch3.zip + unzip pr_number.zip + - name: Compare outputs + run: | + . venv/bin/activate + python tests/primer/__main__.py compare \ + --commit=${{ github.event.workflow_run.head_sha }} \ + --base-file=output_${{ env.DEFAULT_PYTHON }}_main_BATCHIDX.txt \ + --new-file=output_${{ env.DEFAULT_PYTHON }}_pr_BATCHIDX.txt \ + --batches=4 + - name: Post comment + id: post-comment + uses: actions/github-script@v8.0.0 + with: + script: | + const fs = require('fs') + const comment = fs.readFileSync('tests/.pylint_primer_tests/comment.txt', { encoding: 'utf8' }) + console.log("Comment to post:") + console.log(comment) + const prNumber = parseInt(fs.readFileSync("pr_number.txt", { encoding: "utf8" })) + await github.rest.issues.createComment({ + issue_number: prNumber, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }) + return prNumber + - name: Hide old comments + # Taken from mypy primer + uses: kanga333/comment-hider@c12bb20b48aeb8fc098e35967de8d4f8018fffdf # v0.4.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + leave_visible: 1 + issue_number: ${{ steps.post-comment.outputs.result }} diff --git a/src/pylint/pylint-main/.github/workflows/primer_run_main.yaml b/src/pylint/pylint-main/.github/workflows/primer_run_main.yaml new file mode 100644 index 0000000..ddf6478 --- /dev/null +++ b/src/pylint/pylint-main/.github/workflows/primer_run_main.yaml @@ -0,0 +1,132 @@ +# Most of this is inspired by the mypy primer +# See: https://github.com/hauntsaninja/mypy_primer +# This is the primer job that runs on the default 'main' branch +# It is also responsible for caching the packages to prime on + +name: Primer / Main + +on: + push: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + # This needs to be the SAME as in the PR and comment job + CACHE_VERSION: 4 + KEY_PREFIX: venv-primer + +permissions: + contents: read + +jobs: + run-primer: + name: Run / ${{ matrix.python-version }} / batch index ${{ matrix.batchIdx }} + runs-on: ubuntu-latest + timeout-minutes: 45 + strategy: + matrix: + python-version: ["3.10", "3.13"] + batches: [4] + batchIdx: [0, 1, 2, 3] + steps: + - name: Check out code from GitHub + uses: actions/checkout@v5.0.0 + - name: Set up Python ${{ matrix.python-version }} + id: python + uses: actions/setup-python@v6.0.0 + with: + python-version: ${{ matrix.python-version }} + check-latest: true + + # Create a re-usable virtual environment + - name: Restore Python virtual environment cache + id: cache-venv + uses: actions/cache/restore@v4.3.0 + with: + path: venv + key: + ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ + env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml', + 'requirements_test.txt', 'requirements_test_min.txt', + 'requirements_test_pre_commit.txt') }} + - name: Create Python virtual environment + if: steps.cache-venv.outputs.cache-hit != 'true' + run: | + python -m venv venv + . venv/bin/activate + python -m pip install --upgrade pip + pip install --upgrade --requirement requirements_test.txt + # Save cached Python environment (explicit because cancel-in-progress: true) + - name: Save Python virtual environment to cache + if: steps.cache-venv.outputs.cache-hit != 'true' + uses: actions/cache/save@v4.3.0 + with: + path: venv + key: + ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ + env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml', + 'requirements_test.txt', 'requirements_test_min.txt', + 'requirements_test_pre_commit.txt') }} + + # Cache primer packages + - name: Get commit string + id: commitstring + run: | + . venv/bin/activate + python tests/primer/__main__.py prepare --make-commit-string + output=$(python tests/primer/__main__.py prepare --read-commit-string) + echo "commitstring=$output" >> $GITHUB_OUTPUT + - name: Restore projects cache + id: cache-projects + uses: actions/cache/restore@v4.3.0 + with: + path: tests/.pylint_primer_tests/ + key: >- + ${{ runner.os }}-${{ matrix.python-version }}-${{ + steps.commitstring.outputs.commitstring }}-primer + - name: Regenerate cache + if: steps.cache-projects.outputs.cache-hit != 'true' + run: | + . venv/bin/activate + python tests/primer/__main__.py prepare --clone + - name: Save projects cache + if: steps.cache-projects.outputs.cache-hit != 'true' + uses: actions/cache/save@v4.3.0 + with: + path: tests/.pylint_primer_tests/ + key: >- + ${{ runner.os }}-${{ matrix.python-version }}-${{ + steps.commitstring.outputs.commitstring }}-primer + - name: Upload commit string + uses: actions/upload-artifact@v4.6.2 + if: matrix.batchIdx == 0 + with: + name: primer_commitstring_${{ matrix.python-version }} + path: + tests/.pylint_primer_tests/commit_string_${{ matrix.python-version }}.txt + + # Run primer + - name: Run pylint primer + run: | + . venv/bin/activate + pip install . --no-deps + python tests/primer/__main__.py run --type=main --batches=${{ matrix.batches }} --batchIdx=${{ matrix.batchIdx }} 2>warnings.txt + - name: Echo warnings + if: success() || failure() + run: | + WARNINGS=$(head -c 65000 < warnings.txt) + if [[ $WARNINGS ]] + then echo "::warning ::$WARNINGS" + fi + - name: Upload output + uses: actions/upload-artifact@v4.6.2 + with: + name: + primer_output_main_${{ matrix.python-version }}_batch${{ matrix.batchIdx }} + path: >- + tests/.pylint_primer_tests/output_${{ matrix.python-version }}_main_batch${{ + matrix.batchIdx }}.txt diff --git a/src/pylint/pylint-main/.github/workflows/primer_run_pr.yaml b/src/pylint/pylint-main/.github/workflows/primer_run_pr.yaml new file mode 100644 index 0000000..9314b5c --- /dev/null +++ b/src/pylint/pylint-main/.github/workflows/primer_run_pr.yaml @@ -0,0 +1,225 @@ +# Most of this is inspired by the mypy primer +# See: https://github.com/hauntsaninja/mypy_primer +# This is the primer job that runs on every PR + +name: Primer / Run + +on: + pull_request: + paths: + - "pylint/**" + - "tests/primer/**" + - "requirements*" + - ".github/workflows/**" + # We ignore these specific files because they need to be changed + # on 'main' and will always fail the PR run. + - "!.github/workflows/primer_run_main.yaml" + - "!.github/workflows/primer_comment.yaml" + - "!tests/primer/packages_to_prime.json" + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + # This needs to be the SAME as in the Main and comment job + CACHE_VERSION: 4 + KEY_PREFIX: venv-primer + +permissions: + contents: read + +jobs: + run-primer: + name: Run / ${{ matrix.python-version }} / batch index ${{ matrix.batchIdx }} + runs-on: ubuntu-latest + timeout-minutes: 45 + strategy: + matrix: + python-version: ["3.10", "3.13"] + batches: [4] + batchIdx: [0, 1, 2, 3] + steps: + - name: Check out code from GitHub + uses: actions/checkout@v5.0.0 + with: + fetch-depth: 0 + - name: Set up Python ${{ matrix.python-version }} + id: python + uses: actions/setup-python@v6.0.0 + with: + python-version: ${{ matrix.python-version }} + check-latest: true + + # Restore cached Python environment + - name: Restore Python virtual environment + id: cache-venv + uses: actions/cache/restore@v4.3.0 + with: + path: venv + key: + ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ + env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml', + 'requirements_test.txt', 'requirements_test_min.txt', + 'requirements_test_pre_commit.txt') }} + # Create environment must match step in 'Primer / Main' + - name: Create Python virtual environment + if: steps.cache-venv.outputs.cache-hit != 'true' + run: | + python -m venv venv + . venv/bin/activate + python -m pip install --upgrade pip + pip install --upgrade --requirement requirements_test.txt + # Save cached Python environment (explicit because cancel-in-progress: true) + - name: Save Python virtual environment + if: steps.cache-venv.outputs.cache-hit != 'true' + uses: actions/cache/save@v4.3.0 + with: + path: venv + key: + ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ + env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml', + 'requirements_test.txt', 'requirements_test_min.txt', + 'requirements_test_pre_commit.txt') }} + + # Cache primer packages + - name: Download last 'main' run info + id: download-main-run + uses: actions/github-script@v8.0.0 + env: + COMMIT_STRING_ARTIFACT: primer_commitstring_${{ matrix.python-version }} + OUTPUT_ARTIFACT: + primer_output_main_${{ matrix.python-version }}_batch${{ matrix.batchIdx }} + with: + script: | + const { COMMIT_STRING_ARTIFACT, OUTPUT_ARTIFACT } = process.env + // Download 'main' pylint output + const fs = require('fs'); + const runs = await github.rest.actions.listWorkflowRuns({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: ".github/workflows/primer_run_main.yaml", + status: "success" + }); + const lastRunMain = runs.data.workflow_runs.reduce(function(prev, current) { + return (prev.run_number > current.run_number) ? prev : current + }) + console.log("Last run on main:") + console.log(lastRunMain.html_url) + const artifacts_main = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: lastRunMain.id, + }); + + // Get commitstring + const [matchArtifactMain] = artifacts_main.data.artifacts.filter((artifact) => + artifact.name === COMMIT_STRING_ARTIFACT); + const downloadWorkflow = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifactMain.id, + archive_format: "zip", + }); + fs.writeFileSync(`${COMMIT_STRING_ARTIFACT}.zip`, Buffer.from(downloadWorkflow.data)); + + // Get output + const [matchArtifactMainOutput] = artifacts_main.data.artifacts.filter((artifact) => + artifact.name === OUTPUT_ARTIFACT); + const downloadWorkflowTwo = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifactMainOutput.id, + archive_format: "zip", + }); + fs.writeFileSync(`${OUTPUT_ARTIFACT}.zip`, Buffer.from(downloadWorkflowTwo.data)); + return lastRunMain.head_sha; + - name: Copy and unzip the commit string + run: | + unzip primer_commitstring_${{ matrix.python-version }}.zip + cp commit_string_${{ matrix.python-version }}.txt tests/.pylint_primer_tests/commit_string_${{ matrix.python-version }}.txt + - name: Unzip the output of 'main' + run: | + unzip primer_output_main_${{ matrix.python-version }}_batch${{ matrix.batchIdx }}.zip + - name: Get commit string + id: commitstring + run: | + . venv/bin/activate + output=$(python tests/primer/__main__.py prepare --read-commit-string) + echo "commitstring=$output" >> $GITHUB_OUTPUT + - name: Restore projects cache + id: cache-projects + uses: actions/cache/restore@v4.3.0 + with: + path: tests/.pylint_primer_tests/ + key: >- + ${{ runner.os }}-${{ matrix.python-version }}-${{ + steps.commitstring.outputs.commitstring }}-primer + - name: Regenerate cache + if: steps.cache-projects.outputs.cache-hit != 'true' + run: | + . venv/bin/activate + python tests/primer/__main__.py prepare --clone + - name: Save projects cache + if: steps.cache-projects.outputs.cache-hit != 'true' + uses: actions/cache/save@v4.3.0 + with: + path: tests/.pylint_primer_tests/ + key: >- + ${{ runner.os }}-${{ matrix.python-version }}-${{ + steps.commitstring.outputs.commitstring }}-primer + - name: Check cache + run: | + . venv/bin/activate + python tests/primer/__main__.py prepare --check + + # Merge the 'main' commit of last successful run + - name: Pull 'main' + shell: bash + run: | + git config --global user.email "primer@example.com" + git config --global user.name "Pylint Primer" + git pull origin ${{ steps.download-main-run.outputs.result }} --no-edit --no-commit --no-rebase + + # Run primer + - name: Run pylint primer + run: | + . venv/bin/activate + pip install . --no-deps + python tests/primer/__main__.py run --type=pr --batches=${{ matrix.batches }} --batchIdx=${{ matrix.batchIdx }} 2>warnings.txt + - name: Echo warnings + if: success() || failure() + run: | + WARNINGS=$(head -c 65000 < warnings.txt) + if [[ $WARNINGS ]] + then echo "::warning ::$WARNINGS" + fi + - name: Upload output of PR + uses: actions/upload-artifact@v4.6.2 + with: + name: + primer_output_pr_${{ matrix.python-version }}_batch${{ matrix.batchIdx }} + path: + tests/.pylint_primer_tests/output_${{ matrix.python-version }}_pr_batch${{ + matrix.batchIdx }}.txt + - name: Upload output of 'main' + uses: actions/upload-artifact@v4.6.2 + with: + name: + primer_output_main_${{ matrix.python-version }}_batch${{ matrix.batchIdx }} + path: output_${{ matrix.python-version }}_main_batch${{ matrix.batchIdx }}.txt + + # Save PR number so we know which PR to comment on + - name: Save PR number + run: | + echo ${{ github.event.pull_request.number }} | tee pr_number.txt + - name: Upload PR number + if: + startsWith(steps.python.outputs.python-version, '3.10') && matrix.batchIdx == + 0 + uses: actions/upload-artifact@v4.6.2 + with: + name: pr_number + path: pr_number.txt diff --git a/src/pylint/pylint-main/.github/workflows/release.yml b/src/pylint/pylint-main/.github/workflows/release.yml new file mode 100644 index 0000000..0acafde --- /dev/null +++ b/src/pylint/pylint-main/.github/workflows/release.yml @@ -0,0 +1,80 @@ +name: Release + +on: + release: + types: + - published + +env: + DEFAULT_PYTHON: "3.13" + +permissions: + contents: read + +jobs: + build: + name: Build release assets + runs-on: ubuntu-latest + if: github.event_name == 'release' + steps: + - name: Check out code from Github + uses: actions/checkout@v5.0.0 + - name: Set up Python ${{ env.DEFAULT_PYTHON }} + id: python + uses: actions/setup-python@v6.0.0 + with: + python-version: ${{ env.DEFAULT_PYTHON }} + check-latest: true + - name: Install requirements + run: | + # Remove dist, build, and pylint.egg-info + # when building locally for testing! + python -m pip install build + - name: Build distributions + run: | + python -m build + - name: Upload release assets + uses: actions/upload-artifact@v4.6.2 + with: + name: release-assets + path: dist/ + + release-pypi: + name: Upload release to PyPI + runs-on: ubuntu-latest + needs: ["build"] + environment: + name: PyPI + url: https://pypi.org/project/pylint/ + permissions: + id-token: write + steps: + - name: Download release assets + uses: actions/download-artifact@v5.0.0 + with: + name: release-assets + path: dist/ + - name: Upload to PyPI + if: github.event_name == 'release' + uses: pypa/gh-action-pypi-publish@release/v1 + + release-github: + name: Upload assets to Github release + runs-on: ubuntu-latest + needs: ["build"] + permissions: + contents: write + id-token: write + steps: + - name: Download release assets + uses: actions/download-artifact@v5.0.0 + with: + name: release-assets + path: dist/ + - name: Sign the dists with Sigstore and upload assets to Github release + if: github.event_name == 'release' + uses: sigstore/gh-action-sigstore-python@v3.0.1 + with: + inputs: | + ./dist/*.tar.gz + ./dist/*.whl diff --git a/src/pylint/pylint-main/.github/workflows/stale.yml b/src/pylint/pylint-main/.github/workflows/stale.yml new file mode 100644 index 0000000..be87d51 --- /dev/null +++ b/src/pylint/pylint-main/.github/workflows/stale.yml @@ -0,0 +1,44 @@ +name: close stale issues and pr +on: + schedule: + - cron: "30 1 * * *" + workflow_dispatch: + +jobs: + close-issues: + if: github.repository_owner == 'pylint-dev' + runs-on: ubuntu-latest + permissions: + actions: write + issues: write + pull-requests: write + steps: + - uses: actions/stale@v10 + with: + operations-per-run: 100 + + days-before-issue-stale: 28 + days-before-issue-close: 7 + any-of-issue-labels: + "Waiting on author,Cannot reproduce 🤷,python past end of life,Won't fix/not + planned" + exempt-issue-labels: "High priority,Blocked 🚧,Needs decision 🔒" + stale-issue-message: + "This issue is stale because it has been open 4 weeks with no activity. + Remove 'Stale' label or comment or this will be closed in a week." + close-issue-message: + "This issue was closed because it has been stalled for five weeks with no + activity." + + any-of-pr-labels: + "Waiting on author,python past end of life,Won't fix/not planned" + exempt-pr-labels: "High priority,Blocked 🚧,Needs review 🔍" + days-before-pr-stale: 56 + days-before-pr-close: -1 + stale-pr-label: "Needs take over 🛎️" + close-pr-message: + "This PR was closed because it needed to be taken over for 16 weeks with no + one stepping up." + stale-pr-message: + "This PR needs take over because because it has been open 8 weeks with no + activity." diff --git a/src/pylint/pylint-main/.github/workflows/tests.yaml b/src/pylint/pylint-main/.github/workflows/tests.yaml new file mode 100644 index 0000000..b375ccb --- /dev/null +++ b/src/pylint/pylint-main/.github/workflows/tests.yaml @@ -0,0 +1,208 @@ +name: Tests + +on: + push: + branches: + - main + - "maintenance/**" + paths-ignore: + - doc/data/messages/** + pull_request: + branches: + - main + - "maintenance/**" + workflow_dispatch: + +env: + CACHE_VERSION: 5 + KEY_PREFIX: venv + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + tests: + name: run / ${{ matrix.python-version }} / ${{ matrix.os }} + timeout-minutes: 25 + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + python-version: &matrix-python-version ["3.10", "3.11", "3.12", "3.13", "3.14"] + include: + - os: macos-latest + python-version: "3.10" + - os: ubuntu-latest + python-version: "pypy-3.10" + - os: ubuntu-latest + python-version: "pypy-3.11" + runs-on: ${{ matrix.os }} + outputs: + python-key: ${{ steps.generate-python-key.outputs.key }} + steps: + - &checkout + name: Check out code from GitHub + uses: actions/checkout@v5.0.0 + - &setup-python + name: Set up Python ${{ matrix.python-version }} + id: python + uses: actions/setup-python@v6.0.0 + with: + python-version: ${{ matrix.python-version }} + allow-prereleases: true + check-latest: true + - name: Generate partial Python venv restore key + id: generate-python-key + run: >- + echo "key=${{ env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ + hashFiles('pyproject.toml', 'requirements_test.txt', + 'requirements_test_min.txt', 'requirements_test_pre_commit.txt') }}" >> + $GITHUB_OUTPUT + - &cache-python + name: Restore Python virtual environment + id: cache-venv + uses: actions/cache@v4.3.0 + with: + path: venv + key: >- + ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ + steps.generate-python-key.outputs.key }} + - name: Create Python virtual environment + if: steps.cache-venv.outputs.cache-hit != 'true' + run: | + python -m venv venv + . venv/bin/activate + python -m pip install --upgrade pip + pip install --upgrade --requirement requirements_test.txt + - name: Run pytest + run: | + . venv/bin/activate + pip install . --no-deps + pip list | grep 'astroid\|pylint' + python -m pytest --durations=10 --benchmark-disable --cov --cov-report= tests/ + - name: Run functional tests with minimal messages config + run: | + . venv/bin/activate + pip list | grep 'astroid\|pylint' + python -m pytest -vv --minimal-messages-config tests/test_functional.py --benchmark-disable + - name: Upload coverage artifact + if: runner.os == 'Linux' + uses: actions/upload-artifact@v4.6.2 + with: + name: coverage-${{ matrix.python-version }} + include-hidden-files: true + path: .coverage + + coverage: + name: process / coverage + runs-on: ubuntu-latest + timeout-minutes: 5 + needs: [tests] + steps: + - *checkout + - name: Set up Python 3.13 + id: python + uses: actions/setup-python@v6.0.0 + with: + python-version: "3.13" + check-latest: true + - &cache-restore-python + name: Restore Python virtual environment + id: cache-venv + uses: actions/cache/restore@v4.3.0 + with: + path: venv + fail-on-cache-miss: true + key: + ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ + needs.tests.outputs.python-key }} + - name: Download all coverage artifacts + uses: actions/download-artifact@v5.0.0 + - name: Combine coverage results + run: | + . venv/bin/activate + coverage combine coverage*/.coverage + coverage xml + - uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + verbose: true + + benchmark-linux: + name: run benchmark / ${{ matrix.python-version }} / Linux + runs-on: ubuntu-latest + timeout-minutes: 10 + needs: [tests] + strategy: + fail-fast: false + matrix: + python-version: ["3.13"] + steps: + - *checkout + - *setup-python + - *cache-restore-python + - name: Run pytest + run: | + . venv/bin/activate + pip install pygal + pip install . --no-deps + pip list | grep 'astroid\|pylint' + pytest --exitfirst \ + --benchmark-only \ + --benchmark-autosave \ + --benchmark-save-data \ + --benchmark-group-by="group" + - name: Create partial artifact name suffix + id: artifact-name-suffix + run: >- + echo "datetime="$(date "+%Y%m%d_%H%M") >> $GITHUB_OUTPUT + - name: Upload benchmark artifact + uses: actions/upload-artifact@v4.6.2 + with: + name: + benchmark-${{ runner.os }}-${{ matrix.python-version }}_${{ + steps.artifact-name-suffix.outputs.datetime }} + include-hidden-files: true + path: .benchmarks/ + + tests-windows: + name: run / ${{ matrix.python-version }} / Windows + runs-on: windows-latest + timeout-minutes: 25 + needs: [tests] + strategy: + fail-fast: false + matrix: + python-version: *matrix-python-version + steps: + - name: Set temp directory + run: echo "TEMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV + # Workaround to set correct temp directory on Windows + # https://github.com/actions/virtual-environments/issues/712 + - *checkout + - *setup-python + - name: Generate partial Python venv restore key + id: generate-python-key + run: >- + echo "key=venv-${{ env.CACHE_VERSION }}-${{ + hashFiles('pyproject.toml', 'requirements_test_min.txt') + }}" >> $env:GITHUB_OUTPUT + - *cache-python + - name: Create Python virtual environment + if: steps.cache-venv.outputs.cache-hit != 'true' + run: | + python -m venv venv + . venv\\Scripts\\activate + python -m pip install --upgrade pip + pip install --upgrade --requirement requirements_test_min.txt + - name: Run pytest + run: | + . venv\\Scripts\\activate + pip install . --no-deps + pip list | grep 'astroid\|pylint' + python -m pytest --durations=10 --benchmark-disable tests/ diff --git a/src/pylint/pylint-main/.gitignore b/src/pylint/pylint-main/.gitignore new file mode 100644 index 0000000..d807609 --- /dev/null +++ b/src/pylint/pylint-main/.gitignore @@ -0,0 +1,29 @@ +# Do not add entries specific to your dev environment or development +# preferences in this file. You can use the global .gitignore for that: +# git config --global core.excludesFile '~/.gitignore' +/log +*.py[cod] +/build +/doc/_build +/dist/ +/pylint.egg-info/ +.tox +*.sw[a-z] +# Can't use | operator in .gitignore, see +# https://unix.stackexchange.com/a/31806/189111 +doc/user_guide/messages/convention/ +doc/user_guide/messages/error/ +doc/user_guide/messages/fatal/ +doc/user_guide/messages/information/ +doc/user_guide/messages/refactor/ +doc/user_guide/messages/warning/ +tests/.pylint_primer_tests/ +pyve +build-stamp +.coverage +.coverage.* +.cache/ +.eggs/ +.pytest_cache/ +.mypy_cache/ +.benchmarks/ diff --git a/src/pylint/pylint-main/.pre-commit-config.yaml b/src/pylint/pylint-main/.pre-commit-config.yaml new file mode 100644 index 0000000..20537cb --- /dev/null +++ b/src/pylint/pylint-main/.pre-commit-config.yaml @@ -0,0 +1,174 @@ +ci: + skip: [pylint] + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: trailing-whitespace + exclude: tests(/\w*)*/functional/t/trailing_whitespaces.py|tests/pyreverse/data/.*.html|doc/data/messages/t/trailing-whitespace/bad.py + # - id: file-contents-sorter # commented out because it does not preserve comments order + # args: ["--ignore-case", "--unique"] + # files: "custom_dict.txt" + - id: end-of-file-fixer + exclude: | + (?x)^( + tests(/\w*)*/functional/m/missing/missing_final_newline.py| + tests/functional/t/trailing_newlines.py| + doc/data/messages/t/trailing-newlines/bad.py| + doc/data/messages/m/missing-final-newline/bad/lf.py| + doc/data/messages/m/missing-final-newline/bad/crlf.py + )$ + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.14.0" + hooks: + - id: ruff-check + args: ["--fix"] + exclude: doc/data/messages + - id: ruff-check + name: ruff-doc + files: doc/data/messages + # Please exclude using doc/data/ruff.toml + # exclude: "" # Leave empty + - repo: https://github.com/Pierre-Sassoulas/copyright_notice_precommit + rev: 0.1.2 + hooks: + - id: copyright-notice + args: ["--notice=script/copyright.txt", "--enforce-all"] + exclude: tests(/\w*)*/functional/|tests/input|doc/data/messages|examples/|setup.py|tests(/\w*)*data/ + types: [python] + - repo: https://github.com/PyCQA/isort + rev: 7.0.0 + hooks: + - id: isort + exclude: doc/data/messages/ + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 25.9.0 + hooks: + - id: black + args: [--safe, --quiet] + exclude: &fixtures tests(/\w*)*/functional/|tests/input|doc/data/messages|tests(/\w*)*data/ + - id: black + name: black-doc + args: [--safe, --quiet] + files: doc/data/messages/ + exclude: | + (?x)^( + doc/data/messages/b/bad-indentation/bad.py| + doc/data/messages/i/inconsistent-quotes/bad.py| + doc/data/messages/i/invalid-format-index/bad.py| + doc/data/messages/l/line-too-long/bad.py| + doc/data/messages/m/missing-final-newline/bad/crlf.py| + doc/data/messages/m/missing-final-newline/bad/lf.py| + doc/data/messages/m/multiple-statements/bad.py| + doc/data/messages/r/redundant-u-string-prefix/bad.py| + doc/data/messages/s/superfluous-parens/bad/example_1.py| + doc/data/messages/s/syntax-error/bad.py| + doc/data/messages/t/too-many-ancestors/bad.py| + doc/data/messages/t/trailing-comma-tuple/bad.py| + doc/data/messages/t/trailing-newlines/bad.py| + doc/data/messages/t/trailing-whitespace/bad.py| + doc/data/messages/u/unnecessary-semicolon/bad.py + )$ + - repo: https://github.com/Pierre-Sassoulas/black-disable-checker + rev: v1.1.3 + hooks: + - id: black-disable-checker + - repo: local + hooks: + - id: pylint + name: pylint + entry: pylint + language: system + types: [python] + # Not that problematic to run in parallel see Pre-commit + # integration in the doc for details + # require_serial: true + args: ["-rn", "-sn", "--rcfile=pylintrc", "--fail-on=I"] + exclude: tests(/\w*)*/functional/|tests/input|tests(/\w*)*data/|doc/ + - id: pyright + name: pyright + description: "Python command line wrapper for pyright, a static type checker" + entry: pyright + language: python + "types_or": [python, pyi] + require_serial: true + minimum_pre_commit_version: "2.9.2" + exclude: tests(/\w*)*/functional/|tests/input|tests(/.*)+/conftest.py|doc/data/messages|tests(/\w*)*data/ + stages: [manual] + # We define an additional manual step to allow running pylint with a spelling + # checker in CI. + - id: pylint + alias: pylint-with-spelling + name: pylint + entry: pylint + language: system + types: [python] + args: + [ + "-rn", + "-sn", + "--rcfile=pylintrc", + "--fail-on=I", + "--spelling-dict=en", + "--output-format=github", + ] + exclude: tests(/\w*)*/functional/|tests/input|tests(/\w*)*data/|doc/ + stages: [manual] + - id: check-newsfragments + name: Check newsfragments + entry: python3 -m script.check_newsfragments + language: system + types: [text] + files: ^(doc/whatsnew/fragments) + exclude: doc/whatsnew/fragments/_.*.rst + - repo: https://github.com/rstcheck/rstcheck + rev: "v6.2.5" + hooks: + - id: rstcheck + args: ["--report-level=warning"] + files: ^(doc/(.*/)*.*\.rst) + additional_dependencies: ["Sphinx==7.4.3"] + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.18.2 + hooks: + - id: mypy + name: mypy + args: [] + additional_dependencies: + ["isort>=5", "platformdirs==2.2.0", "py==1.11", "tomlkit>=0.10.1"] + exclude: tests(/\w*)*/functional/|tests/input|tests(/.*)+/conftest.py|doc/data/messages|tests(/\w*)*data/ + - repo: https://github.com/rbubley/mirrors-prettier + rev: v3.6.2 + hooks: + - id: prettier + args: [--prose-wrap=always, --print-width=88] + exclude: (tests(/\w*)*data/|.github/FUNDING.yml) + - repo: https://github.com/DanielNoord/pydocstringformatter + rev: v0.7.5 + hooks: + - id: pydocstringformatter + exclude: *fixtures + args: ["--max-summary-lines=2", "--linewrap-full-docstring"] + files: "pylint" + - repo: https://github.com/PyCQA/bandit + rev: 1.8.6 + hooks: + - id: bandit + args: ["-r", "-lll"] + exclude: *fixtures + - repo: https://github.com/codespell-project/codespell + rev: v2.4.1 + hooks: + - id: codespell + args: ["--toml=pyproject.toml"] + additional_dependencies: + - tomli + - repo: https://github.com/tox-dev/pyproject-fmt + rev: "v2.10.0" + hooks: + - id: pyproject-fmt + - repo: https://github.com/abravalheri/validate-pyproject + rev: v0.24.1 + hooks: + - id: validate-pyproject diff --git a/src/pylint/pylint-main/.pre-commit-hooks.yaml b/src/pylint/pylint-main/.pre-commit-hooks.yaml new file mode 100644 index 0000000..1bec079 --- /dev/null +++ b/src/pylint/pylint-main/.pre-commit-hooks.yaml @@ -0,0 +1,6 @@ +- id: pylint + name: pylint + entry: pylint + language: python + types: [python] + require_serial: true diff --git a/src/pylint/pylint-main/.readthedocs.yaml b/src/pylint/pylint-main/.readthedocs.yaml new file mode 100644 index 0000000..36666db --- /dev/null +++ b/src/pylint/pylint-main/.readthedocs.yaml @@ -0,0 +1,19 @@ +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +sphinx: + fail_on_warning: true + configuration: doc/conf.py + +python: + install: + - requirements: doc/readthedoc_requirements.txt + +build: + os: ubuntu-22.04 + tools: + python: "3.11" + jobs: + pre_build: + - towncrier build --yes --date TBA diff --git a/src/pylint/pylint-main/CITATION.cff b/src/pylint/pylint-main/CITATION.cff new file mode 100644 index 0000000..53098e8 --- /dev/null +++ b/src/pylint/pylint-main/CITATION.cff @@ -0,0 +1,14 @@ +cff-version: 1.2.0 +title: "Pylint" +message: >- + If you use this software, please cite it using the metadata from this file. +type: software +authors: + - name: "Pylint contributors" +repository-code: "https://github.com/pylint-dev/pylint" +url: "https://pylint.readthedocs.io/en/latest/" +abstract: >- + Pylint is a static code analyser for Python 2 or 3. 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. +license: GPL-2.0 diff --git a/src/pylint/pylint-main/CODE_OF_CONDUCT.md b/src/pylint/pylint-main/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..6d30aaa --- /dev/null +++ b/src/pylint/pylint-main/CODE_OF_CONDUCT.md @@ -0,0 +1,120 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a +harassment-free experience for everyone, regardless of age, body size, visible or +invisible disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, +inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community +include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, and + learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of any + kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, without + their explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional + setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in response to +any behavior that they deem inappropriate, threatening, offensive, or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, +commits, code, wiki edits, issues, and other contributions that are not aligned to this +Code of Conduct, and will communicate reasons for moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an +individual is officially representing the community in public spaces. Examples of +representing our community include using an official e-mail address, posting via an +official social media account, or acting as an appointed representative at an online or +offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to +the community leaders responsible for enforcement at pierre.sassoulas at gmail.com. All +complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter +of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the +consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing clarity +around the nature of the violation and an explanation of why the behavior was +inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of actions. + +**Consequence**: A warning with consequences for continued behavior. No interaction with +the people involved, including unsolicited interaction with those enforcing the Code of +Conduct, for a specified period of time. This includes avoiding interactions in +community spaces as well as external channels like social media. Violating these terms +may lead to a temporary or permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including sustained +inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public communication +with the community for a specified period of time. No public or private interaction with +the people involved, including unsolicited interaction with those enforcing the Code of +Conduct, is allowed during this period. Violating these terms may lead to a permanent +ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community standards, +including sustained inappropriate behavior, harassment of an individual, or aggression +toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, +available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/src/pylint/pylint-main/CONTRIBUTORS.txt b/src/pylint/pylint-main/CONTRIBUTORS.txt new file mode 100644 index 0000000..146e1b9 --- /dev/null +++ b/src/pylint/pylint-main/CONTRIBUTORS.txt @@ -0,0 +1,699 @@ +# This file is autocompleted by 'contributors-txt', +# using the configuration in 'script/.contributors_aliases.json'. +# Do not add new persons manually and only add information without +# using '-' as the line first character. +# Please verify that your change are stable if you modify manually. + +Ex-maintainers +-------------- +- Claudiu Popa +- Sylvain Thénault : main author / maintainer +- Torsten Marek + + +Maintainers +----------- +- Pierre Sassoulas +- Daniël van Noord <13665637+DanielNoord@users.noreply.github.com> +- Jacob Walls +- Marc Mueller <30130371+cdce8p@users.noreply.github.com> +- Hippo91 +- Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com> +- Andreas Finkler <3929834+DudeNr33@users.noreply.github.com> +- Matus Valo +- Dani Alcala <112832187+clavedeluna@users.noreply.github.com> +- Łukasz Rogalski +- Nick Drozd : performance improvements to astroid +- Ashley Whetter +- Bryce Guinta +- Yu Shao, Pang <36848472+yushao2@users.noreply.github.com> +- Dimitri Prybysh + * multiple-imports, not-iterable, not-a-mapping, various patches. +- Roy Williams (Lyft) + * added check for implementing __eq__ without implementing __hash__, + * Added Python 3 check for accessing Exception.message. + * Added Python 3 check for calling encode/decode with invalid codecs. + * Added Python 3 check for accessing sys.maxint. + * Added Python 3 check for bad import statements. + * Added Python 3 check for accessing deprecated methods on the 'string' module, + various patches. +- Florian Bruhin +- Arianna Yang + + +Contributors +------------ + +We would not be here without folks that contributed patches, pull requests, +issues and their time to pylint. We're incredibly grateful to all of these +contributors: + +- Emile Anclin (Logilab): python 3 support +- Michal Nowikowski : + * wrong-spelling-in-comment + * wrong-spelling-in-docstring + * parallel execution on multiple CPUs +- Julthep Nandakwang +- Bruno Daniel : check_docs extension. +- Sushobhit <31987769+sushobhit27@users.noreply.github.com> (sushobhit27) + * Added new check 'comparison-with-itself'. + * Added new check 'useless-import-alias'. + * Added support of annotations in missing-type-doc and missing-return-type-doc. + * Added new check 'comparison-with-callable'. + * Removed six package dependency. + * Added new check 'chained-comparison'. + * Added new check 'useless-object-inheritance'. +- Brett Cannon : + * Port source code to be Python 2/3 compatible + * Python 3 checker +- Laura Médioni (Logilab, on behalf of the CNES): + * misplaced-comparison-constant + * no-classmethod-decorator + * no-staticmethod-decorator + * too-many-nested-blocks, + * too-many-boolean-expressions + * unneeded-not + * wrong-import-order + * ungrouped-imports, + * wrong-import-position + * redefined-variable-type +- Harutaka Kawamura +- Alexandre Fayolle (Logilab): TkInter gui, documentation, debian support +- Ville Skyttä +- Zen Lee <53538590+zenlyj@users.noreply.github.com> +- Julien Cristau (Logilab): python 3 support +- Moisés López <6644187+moylop260@users.noreply.github.com>: + * Support for deprecated-modules in modules not installed, + * Refactor wrong-import-order to integrate it with `isort` library + * Add check too-complex with mccabe for cyclomatic complexity + * Refactor wrong-import-position to skip try-import and nested cases + * Add consider-merging-isinstance, superfluous-else-return + * Fix consider-using-ternary for 'True and True and True or True' case + * Add bad-docstring-quotes and docstring-first-line-empty + * Add missing-timeout + * Fix false negative for `deprecated-module` when a `__import__` method is used instead of `import` sentence +- Adrien Di Mascio +- Frank Harrison (doublethefish) +- Pierre-Yves David +- David Shea : invalid sequence and slice index +- Gunung P. Wibisono <55311527+gunungpw@users.noreply.github.com> +- Derek Gustafson +- Cezar Elnazli : deprecated-method +- Joseph Young <80432516+jpy-git@users.noreply.github.com> (jpy-git) +- Tim Martin +- Ollie <46904826+ollie-iterators@users.noreply.github.com> +- Julian Grimm <51880314+Julfried@users.noreply.github.com> +- Tushar Sadhwani (tusharsadhwani) +- Nicolas Chauvat +- orSolocate <38433858+orSolocate@users.noreply.github.com> +- Radu Ciorba : not-context-manager and confusing-with-statement warnings. +- Holger Peters +- Cosmin Poieană : unichr-builtin and improvements to bad-open-mode. +- Yilei "Dolee" Yang +- Steven Myint : duplicate-except. +- Peter Kolbus (Garmin) +- Luigi Bertaco Cristofolini (luigibertaco) +- Glenn Matthews : + * autogenerated documentation for optional extensions, + * bug fixes and enhancements for docparams (née check_docs) extension +- crazybolillo +- correctmost <134317971+correctmost@users.noreply.github.com> +- Vlad Temian : redundant-unittest-assert and the JSON reporter. +- Julien Jehannet +- Boris Feld +- Anthony Sottile +- Andrew Haigh (nelfin) +- Robert Hofer +- Pedro Algarvio (s0undt3ch) +- Julien Palard +- Hugo van Kemenade +- David Liu (david-yz-liu) +- Dan Goldsmith : support for msg-template in HTML reporter. +- Buck Evan +- Mariatta Wijaya + * Added new check `logging-fstring-interpolation` + * Documentation typo fixes +- Jakub Wilk +- Eli Fine (eli88fine): Fixed false positive duplicate code warning for lines with symbols only +- Émile Crater +- Pavel Roskin +- David Gilman +- へーさん +- Thomas Hisch +- Marianna Polatoglou : minor contribution for wildcard import check +- Manuel Vázquez Acosta +- Luis Escobar (Vauxoo): Add bad-docstring-quotes and docstring-first-line-empty +- Lucas Cimon +- Konstantina Saketou <56515303+ksaketou@users.noreply.github.com> +- Konstantin +- Jim Robertson +- Ethan Leba +- Enji Cooper +- Drum Ogilvie +- David Lindquist : logging-format-interpolation warning. +- Daniel Harding +- Anthony Truchet +- Alexander Todorov : + * added new error conditions to 'bad-super-call', + * Added new check for incorrect len(SEQUENCE) usage, + * Added new extension for comparison against empty string constants, + * Added new extension which detects comparing integers to zero, + * Added new useless-return checker, + * Added new try-except-raise checker +- theirix +- Téo Bouvard +- Sviatoslav Sydorenko +- Stavros Ntentos <133706+stdedos@users.noreply.github.com> +- Nicolas Boulenguez +- Mihai Balint +- Mark Bell +- Levi Gruspe +- Jakub Kuczys +- Hornwitser : fix import graph +- Fureigh +- David Douard +- Daniel Balparda (Google): GPyLint maintainer (Google's pylint variant) +- Christian Clauss +- Bastien Vallet (Djailla) +- Aru Sahni : Git ignoring, regex-based ignores +- Andreas Freimuth : fix indentation checking with tabs +- Alexandru Coman +- jpkotta +- Thomas Grainger +- Takahide Nojima +- Taewon D. Kim +- Sneaky Pete +- Sergey B Kirpichev +- Sandro Tosi : Debian packaging +- Rogdham +- Rene Zhang +- Paul Lichtenberger +- Or Bahari +- Mr. Senko +- Mike Frysinger +- Martin von Gagern (Google): Added 'raising-format-tuple' warning. +- Martin Vielsmaier +- Martin Pool (Google): + * warnings for anomalous backslashes + * symbolic names for messages (like 'unused') + * etc. +- Martin Bašti + * Added new check for shallow copy of os.environ + * Added new check for useless `with threading.Lock():` statement +- Marcus Näslund (naslundx) +- Marco Pernigotti <7657251+mpernigo@users.noreply.github.com> +- Marco Forte +- James Addison <55152140+jayaddison@users.noreply.github.com> +- Ionel Maries Cristian +- Gergely Kalmár +- Damien Baty +- Benjamin Drung : contributing Debian Developer +- Anubhav <35621759+anubh-v@users.noreply.github.com> +- Antonio Quarta +- Andrew J. Simmons +- Alvaro Frias +- Alexey Pelykh +- Alex Prabhat Bara +- wtracy +- jessebrennan +- chohner +- aatle <168398276+aatle@users.noreply.github.com> +- Tiago Honorato <61059243+tiagohonorato@users.noreply.github.com> +- Steven M. Vascellaro +- Robin Tweedie <70587124+robin-wayve@users.noreply.github.com> +- Roberto Leinardi : PyCharm plugin maintainer +- Ricardo Gemignani +- Piotr Idzik <65706193+vil02@users.noreply.github.com> +- Pieter Engelbrecht +- Philipp Albrecht (pylbrecht) +- Nicolas Dickreuter +- Nick Bastin +- Nathaniel Manista : suspicious lambda checking +- Maksym Humetskyi (mhumetskyi) + * Fixed ignored empty functions by similarities checker with "ignore-signatures" option enabled + * Ignore function decorators signatures as well by similarities checker with "ignore-signatures" option enabled + * Ignore class methods and nested functions signatures as well by similarities checker with "ignore-signatures" option enabled +- Kylian +- Konstantin Manna +- Kai Mueller <15907922+kasium@users.noreply.github.com> +- Joshua Cannon +- John Leach +- James Morgensen : ignored-modules option applies to import errors. +- Jaehoon Hwang (jaehoonhwang) +- Huw Jones +- Gideon <87426140+GideonBear@users.noreply.github.com> +- Ganden Schaffner +- Frost Ming +- Federico Bond +- Erik Wright +- Erik Eriksson : Added overlapping-except error check. +- Emmanuel Ferdman +- Dave Bunten +- Daniel Wang +- Daniel Mouritzen +- Dan Hemberger <846186+hemberger@users.noreply.github.com> +- Chris Rebert : unidiomatic-typecheck. +- Aurelien Campeas +- Alexander Pervakov +- Alain Leufroy +- Akhil Kamat +- Adam Williamson +- Aaron Liu +- xmo-odoo +- tbennett0 +- purajit <7026198+purajit@users.noreply.github.com> +- omarandlorraine <64254276+omarandlorraine@users.noreply.github.com> +- craig-sh +- bernie gray +- azinneck0485 <123660683+azinneck0485@users.noreply.github.com> +- Wing Lian +- Wes Turner (Google): added new check 'inconsistent-quotes' +- Tyler Thieding +- Tobias Hernstig <30827238+thernstig@users.noreply.github.com> +- Smixi +- Simu Toni +- Sergei Lebedev <185856+superbobry@users.noreply.github.com> +- Scott Worley +- Saugat Pachhai +- Samuel FORESTIER +- Rémi Cardona +- Ryan Ozawa +- Roger Sheu <78449574+rogersheu@users.noreply.github.com> +- Raphael Gaschignard +- Ram Rachum (cool-RR) +- Radostin Stoyanov +- Peter Bittner +- Paul Renvoisé +- PHeanEX +- Omega Weapon +- Nikolai Kristiansen +- Nick Pesce +- Nedelcu Ioan-Andrei <138256980+nedelcu-ioan@users.noreply.github.com> +- Nathan Marrow +- Mikhail Fesenko +- Matthew Suozzo +- Matthew Beckers <17108752+mattlbeck@users.noreply.github.com> (mattlbeck) +- Mark Roman Miller : fix inline defs in too-many-statements +- MalanB +- Mads Kiilerich +- Maarten ter Huurne +- Lefteris Karapetsas +- LCD 47 +- Jérome Perrin +- Justin Li +- John Kirkham +- Jens H. Nielsen +- Jake Lishman +- Ioana Tagirta : fix bad thread instantiation check +- Ikraduya Edian : Added new checks 'consider-using-generator' and 'use-a-generator'. +- Hugues Bruant +- Hashem Nasarat +- Harut +- Grygorii Iermolenko +- Grizzly Nyo +- Gabriel R. Sezefredo : Fixed "exception-escape" false positive with generators +- Filipe Brandenburger +- Fantix King (UChicago) +- Eric McDonald <221418+emcd@users.noreply.github.com> +- Elias Dorneles : minor adjust to config defaults and docs +- Elazrod56 +- Edward K. Ream +- Derek Harland +- David Pursehouse +- Daniel Miller +- Christoph Blessing <33834216+cblessing24@users.noreply.github.com> +- Chris Murray +- Chris Lamb +- Charles Hebert +- Carli Freudenberg (CarliJoy) + * Fixed issue 5281, added Unicode checker + * Improve non-ascii-name checker +- Bruce Dawson +- Brian Shaginaw : prevent error on exception check for functions +- Benny Mueller +- Ben James +- Ben Green +- Batuhan Taskaya +- Artem Yurchenko +- Alexander Kapshuna +- Akshay Choudhary <153769403+Akshay9715@users.noreply.github.com> +- Adam Parkin +- 谭九鼎 <109224573@qq.com> +- Łukasz Sznuk +- zasca +- y2kbugger +- vinnyrose +- ttenhoeve-aa +- thinwybk +- temyurchenko <44875844+temyurchenko@users.noreply.github.com> +- syutbai +- sur.la.route <17788706+christopherpickering@users.noreply.github.com> +- sdet_liang +- pavan-msys <149513767+pavan-msys@users.noreply.github.com> +- paschich +- oittaa <8972248+oittaa@users.noreply.github.com> +- nyabkun <75878387+nyabkun@users.noreply.github.com> +- nhdsd +- moxian +- mar-chi-pan +- lrjball <50599110+lrjball@users.noreply.github.com> +- levon-d +- laike9m +- kyoto7250 <50972773+kyoto7250@users.noreply.github.com> +- kriek +- kdestin <101366538+kdestin@users.noreply.github.com> +- jaydesl <35102795+jaydesl@users.noreply.github.com> +- jab +- gracejiang16 <70730457+gracejiang16@users.noreply.github.com> +- glmdgrielson <32415403+glmdgrielson@users.noreply.github.com> +- glegoux +- gaurikholkar +- flyingbot91 +- fly +- fahhem +- fadedDexofan +- epenet <6771947+epenet@users.noreply.github.com> +- danields +- cosven +- cordis-dev +- cherryblossom <31467609+cherryblossom000@users.noreply.github.com> +- bluesheeptoken +- anatoly techtonik +- amelenty +- akirchhoff-modular +- agutole +- Zeckie <49095968+Zeckie@users.noreply.github.com> +- Zeb Nicholls + * Made W9011 compatible with 'of' syntax in return types +- Yuval Langer +- Yury Gribov +- Yuri Bochkarev : Added epytext support to docparams extension. +- Youngsoo Sung +- Yory <39745367+yory8@users.noreply.github.com> +- Yoichi Nakayama +- Yeting Li (yetingli) +- Yannack +- Yann Dirson +- Yang Yang +- Xi Shen +- Winston H <56998716+winstxnhdw@users.noreply.github.com> +- Will Shanks +- Viorel Știrbu : intern-builtin warning. +- VictorT +- Victor Jiajunsu <16359131+jiajunsu@users.noreply.github.com> +- ViRuSTriNiTy +- Val Lorentz +- Ulrich Eckhardt +- Udi Fuchs +- Trevor Bekolay + * Added --list-msgs-enabled command +- Tomer Chachamu : simplifiable-if-expression +- Tomasz Michalski +- Tomasz Magulski +- Tom +- Tim Hatch +- Tim Gates +- Tianyu Chen <124018391+UTsweetyfish@users.noreply.github.com> +- Théo Battrel +- Thomas Benhamou +- Theodore Ni <3806110+tjni@users.noreply.github.com> +- Tanvi Moharir <74228962+tanvimoharir@users.noreply.github.com>: Fix for invalid toml config +- T.Rzepka +- Svetoslav Neykov +- SubaruArai <78188579+SubaruArai@users.noreply.github.com> +- Stéphane Wirtel : nonlocal-without-binding +- Stephen Longofono <8992396+SLongofono@users.noreply.github.com> +- Stephane Odul <1504511+sodul@users.noreply.github.com> +- Stanislav Levin +- Sorin Sbarnea +- Slavfox +- Skip Montanaro +- Sigurd Spieckermann <2206639+sisp@users.noreply.github.com> +- Shiv Venkatasubrahmanyam +- Sebastian Müller +- Sayyed Faisal Ali <80758388+C0DE-SLAYER@users.noreply.github.com> +- Sasha Bagan +- Sardorbek Imomaliev +- Santiago Castro +- Samuel Freilich (sfreilich) +- Sam Vermeiren <88253337+PaaEl@users.noreply.github.com> +- Ryan McGuire +- Ry4an Brase +- Ruro +- Roshan Shetty +- Roman Ivanov +- Robert Schweizer +- Reverb Chu +- Renat Galimov +- Rebecca Turner (9999years) +- Randall Leeds +- Ranadheer Gorrepati <35244169+ranadheerg@users.noreply.github.com> +- Ramon Saraiva +- Ramiro Leal-Cavazos (ramiro050): Fixed bug preventing pylint from working with Emacs tramp +- RSTdefg <34202999+RSTdefg@users.noreply.github.com> +- R. N. West <98110034+rnwst@users.noreply.github.com> +- Qwiddle13 <32040075+Qwiddle13@users.noreply.github.com> +- Quentin Young +- Prajwal Borkar +- Petr Pulc : require whitespace around annotations +- Peter Dawyndt +- Peter Dave Hello +- Peter Aronoff +- Paul Cochrane +- Patrik +- Pascal Corpet +- Pablo Galindo Salgado + * Fix false positive 'Non-iterable value' with async comprehensions. +- Osher De Paz +- Oisín Moran +- Obscuron +- Noam Yorav-Raphael +- Noah-Agnel <138210920+Noah-Agnel@users.noreply.github.com> +- Nir Soffer +- Niko Wenselowski +- Nikita Sobolev +- Nick Smith +- Neowizard +- Ned Batchelder +- Natalie Serebryakova +- Naglis Jonaitis <827324+naglis@users.noreply.github.com> +- Moody +- Mitchell Young : minor adjustment to docparams +- Mitar +- Ming Lyu +- Mikhail f. Shiryaev +- Mike Fiedler (miketheman) +- Mike Bryant +- Mike Bernard +- Michka Popoff +- Michal Vasilek +- Michael Scott Cuthbert +- Michael Kefeder +- Michael K +- Michael Hudson-Doyle +- Michael Giuffrida +- Melvin Hazeleger <31448155+melvio@users.noreply.github.com> +- Meltem Kenis +- Mehdi Drissi +- Matěj Grabovský +- Matthijs Blom <19817960+MatthijsBlom@users.noreply.github.com> +- Matej Spiller Muys +- Matej Marušák +- Marzuk Rashid +- Markus Siebenhaar <41283549+siehar@users.noreply.github.com> +- Marco Edward Gorelli : Documented Jupyter integration +- Marcin Kurczewski (rr-) +- Maik Röder +- Lumír 'Frenzy' Balhar +- Ludovic Aubry +- Louis Sautier +- Lorena Buciu <46202743+lorena-b@users.noreply.github.com> +- Logan Miller <14319179+komodo472@users.noreply.github.com> +- Kári Tristan Helgason +- Kurian Benoy <70306694+kurianbenoy-aot@users.noreply.github.com> +- Krzysztof Czapla +- Kraig Brockschmidt +- Kound +- KotlinIsland <65446343+KotlinIsland@users.noreply.github.com> +- Kosarchuk Sergey +- Konrad Weihmann <46938494+priv-kweihmann@users.noreply.github.com> +- Kian Meng, Ang +- Kevin Phillips +- Kevin Jing Qiu +- Kenneth Schackart +- Kayran Schmidt <59456929+yumasheta@users.noreply.github.com> +- Karthik Nadig +- Jürgen Hermann +- Josselin Feist +- Jonathan Kotta +- John Paraskevopoulos : add 'differing-param-doc' and 'differing-type-doc' +- John McGehee +- John Gabriele +- John Belmonte +- Johannes Maron +- Joffrey Mander +- Jochen Preusche +- Jeroen Seegers : + * Fixed `toml` dependency issue +- Jeremy Fleischman +- Jason Owen +- Jason Lau +- Jared Garst +- Jared Deckard +- Janne Rönkkö +- Jamie Scott +- James Sinclair +- James M. Allen +- James Lingard +- James Broadhead +- Jakub Kulík +- Jakob Normark +- Jacques Kvam +- Jace Browning : updated default report format with clickable paths +- JZ +- JT Olds +- Iggy Eom +- Ige-kun <178478713+Ige-kun@users.noreply.github.com> +- Hayden Richards <62866982+SupImDos@users.noreply.github.com> + * Fixed "no-self-use" for async methods + * Fixed "docparams" extension for async functions and methods +- Harshil <37377066+harshil21@users.noreply.github.com> +- Harry +- Gwanbin Park +- Grégoire <96051754+gregoire-mullvad@users.noreply.github.com> +- Grant Welch +- Giuseppe Valente +- Gary Tyler McLeod +- Felix von Drigalski +- Felix Preuschoff <37065638+felixp98@users.noreply.github.com> +- Fabrice Douchant +- Fabio Natali +- Fabian Damken +- Eric Froemling +- Emmanuel Chaudron +- Elizabeth Bott <52465744+elizabethbott@users.noreply.github.com> +- Ekin Dursun +- Eisuke Kawashima +- Edgemaster +- Eddie Darling +- Drew Risinger +- Dr. Nick +- Don Kirkby +- Don Jayamanne +- Dominic Lavery +- Dmytro Kyrychuk +- Dionisio E Alonso +- DetachHead <57028336+DetachHead@users.noreply.github.com> +- Dennis Keck <26092524+fellhorn@users.noreply.github.com> +- Denis Laxalde +- David Lawson +- David Cain +- Danny Hermes +- Daniele Procida +- Daniela Plascencia +- Daniel Werner +- Daniel R. Neal (danrneal) +- Daniel Draper +- Daniel Dorani (doranid) +- Daniel Brookman <53625739+dbrookman@users.noreply.github.com> +- Dan Garrette +- Damien Nozay +- Cubicpath +- Craig Citro +- Cosmo +- Clément Schreiner +- Clément Pit-Claudel +- Christopher Zurcher +- ChandanChainani +- Carl Crowder : don't evaluate the value of arguments for 'dangerous-default-value' +- Carey Metcalfe : demoted `try-except-raise` from error to warning +- Cameron Olechowski +- Calin Don +- Caio Carrara +- C.A.M. Gerlach +- Bruno P. Kinoshita +- Brice Chardin +- Brian C. Lane +- Brandon W Maister +- BioGeek +- Berker ŞAL +- Benjamin Partzsch <32679788+bnjmnp@users.noreply.github.com> +- Benjamin Graham +- Benedikt Morbach +- Ben Greiner +- Barak Shoshany +- Banjamin Freeman +- Ayushi Kotiyal <70513726+Ayushikotiyal@users.noreply.github.com> +- Avram Lubkin +- Athos Ribeiro : Fixed dict-keys-not-iterating false positive for inverse containment checks +- Arun Persaud +- Arthur Lutz +- Antonio Ossa +- Antonio Gámiz Delgado <73933988+antoniogamizbadger@users.noreply.github.com> +- Anthony VEREZ +- Anthony Tan +- Anthony Foglia (Google): Added simple string slots check. +- Anentropic +- Andy Young +- Andy Palmer <25123779+ninezerozeronine@users.noreply.github.com> +- Andrzej Klajnert +- Andrew Howe +- Andres Perez Hortal +- Andre Hora +- Aman Salwan <121633121+AmanSal1@users.noreply.github.com> +- Alok Singh <8325708+alok@users.noreply.github.com> +- Allan Chandler <95424144+allanc65@users.noreply.github.com> (allanc65) + * Fixed issue 5452, false positive missing-param-doc for multi-line Google-style params +- Alex Waygood +- Alex Mor <5476113+nashcontrol@users.noreply.github.com> +- Alex Jurkiewicz +- Alex Hearn +- Alex Fortin +- Aleksander Mamla +- Alan Evangelista +- Alan Chan +- Aivar Annamaa +- Aidan Haase <44787650+haasea@users.noreply.github.com> +- Ahirnish Pareek : 'keyword-arg-before-var-arg' check +- Agustin Marquez +- Adrian Chirieac +- Aditya Gupta (adityagupta1089) + * Added ignore_signatures to duplicate checker +- Adam Tuft <73994535+adamtuft@users.noreply.github.com> +- Adam Dangoor +- 243f6a88 85a308d3 <33170174+243f6a8885a308d313198a2e037@users.noreply.github.com> + + +Co-Author +--------- +The following persons were credited manually but did not commit themselves +under this name, or we did not manage to find their commits in the history. + +- Agustin Toledo +- Amaury Forgeot d'Arc: check names imported from a module exists in the module +- Anthony Tan +- Axel Muller +- Benjamin Niemann: allow block level enabling/disabling of messages +- Bernard Nauwelaerts +- Bill Wendling +- Brian van den Broek: windows installation documentation +- Craig Henriques +- D. Alphus (Alphadelta14) +- Daniil Kharkov +- Eero Vuojolahti +- Fabio Zadrozny +- Gauthier Sebaux +- James DesLauriers +- manderj +- Mirko Friedenhagen +- Nicholas Smith +- Nuzula H. Yudaka (Nuzhuka) +- Pek Chhan +- Peter Hammond +- Pierre Rouleau +- Richard Goodman: simplifiable-if-expression (with Tomer Chachamu) +- Sebastian Ulrich +- Takashi Hirashima +- Thomas Snowden: fix missing-docstring for inner functions +- Wolfgang Grafen +- Yannick Brehon diff --git a/src/pylint/pylint-main/LICENSE b/src/pylint/pylint-main/LICENSE new file mode 100644 index 0000000..8c4c849 --- /dev/null +++ b/src/pylint/pylint-main/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/src/pylint/pylint-main/MANIFEST.in b/src/pylint/pylint-main/MANIFEST.in new file mode 100644 index 0000000..6943930 --- /dev/null +++ b/src/pylint/pylint-main/MANIFEST.in @@ -0,0 +1,14 @@ +include 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] diff --git a/src/pylint/pylint-main/README.rst b/src/pylint/pylint-main/README.rst new file mode 100644 index 0000000..a4f22ef --- /dev/null +++ b/src/pylint/pylint-main/README.rst @@ -0,0 +1,225 @@ +`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 diff --git a/src/pylint/pylint-main/codecov.yml b/src/pylint/pylint-main/codecov.yml new file mode 100644 index 0000000..c45517a --- /dev/null +++ b/src/pylint/pylint-main/codecov.yml @@ -0,0 +1,10 @@ +coverage: + status: + patch: + default: + target: 100% + project: + default: + target: 95% +comment: + layout: "reach, diff, flags, files" diff --git a/src/pylint/pylint-main/custom_dict.txt b/src/pylint/pylint-main/custom_dict.txt new file mode 100644 index 0000000..77df598 --- /dev/null +++ b/src/pylint/pylint-main/custom_dict.txt @@ -0,0 +1,396 @@ +abc +abcmeta +abspath +abstractproperty +analyse +analysed +analysing +arg +argparse +args +argumentdefaultshelpformatter +argumentparser +argumentsparser +argv +ascii +asend +assignattr +assignname +AST +ast +astroid +async +asynccontextmanager +attr +attrib +attrname +backport +BaseChecker +basename +behaviour +bidi +Bitbucket +bla +bom +bool +boolean +booleaness +boolop +boundmethod +builtins +bw +callables +cardinality +cd +cfg +changelog +cheaders +chroot +chunker +classdef +classdiagram +classmethod +classmethod's +classname +classobj +CLI +cls +cmp +codebase +codec +codecs +col's +conf +config +const +Const +contextlib +contextmanager +contravariance +contravariant +cgroup +CPython +cpython +csv +CVE +cwd +cyclomatic +dataclass +dataclasses +datetime +debian +deduplication +deepcopy +defaultdicts +defframe +defstmts +deleter +dependabot +deque +destructured +destructuring +diadefs +diadefslib +dictcomp +dicts +dir +dirname +docparams +docstring +docstrings +dumpable +dunder +elif +elif's +elt +emittable +encodings +endswith +enum +enums +epilog +epylint +epytext +erroring +etree +expr +falsey +favour +filepath +filestream +finalbody +# TODO Remove when we are able to remove our own symbols +fixme +Flymake +fmt +formatter +formfeed +fromlineno +fullname +func +functiondef +functiøn +functools +genexpr +getattr +globals +globbing +GPL +graphname +graphviz +grey +guido's +gv +hashable +hmac +html +idgeneratormixin +ifexpr +igetattr +importedname +importfrom +importnode +importschecker +InferenceError +ini +INI +init +initializer +inlinevar +instantiation +isdir +isfile +isinstance +isort +iter +iterable +iterables +itered +iteritems +iTerm +jn +jpg +json +jx +jython +# class is a reserved word +klass +kwarg +kwargs +kwonlyargs +latin +len +lhs +linecache +lineno +linenum +lineset +lineset's +linesets +linkers +linter +linux +listcomp +Logilab +longstring +lsp +mapfile +mapreduce +maxsize +maxsplit +mcs +mermaidjs +metaclass +metaclasses +misdesign +misdesigns +mixin +modname +monkeypatch +mro +# Used so much that we need the abbreviation +msg +msg-template +msgid +msgids +msgs +mult +multiline +multiset +multisets +myattr +myfunction +mymain +mymethod +mymodule +mypy +namedtuple +namespace +newsfile +newstyle +nl +nodename +nodeng +noinspection +nonlocal +nonlocals +num +numpy +ok +optdict +optik +optionals +optiondict +optname +optparse +optvalue +orelse +os +outputfile +overridable +params +paren +parens +passthru +pathlib +patternerror +png +positionals +pragma +pragma's +pragmas +pre +preorder +prepended +proc +py +pyenchant +pyfile +pyi +pylint +pylint's +pylintdict +pylintrc +pyproject +pypy +pyreverse +pytest +qname +rawcheckers +rc +rcfile +re-usable +readlines +recognise +recurse +recurses +redef +reportid +rgx +rheaders +rhs +roid +rsplit +rst +rstrip +rtype +runtime +se +seaborn +sep +setcomp +shortstrings +singledispatch +singledispatchmethod +spammy +sqlalchemy +src +starargs +stateful +staticmethod +stderr +stdin +stdlib +stdout +stmt +str +stringified +subclasses +subcommands +subdicts +subgraphs +sublists +submodule +submodules +subparsers +subparts +subprocess +subscriptable +subscripted +subtree +supcls +superclass +symilar +symlink +symlinks +sys +tbump +tempfile +testcase +testdata +testoptions +tmp +tokencheckers +tokeninfo +tokenization +tokenize +tokenizer +toml +tomlkit +toplevel +towncrier +tp +truthey +truthness +truthy +tryexcept +txt +typecheck +typechecking +typeddict +typehint +typeshed +uid +uml +un +unary +unflattens +unhandled +unicode +uninferable +Uninferable +unittest +unraisablehook +untriggered +# prefix for string +ur +ureport +ureports +utf +utils +validator +vararg +varargs +variadic +variadics +vcg +vcg's +vectorisation +virtualized +wc +whitespaces +xfails +xml +xyz +yml +yoda diff --git a/src/pylint/pylint-main/doc/Makefile b/src/pylint/pylint-main/doc/Makefile new file mode 100644 index 0000000..7f21f73 --- /dev/null +++ b/src/pylint/pylint-main/doc/Makefile @@ -0,0 +1,47 @@ +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +# -------------------------------- +# This part is specific to pylint. +#--------------------------------- + +# Set PYLINT_SPHINX_FATAL_WARNINGS= on the command line to restore the default. +PYLINT_SPHINX_FATAL_WARNINGS = -W --keep-going + +# Do not use O, we abuse it for internal purposes. +O = -d $(BUILDDIR)/doctrees -T $(PYLINT_SPHINX_FATAL_WARNINGS) -n + +.PHONY clean: remove-generated-messages +remove-generated-messages: + rm -rf user_guide/messages/convention user_guide/messages/error \ + user_guide/messages/fatal user_guide/messages/information user_guide/messages/refactor \ + user_guide/messages/warning + +# Generated by exts/*.py but kept in the VCS for easier review of changes: +.PHONY: distclean +distclean: clean + rm -f user_guide/checkers/extensions.rst user_guide/checkers/features.rst \ + user_guide/configuration/all-options.rst user_guide/messages/messages_overview.rst + +# Set PIP=true on the command line to skip installation of dependencies. +PIP = pip + +.PHONY html: install-dependencies +install-dependencies: + @echo "Install dependencies" + cd ../ && $(PIP) install -r doc/requirements.txt diff --git a/src/pylint/pylint-main/doc/additional_tools/pyreverse/configuration.rst b/src/pylint/pylint-main/doc/additional_tools/pyreverse/configuration.rst new file mode 100644 index 0000000..5967db2 --- /dev/null +++ b/src/pylint/pylint-main/doc/additional_tools/pyreverse/configuration.rst @@ -0,0 +1,201 @@ +.. This file is auto-generated. Make any changes to the associated +.. docs extension in 'doc/exts/pyreverse_configuration.py'. + + +Usage +##### + + +``pyreverse`` is run from the command line using the following syntax:: + + pyreverse [options] + +where ```` is one or more Python packages or modules to analyze. + +The available options are organized into the following categories: + +* :ref:`filtering-and-scope` - Control which classes and relationships appear in your diagrams +* :ref:`display-options` - Customize the visual appearance including colors and labels +* :ref:`output-control` - Select output formats and set the destination directory +* :ref:`project-configuration` - Define project settings like source roots and ignored files + + +.. _filtering-and-scope: + +Filtering and Scope +=================== + + +--all-ancestors +--------------- +*Show all ancestors of all classes in .* + +**Default:** ``None`` + + +--all-associated +---------------- +*Show all classes associated with the target classes, including indirect associations.* + +**Default:** ``None`` + + +--class +------- +*Create a class diagram with all classes related to ; this uses by default the options -ASmy* + +**Default:** ``None`` + + +--filter-mode +------------- +*Filter attributes and functions according to . Correct modes are: +'PUB_ONLY' filter all non public attributes [DEFAULT], equivalent to PRIVATE+SPECIAL +'ALL' no filter +'SPECIAL' filter Python special functions except constructor +'OTHER' filter protected and private attributes* + +**Default:** ``PUB_ONLY`` + + +--max-depth +----------- +*Maximum depth of packages/modules to include in the diagram, relative to the deepest specified package. A depth of 0 shows only the specified packages/modules, while 1 includes their immediate children, etc. When specifying nested packages, depth is calculated from the deepest package level. If not specified, all packages/modules in the hierarchy are shown.* + +**Default:** ``None`` + + +--show-ancestors +---------------- +*Show generations of ancestor classes not in .* + +**Default:** ``None`` + + +--show-associated +----------------- +*Show levels of associated classes not in .* + +**Default:** ``None`` + + +--show-builtin +-------------- +*Include builtin objects in representation of classes.* + +**Default:** ``False`` + + +--show-stdlib +------------- +*Include standard library objects in representation of classes.* + +**Default:** ``False`` + + + + +.. _display-options: + +Display Options +=============== + + +--color-palette +--------------- +*Comma separated list of colors to use for the package depth coloring.* + +**Default:** ``('#77AADD', '#99DDFF', '#44BB99', '#BBCC33', '#AAAA00', '#EEDD88', '#EE8866', '#FFAABB', '#DDDDDD')`` + + +--colorized +----------- +*Use colored output. Classes/modules of the same package get the same color.* + +**Default:** ``False`` + + +--max-color-depth +----------------- +*Use separate colors up to package depth of . Higher depths will reuse colors.* + +**Default:** ``2`` + + +--module-names +-------------- +*Include module name in the representation of classes.* + +**Default:** ``None`` + + +--no-standalone +--------------- +*Only show nodes with connections.* + +**Default:** ``False`` + + +--only-classnames +----------------- +*Don't show attributes and methods in the class boxes; this disables -f values.* + +**Default:** ``False`` + + + + +.. _output-control: + +Output Control +============== + + +--output +-------- +*Create a *. output file if format is available. Available formats are: .dot, .puml, .plantuml, .mmd, .html. Any other format will be tried to be created by using the 'dot' command line tool, which requires a graphviz installation. In this case, these additional formats are available (see `Graphviz output formats `_).* + +**Default:** ``dot`` + + +--output-directory +------------------ +*Set the output directory path.* + +**Default:** ``""`` + + + + +.. _project-configuration: + +Project Configuration +===================== + + +--ignore +-------- +*Files or directories to be skipped. They should be base names, not paths.* + +**Default:** ``('CVS',)`` + + +--project +--------- +*Set the project name. This will later be appended to the output file names.* + +**Default:** ``""`` + + +--source-roots +-------------- +*Add paths to the list of the source roots. Supports globbing patterns. The source root is an absolute path or a path relative to the current working directory used to determine a package namespace for modules located under the source root.* + +**Default:** ``()`` + + +--verbose +--------- +*Makes pyreverse more verbose/talkative. Mostly useful for debugging.* + +**Default:** ``False`` diff --git a/src/pylint/pylint-main/doc/additional_tools/pyreverse/index.rst b/src/pylint/pylint-main/doc/additional_tools/pyreverse/index.rst new file mode 100644 index 0000000..4dc8a9b --- /dev/null +++ b/src/pylint/pylint-main/doc/additional_tools/pyreverse/index.rst @@ -0,0 +1,40 @@ +.. _pyreverse: + +========= +Pyreverse +========= + +``pyreverse`` is a powerful tool that creates UML diagrams from your Python code. It helps you visualize: + +- Package dependencies and structure +- Class hierarchies and relationships +- Method and attribute organization + +Output Formats +============== + +``pyreverse`` supports multiple output formats: + +* Native formats: + * ``.dot``/``.gv`` (Graphviz) + * ``.puml``/``.plantuml`` (PlantUML) + * ``.mmd``/``.html`` (MermaidJS) + +* Additional formats (requires Graphviz installation): + * All `Graphviz output formats `_ (PNG, SVG, PDF, etc.) + * ``pyreverse`` first generates a temporary ``.gv`` file, which is then fed to Graphviz to generate the final image + +Getting Started +=============== + +Check out the :doc:`configuration` guide to learn about available options, or see :doc:`output_examples` +for sample diagrams and common use cases. + +.. toctree:: + :maxdepth: 2 + :caption: Pyreverse + :titlesonly: + :hidden: + + configuration + output_examples diff --git a/src/pylint/pylint-main/doc/additional_tools/pyreverse/output_examples.rst b/src/pylint/pylint-main/doc/additional_tools/pyreverse/output_examples.rst new file mode 100644 index 0000000..32fdfc8 --- /dev/null +++ b/src/pylint/pylint-main/doc/additional_tools/pyreverse/output_examples.rst @@ -0,0 +1,40 @@ +Example Output +############## + +Example diagrams generated with the ``.puml`` output format are shown below. + +Package Diagram +............... + +.. image:: ../../media/pyreverse_example_packages.png + :width: 344 + :height: 177 + :alt: Package diagram generated by pyreverse + :align: center + +Class Diagram +............. + +.. image:: ../../media/pyreverse_example_classes.png + :width: 625 + :height: 589 + :alt: Class diagram generated by pyreverse + :align: center + +Creating Class Diagrams for Specific Classes +'''''''''''''''''''''''''''''''''''''''''''' + +In many cases creating a single diagram depicting all classes in the project yields a rather unwieldy, giant diagram. +While limiting the input path to a single package or module can already help greatly to narrow down the scope, the ``-c`` option +provides another way to create a class diagram focusing on a single class and its collaborators. +For example, running:: + + pyreverse -ASmy -c pylint.checkers.classes.ClassChecker pylint + +will generate the full class and package diagrams for ``pylint``, but will additionally generate a file ``pylint.checkers.classes.ClassChecker.dot``: + +.. image:: ../../media/ClassChecker_diagram.png + :width: 757 + :height: 1452 + :alt: Package diagram generated by pyreverse + :align: center diff --git a/src/pylint/pylint-main/doc/additional_tools/symilar/index.rst b/src/pylint/pylint-main/doc/additional_tools/symilar/index.rst new file mode 100644 index 0000000..b79a835 --- /dev/null +++ b/src/pylint/pylint-main/doc/additional_tools/symilar/index.rst @@ -0,0 +1,37 @@ +.. _symilar: + +Symilar +------- + +The console script ``symilar`` finds copy pasted block of text in a set of files. It provides a command line interface to check only the ``duplicate-code`` message. + +It can be invoked with:: + + symilar [-d|--duplicates min_duplicated_lines] [-i|--ignore-comments] [--ignore-docstrings] [--ignore-imports] [--ignore-signatures] file1... + +All files that shall be checked have to be passed in explicitly, e.g.:: + + symilar foo.py, bar.py, subpackage/spam.py, subpackage/eggs.py + +``symilar`` produces output like the following:: + + 17 similar lines in 2 files + ==tests/data/clientmodule_test.py:3 + ==tests/data/suppliermodule_test.py:12 + class Ancestor: + """ Ancestor method """ + cls_member = DoNothing() + + def __init__(self, value): + local_variable = 0 + self.attr = 'this method shouldn\'t have a docstring' + self.__value = value + + def get_value(self): + """ nice docstring ;-) """ + return self.__value + + def set_value(self, value): + self.__value = value + return 'this method shouldn\'t have a docstring' + TOTAL lines=58 duplicates=17 percent=29.31 diff --git a/src/pylint/pylint-main/doc/conf.py b/src/pylint/pylint-main/doc/conf.py new file mode 100644 index 0000000..5abb8df --- /dev/null +++ b/src/pylint/pylint-main/doc/conf.py @@ -0,0 +1,310 @@ +# 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 + +from __future__ import annotations + +import os +import sys +from datetime import datetime + +# Pylint documentation build configuration file, created by +# sphinx-quickstart on Thu Apr 4 20:31:25 2013. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use 'os.path.abspath' to make it absolute, like shown here. +sys.path.append(os.path.abspath("exts")) +sys.path.append(os.path.abspath("..")) + +# pylint: disable=wrong-import-position +from pylint import __version__ +from pylint.__pkginfo__ import numversion + +# pylint: enable=wrong-import-position + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [ + "pylint_features", + "pylint_extensions", + "pylint_messages", + "pylint_options", + "pyreverse_configuration", + "sphinx.ext.autosectionlabel", + "sphinx.ext.intersphinx", + "sphinx_reredirects", +] + + +# Single file redirects are handled in this file and can be done by a pylint +# contributor. We use the following extension: +# https://documatt.gitlab.io/sphinx-reredirects/usage.html +# Directory redirects are handled in ReadTheDoc admin interface and can only be done +# by pylint maintainers at the following URL: +# https://readthedocs.org/dashboard/pylint/redirects/ +redirects: dict[str, str] = { + # "": "" + "additional_commands/index": "../index.html", + "development_guide/index": "api/index.html", + "development_guide/contribute": "../development_guide/contributor_guide/index.html", + "development_guide/contributor_guide": "contributor_guide/index.html", + "development_guide/profiling": "../development_guide/contributor_guide/profiling.html", + "development_guide/tests/index": "../contributor_guide/tests/index.html", + "development_guide/tests/install": "../contributor_guide/tests/install.html", + "development_guide/tests/launching_test": "../contributor_guide/tests/launching_test.html", + # There was a typo in the original file, don't fix. + "development_guide/tests/writting_test": "../contributor_guide/tests/writing_test.html", + "development/testing": "tests/index.html", + "how_tos/custom_checkers": "../development_guide/how_tos/custom_checkers.html", + "how_tos/index": "../development_guide/how_tos/index.html", + "how_tos/plugins": "../development_guide/how_tos/plugins.html", + "how_tos/transform_plugins": "../development_guide/how_tos/transform_plugins.html", + "intro": "index.html", + "messages/messages_introduction": "../user_guide/messages/index.html", + "messages/messages_list": "../user_guide/messages/messages_overview.html", + "support": "contact.html", + "technical_reference/c_extensions": "../user_guide/messages/error/no-member.html", + "technical_reference/extensions": "../user_guide/checkers/extensions.html", + "technical_reference/checkers": "../development_guide/technical_reference/checkers.html", + "technical_reference/features": "../user_guide/checkers/features.html", + "technical_reference/index": "../development_guide/technical_reference/index.html", + "technical_reference/startup": "../development_guide/technical_reference/startup.html", + "user_guide/configuration/naming-styles": "../user_guide/messages/convention/invalid-name.html", + "user_guide/ide_integration/flymake-emacs": "../installation/ide_integration/flymake-emacs.html", + "user_guide/ide_integration/ide-integration": "../installation/ide_integration/index.html", + "user_guide/ide-integration": "installation.html", + "user_guide/ide_integration/textmate": "../installation/ide_integration/textmate.html", + "user_guide/index": "installation/index.html", + "user_guide/message-control": "messages/message_control.html", + "user_guide/options": "configuration/all-options.html", + "user_guide/output": "usage/output.html", + "user_guide/pre-commit-integration": "installation/pre-commit-integration.html", + "user_guide/run": "usage/run.html", + "pyreverse": "additional_tools/pyreverse/index.html", + "symilar": "additional_tools/symilar/index.html", +} + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix of source filenames. +source_suffix = ".rst" + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The root toctree document. +root_doc = "index" + +# General information about the project. +project = "Pylint" +current_year = datetime.utcnow().year +contributors = "Logilab and Pylint contributors" +copyright = f"2003-{current_year}, {contributors}" # pylint: disable=redefined-builtin + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# The short X.Y version. +version = f"{numversion[0]}.{numversion[1]}" +# The full version, including alpha/beta/rc tags. +release = __version__ + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ["_build", "data/**", "whatsnew/fragments"] + +# The reST default role (used for this markup: `text`) to use for all documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "furo" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# Currently we use the default Furo configuration +# html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +# html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +html_last_updated_fmt = "%b %d, %Y" + +smartquotes = False + +# Custom sidebar templates, maps document names to template names. +# Currently we use the default Furo Sidebar +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = "Pylintdoc" + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +# latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +# latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ( + "index", + "Pylint.tex", + "Pylint Documentation", + contributors, + "manual", + ) +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +# latex_preamble = '' + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [("index", "pylint", "Pylint Documentation", [contributors], 1)] + +# pylint: disable-next=consider-using-namedtuple-or-dataclass +intersphinx_mapping = { + "astroid": ("https://pylint.readthedocs.io/projects/astroid/en/latest/", None), + "python": ("https://docs.python.org/3", None), +} + +# Prevent label issues due to colliding section names +# through including multiple documents +autosectionlabel_prefix_document = True + +# Permit duplicated titles in the resulting document. +# See https://github.com/pylint-dev/pylint/issues/7362#issuecomment-1256932866 +autosectionlabel_maxdepth = 2 + +linkcheck_ignore = [ + "https://github.com/pylint-dev/pylint/blob/main/pylint/extensions/.*" +] diff --git a/src/pylint/pylint-main/doc/contact.rst b/src/pylint/pylint-main/doc/contact.rst new file mode 100644 index 0000000..cd3594f --- /dev/null +++ b/src/pylint/pylint-main/doc/contact.rst @@ -0,0 +1,58 @@ +Contact +======= + +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 diff --git a/src/pylint/pylint-main/doc/data/messages/a/abstract-class-instantiated/bad.py b/src/pylint/pylint-main/doc/data/messages/a/abstract-class-instantiated/bad.py new file mode 100644 index 0000000..f514a5c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/abstract-class-instantiated/bad.py @@ -0,0 +1,10 @@ +import abc + + +class Animal(abc.ABC): + @abc.abstractmethod + def make_sound(self): + pass + + +sheep = Animal() # [abstract-class-instantiated] diff --git a/src/pylint/pylint-main/doc/data/messages/a/abstract-class-instantiated/good.py b/src/pylint/pylint-main/doc/data/messages/a/abstract-class-instantiated/good.py new file mode 100644 index 0000000..c9dbce1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/abstract-class-instantiated/good.py @@ -0,0 +1,15 @@ +import abc + + +class Animal(abc.ABC): + @abc.abstractmethod + def make_sound(self): + pass + + +class Sheep(Animal): + def make_sound(self): + print("bhaaaaa") + + +sheep = Sheep() diff --git a/src/pylint/pylint-main/doc/data/messages/a/abstract-method/bad/abstract_method.py b/src/pylint/pylint-main/doc/data/messages/a/abstract-method/bad/abstract_method.py new file mode 100644 index 0000000..35e5c81 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/abstract-method/bad/abstract_method.py @@ -0,0 +1,11 @@ +import abc + + +class WildAnimal: + @abc.abstractmethod + def make_sound(self): + pass + + +class Panther(WildAnimal): # [abstract-method] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/a/abstract-method/bad/function_raising_not_implemented_error.py b/src/pylint/pylint-main/doc/data/messages/a/abstract-method/bad/function_raising_not_implemented_error.py new file mode 100644 index 0000000..6a6a183 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/abstract-method/bad/function_raising_not_implemented_error.py @@ -0,0 +1,7 @@ +class Pet: + def make_sound(self): + raise NotImplementedError + + +class Cat(Pet): # [abstract-method] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/a/abstract-method/good/abstract_method.py b/src/pylint/pylint-main/doc/data/messages/a/abstract-method/good/abstract_method.py new file mode 100644 index 0000000..695443e --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/abstract-method/good/abstract_method.py @@ -0,0 +1,12 @@ +import abc + + +class WildAnimal: + @abc.abstractmethod + def make_sound(self): + pass + + +class Panther(WildAnimal): + def make_sound(self): + print("MEEEOW") diff --git a/src/pylint/pylint-main/doc/data/messages/a/abstract-method/good/function_raising_not_implemented_error.py b/src/pylint/pylint-main/doc/data/messages/a/abstract-method/good/function_raising_not_implemented_error.py new file mode 100644 index 0000000..d7635f2 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/abstract-method/good/function_raising_not_implemented_error.py @@ -0,0 +1,8 @@ +class Pet: + def make_sound(self): + raise NotImplementedError + + +class Cat(Pet): + def make_sound(self): + print("Meeeow") diff --git a/src/pylint/pylint-main/doc/data/messages/a/access-member-before-definition/bad.py b/src/pylint/pylint-main/doc/data/messages/a/access-member-before-definition/bad.py new file mode 100644 index 0000000..64f349f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/access-member-before-definition/bad.py @@ -0,0 +1,5 @@ +class Unicorn: + def __init__(self, fluffiness_level): + if self.fluffiness_level > 9000: # [access-member-before-definition] + print("It's OVER-FLUFFYYYY ! *crush glasses*") + self.fluffiness_level = fluffiness_level diff --git a/src/pylint/pylint-main/doc/data/messages/a/access-member-before-definition/good.py b/src/pylint/pylint-main/doc/data/messages/a/access-member-before-definition/good.py new file mode 100644 index 0000000..78d59fa --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/access-member-before-definition/good.py @@ -0,0 +1,5 @@ +class Unicorn: + def __init__(self, fluffiness_level): + self.fluffiness_level = fluffiness_level + if self.fluffiness_level > 9000: + print("It's OVER-FLUFFYYYY ! *crush glasses*") diff --git a/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/bad.py b/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/bad.py new file mode 100644 index 0000000..32da7dd --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/bad.py @@ -0,0 +1 @@ +string = "\z" # [syntax-error] diff --git a/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/details.rst b/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/details.rst new file mode 100644 index 0000000..7f73b51 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/details.rst @@ -0,0 +1,6 @@ +``\z`` is same as ``\\z`` because there's no escape sequence for ``z``. But it is not clear +for the reader of the code. + +The only reason this is demonstrated to raise ``syntax-error`` is because +pylint's CI now runs on Python 3.12, where this truly raises a ``SyntaxError``. +We hope to address this discrepancy in the documentation in the future. diff --git a/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/good/double_escape.py b/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/good/double_escape.py new file mode 100644 index 0000000..1b2c0c8 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/good/double_escape.py @@ -0,0 +1 @@ +string = "\\z" diff --git a/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/good/existing_escape_sequence.py b/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/good/existing_escape_sequence.py new file mode 100644 index 0000000..511425a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/good/existing_escape_sequence.py @@ -0,0 +1 @@ +string = "\t" diff --git a/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/good/r_prefix.py b/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/good/r_prefix.py new file mode 100644 index 0000000..e78a9ae --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/good/r_prefix.py @@ -0,0 +1 @@ +string = r"\z" diff --git a/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/related.rst b/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/related.rst new file mode 100644 index 0000000..cb63bfd --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/anomalous-backslash-in-string/related.rst @@ -0,0 +1,2 @@ +- `String and Bytes literals `_ +- `Long form stackoverflow explanation `_ diff --git a/src/pylint/pylint-main/doc/data/messages/a/anomalous-unicode-escape-in-string/bad.py b/src/pylint/pylint-main/doc/data/messages/a/anomalous-unicode-escape-in-string/bad.py new file mode 100644 index 0000000..21d25ea --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/anomalous-unicode-escape-in-string/bad.py @@ -0,0 +1 @@ +print(b"\u%b" % b"0394") # [syntax-error] diff --git a/src/pylint/pylint-main/doc/data/messages/a/anomalous-unicode-escape-in-string/good.py b/src/pylint/pylint-main/doc/data/messages/a/anomalous-unicode-escape-in-string/good.py new file mode 100644 index 0000000..c5f4cf4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/anomalous-unicode-escape-in-string/good.py @@ -0,0 +1 @@ +print(b"\\u%b" % b"0394") diff --git a/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/bad.py b/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/bad.py new file mode 100644 index 0000000..489ac9d --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/bad.py @@ -0,0 +1,8 @@ +class Drink: + def mix(self, fluid_one, fluid_two): + return fluid_one + fluid_two + + +class Cocktail(Drink): + def mix(self, fluid_one, fluid_two, alcoholic_fluid): # [arguments-differ] + return fluid_one + fluid_two + alcoholic_fluid diff --git a/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/details.rst b/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/details.rst new file mode 100644 index 0000000..ba265b2 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/details.rst @@ -0,0 +1,9 @@ +``argument-differ`` denotes an issue with the Liskov Substitution Principle. +This means that the code in question violates an important design principle which does not have +one single solution. We recommend to search online for the best solution in your case. + +To give some examples of potential solutions: + +* Add the argument to the parent class +* Remove the inheritance completely +* Add default arguments to the child class diff --git a/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/good/add_option_in_base_class.py b/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/good/add_option_in_base_class.py new file mode 100644 index 0000000..35a1095 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/good/add_option_in_base_class.py @@ -0,0 +1,20 @@ +""" +Here we assume that drink and cocktail are the same thing and should actually +inherit from each over. We also assume that 'Drink' are 'Cocktail' without +alcohol (we added the alcohol option in the base class). + +This permit to not have to modify the cocktails calls downstream but the case where +an alcohol is mixed in a soft drink will need to be handled. +""" + + +class Drink: + def mix(self, fluid_one, fluid_two, alcoholic_fluid=None): + # if alcoholic_fluid is not None: + # raise Exception(f"This soft drink has {alcoholic_fluid} in it !") + return fluid_one + fluid_two + + +class Cocktail(Drink): + def mix(self, fluid_one, fluid_two, alcoholic_fluid): + return fluid_one + fluid_two + alcoholic_fluid diff --git a/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/good/default_value.py b/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/good/default_value.py new file mode 100644 index 0000000..7104e4a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/good/default_value.py @@ -0,0 +1,18 @@ +""" +Here we assume that drink and cocktail are the same thing and should actually +inherit from each over. We also assume that any Cocktail can be treated like +a Drink (if you add beer to it). + +This permit to not have to modify the calls downstream and causes the least +amount of disturbance at the cost of making cocktails beer-based implicitly. +""" + + +class Drink: + def mix(self, fluid_one, fluid_two): + return fluid_one + fluid_two + + +class Cocktail(Drink): + def mix(self, fluid_one, fluid_two, alcoholic_fluid="Beer"): + return fluid_one + fluid_two + alcoholic_fluid diff --git a/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/good/no_inheritance.py b/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/good/no_inheritance.py new file mode 100644 index 0000000..2fd2822 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/good/no_inheritance.py @@ -0,0 +1,19 @@ +""" +Here we assume that 'Drink' and 'Cocktail' are different things and should +not be treated together like if they were the same thing. + +This will force some downstream changes and force the API user to make a +conscious decision about the alcoholic content of its drink when using the +API. For example, it's impossible to create a mojito with beer without +explicitly wanting to, or to add an alcohol to a soft-drink. +""" + + +class Drink: + def mix(self, fluid_one, fluid_two): + return fluid_one + fluid_two + + +class Cocktail: + def mix(self, fluid_one, fluid_two, alcoholic_fluid): + return fluid_one + fluid_two + alcoholic_fluid diff --git a/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/related.rst b/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/related.rst new file mode 100644 index 0000000..db005e3 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/arguments-differ/related.rst @@ -0,0 +1 @@ +- `Liskov Substitution Principle `_ diff --git a/src/pylint/pylint-main/doc/data/messages/a/arguments-out-of-order/bad.py b/src/pylint/pylint-main/doc/data/messages/a/arguments-out-of-order/bad.py new file mode 100644 index 0000000..06f6896 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/arguments-out-of-order/bad.py @@ -0,0 +1,13 @@ +def function_3_args(first_argument, second_argument, third_argument): + """Three arguments function""" + return first_argument, second_argument, third_argument + + +def args_out_of_order(): + first_argument = 1 + second_argument = 2 + third_argument = 3 + + function_3_args( # [arguments-out-of-order] + first_argument, third_argument, second_argument + ) diff --git a/src/pylint/pylint-main/doc/data/messages/a/arguments-out-of-order/good.py b/src/pylint/pylint-main/doc/data/messages/a/arguments-out-of-order/good.py new file mode 100644 index 0000000..06ce726 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/arguments-out-of-order/good.py @@ -0,0 +1,11 @@ +def function_3_args(first_argument, second_argument, third_argument): + """Three arguments function""" + return first_argument, second_argument, third_argument + + +def args_out_of_order(): + first_argument = 1 + second_argument = 2 + third_argument = 3 + + function_3_args(first_argument, second_argument, third_argument) diff --git a/src/pylint/pylint-main/doc/data/messages/a/arguments-renamed/bad.py b/src/pylint/pylint-main/doc/data/messages/a/arguments-renamed/bad.py new file mode 100644 index 0000000..98f53a1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/arguments-renamed/bad.py @@ -0,0 +1,15 @@ +class Fruit: + def brew(self, ingredient_name: str): + print(f"Brewing a {type(self)} with {ingredient_name}") + + +class Apple(Fruit): ... + + +class Orange(Fruit): + def brew(self, flavor: str): # [arguments-renamed] + print(f"Brewing an orange with {flavor}") + + +for fruit, ingredient_name in [[Orange(), "thyme"], [Apple(), "cinnamon"]]: + fruit.brew(ingredient_name=ingredient_name) diff --git a/src/pylint/pylint-main/doc/data/messages/a/arguments-renamed/good.py b/src/pylint/pylint-main/doc/data/messages/a/arguments-renamed/good.py new file mode 100644 index 0000000..e150d65 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/arguments-renamed/good.py @@ -0,0 +1,15 @@ +class Fruit: + def brew(self, ingredient_name: str): + print(f"Brewing a {type(self)} with {ingredient_name}") + + +class Apple(Fruit): ... + + +class Orange(Fruit): + def brew(self, ingredient_name: str): + print(f"Brewing an orange with {ingredient_name}") + + +for fruit, ingredient_name in [[Orange(), "thyme"], [Apple(), "cinnamon"]]: + fruit.brew(ingredient_name=ingredient_name) diff --git a/src/pylint/pylint-main/doc/data/messages/a/assert-on-string-literal/bad.py b/src/pylint/pylint-main/doc/data/messages/a/assert-on-string-literal/bad.py new file mode 100644 index 0000000..adbe2a4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assert-on-string-literal/bad.py @@ -0,0 +1,3 @@ +def test_division(): + a = 9 / 3 + assert "No ZeroDivisionError were raised" # [assert-on-string-literal] diff --git a/src/pylint/pylint-main/doc/data/messages/a/assert-on-string-literal/details.rst b/src/pylint/pylint-main/doc/data/messages/a/assert-on-string-literal/details.rst new file mode 100644 index 0000000..188d881 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assert-on-string-literal/details.rst @@ -0,0 +1,4 @@ +Directly asserting a string literal will always pass. The solution is to +test something that could fail, or not assert at all. + +For ``unittest`` assertions there is the similar :ref:`redundant-unittest-assert` message. diff --git a/src/pylint/pylint-main/doc/data/messages/a/assert-on-string-literal/good.py b/src/pylint/pylint-main/doc/data/messages/a/assert-on-string-literal/good.py new file mode 100644 index 0000000..ba27075 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assert-on-string-literal/good.py @@ -0,0 +1,3 @@ +def test_division(): + a = 9 / 3 + assert a == 3 diff --git a/src/pylint/pylint-main/doc/data/messages/a/assert-on-string-literal/related.rst b/src/pylint/pylint-main/doc/data/messages/a/assert-on-string-literal/related.rst new file mode 100644 index 0000000..ee8d29f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assert-on-string-literal/related.rst @@ -0,0 +1,3 @@ +- `Tests without assertion `_ +- `Testing that there is no error raised `_ +- `Parametrizing conditional raising `_ diff --git a/src/pylint/pylint-main/doc/data/messages/a/assert-on-tuple/bad.py b/src/pylint/pylint-main/doc/data/messages/a/assert-on-tuple/bad.py new file mode 100644 index 0000000..ffcc34c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assert-on-tuple/bad.py @@ -0,0 +1 @@ +assert (1, None) # [assert-on-tuple] diff --git a/src/pylint/pylint-main/doc/data/messages/a/assert-on-tuple/details.rst b/src/pylint/pylint-main/doc/data/messages/a/assert-on-tuple/details.rst new file mode 100644 index 0000000..6efb449 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assert-on-tuple/details.rst @@ -0,0 +1,4 @@ +Directly asserting a non-empty tuple will always pass. The solution is to + test something that could fail, or not assert at all. + + For ``unittest`` assertions there is the similar :ref:`redundant-unittest-assert` message. diff --git a/src/pylint/pylint-main/doc/data/messages/a/assert-on-tuple/good.py b/src/pylint/pylint-main/doc/data/messages/a/assert-on-tuple/good.py new file mode 100644 index 0000000..cea57cf --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assert-on-tuple/good.py @@ -0,0 +1,3 @@ +x, y = (1, None) +assert x +assert y diff --git a/src/pylint/pylint-main/doc/data/messages/a/assigning-non-slot/bad.py b/src/pylint/pylint-main/doc/data/messages/a/assigning-non-slot/bad.py new file mode 100644 index 0000000..506ad42 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assigning-non-slot/bad.py @@ -0,0 +1,10 @@ +class Student: + __slots__ = ("name",) + + def __init__(self, name, surname): + self.name = name + self.surname = surname # [assigning-non-slot] + self.setup() + + def setup(self): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/a/assigning-non-slot/good.py b/src/pylint/pylint-main/doc/data/messages/a/assigning-non-slot/good.py new file mode 100644 index 0000000..7337286 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assigning-non-slot/good.py @@ -0,0 +1,10 @@ +class Student: + __slots__ = ("name", "surname") + + def __init__(self, name, surname): + self.name = name + self.surname = surname + self.setup() + + def setup(self): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/a/assignment-from-no-return/bad.py b/src/pylint/pylint-main/doc/data/messages/a/assignment-from-no-return/bad.py new file mode 100644 index 0000000..ea3822a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assignment-from-no-return/bad.py @@ -0,0 +1,5 @@ +def add(x, y): + print(x + y) + + +value = add(10, 10) # [assignment-from-no-return] diff --git a/src/pylint/pylint-main/doc/data/messages/a/assignment-from-no-return/good.py b/src/pylint/pylint-main/doc/data/messages/a/assignment-from-no-return/good.py new file mode 100644 index 0000000..c019007 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assignment-from-no-return/good.py @@ -0,0 +1,5 @@ +def add(x, y): + return x + y + + +value = add(10, 10) diff --git a/src/pylint/pylint-main/doc/data/messages/a/assignment-from-none/bad.py b/src/pylint/pylint-main/doc/data/messages/a/assignment-from-none/bad.py new file mode 100644 index 0000000..033bd89 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assignment-from-none/bad.py @@ -0,0 +1,5 @@ +def function(): + return None + + +f = function() # [assignment-from-none] diff --git a/src/pylint/pylint-main/doc/data/messages/a/assignment-from-none/good.py b/src/pylint/pylint-main/doc/data/messages/a/assignment-from-none/good.py new file mode 100644 index 0000000..d2f4cbc --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/assignment-from-none/good.py @@ -0,0 +1,5 @@ +def function(): + return None + + +f = function() if function() else 1 diff --git a/src/pylint/pylint-main/doc/data/messages/a/astroid-error/details.rst b/src/pylint/pylint-main/doc/data/messages/a/astroid-error/details.rst new file mode 100644 index 0000000..96e8f7a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/astroid-error/details.rst @@ -0,0 +1,2 @@ +This is a message linked to an internal problem in pylint. There's nothing to change in your code, +but maybe in pylint's configuration or installation. diff --git a/src/pylint/pylint-main/doc/data/messages/a/async-context-manager-with-regular-with/bad.py b/src/pylint/pylint-main/doc/data/messages/a/async-context-manager-with-regular-with/bad.py new file mode 100644 index 0000000..72b5201 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/async-context-manager-with-regular-with/bad.py @@ -0,0 +1,10 @@ +from contextlib import asynccontextmanager + + +@asynccontextmanager +async def async_context(): + yield + + +with async_context(): # [async-context-manager-with-regular-with] + print("This will cause an error at runtime") diff --git a/src/pylint/pylint-main/doc/data/messages/a/async-context-manager-with-regular-with/good.py b/src/pylint/pylint-main/doc/data/messages/a/async-context-manager-with-regular-with/good.py new file mode 100644 index 0000000..f9882a4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/async-context-manager-with-regular-with/good.py @@ -0,0 +1,12 @@ +import asyncio +from contextlib import asynccontextmanager + + +@asynccontextmanager +async def async_context(): + yield + + +async def main(): + async with async_context(): + print("This works correctly") diff --git a/src/pylint/pylint-main/doc/data/messages/a/async-context-manager-with-regular-with/related.rst b/src/pylint/pylint-main/doc/data/messages/a/async-context-manager-with-regular-with/related.rst new file mode 100644 index 0000000..642c859 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/async-context-manager-with-regular-with/related.rst @@ -0,0 +1,2 @@ +- `PEP 492 - Coroutines with async and await syntax `_ +- `contextlib.asynccontextmanager `_ diff --git a/src/pylint/pylint-main/doc/data/messages/a/attribute-defined-outside-init/bad.py b/src/pylint/pylint-main/doc/data/messages/a/attribute-defined-outside-init/bad.py new file mode 100644 index 0000000..e62884d --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/attribute-defined-outside-init/bad.py @@ -0,0 +1,3 @@ +class Student: + def register(self): + self.is_registered = True # [attribute-defined-outside-init] diff --git a/src/pylint/pylint-main/doc/data/messages/a/attribute-defined-outside-init/good.py b/src/pylint/pylint-main/doc/data/messages/a/attribute-defined-outside-init/good.py new file mode 100644 index 0000000..cc7d7ac --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/attribute-defined-outside-init/good.py @@ -0,0 +1,6 @@ +class Student: + def __init__(self): + self.is_registered = False + + def register(self): + self.is_registered = True diff --git a/src/pylint/pylint-main/doc/data/messages/a/await-outside-async/bad.py b/src/pylint/pylint-main/doc/data/messages/a/await-outside-async/bad.py new file mode 100644 index 0000000..35fd8c3 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/await-outside-async/bad.py @@ -0,0 +1,5 @@ +import asyncio + + +def main(): + await asyncio.sleep(1) # [await-outside-async] diff --git a/src/pylint/pylint-main/doc/data/messages/a/await-outside-async/good.py b/src/pylint/pylint-main/doc/data/messages/a/await-outside-async/good.py new file mode 100644 index 0000000..231794b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/await-outside-async/good.py @@ -0,0 +1,5 @@ +import asyncio + + +async def main(): + await asyncio.sleep(1) diff --git a/src/pylint/pylint-main/doc/data/messages/a/await-outside-async/related.rst b/src/pylint/pylint-main/doc/data/messages/a/await-outside-async/related.rst new file mode 100644 index 0000000..6cc66c6 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/a/await-outside-async/related.rst @@ -0,0 +1 @@ +- `PEP 492 `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-builtin/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-builtin/bad.py new file mode 100644 index 0000000..1c60815 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-builtin/bad.py @@ -0,0 +1,2 @@ +numbers = list(map(lambda x: 2 * x, [1, 2, 3])) # [bad-builtin] +print(numbers) diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-builtin/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-builtin/good.py new file mode 100644 index 0000000..c56dbfb --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-builtin/good.py @@ -0,0 +1,2 @@ +numbers = [2 * x for x in [1, 2, 3]] +print(numbers) diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-builtin/pylintrc b/src/pylint/pylint-main/doc/data/messages/b/bad-builtin/pylintrc new file mode 100644 index 0000000..d5dfb0c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-builtin/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins = pylint.extensions.bad_builtin diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/bad/parrot.py b/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/bad/parrot.py new file mode 100644 index 0000000..c3ab4d3 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/bad/parrot.py @@ -0,0 +1,7 @@ +shop = { + # animal: (specie, descriptions) + "parrot": ("Norvegian blue", ("restin'", "remarkable", "beautiful plumage")), +} + +if "parrot" in shop is "restin'": # [bad-chained-comparison] + print("Hellooooo, Pooolllllyyy ! WAAAAKEEY, WAKKEEEY !") diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/bad/xor.py b/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/bad/xor.py new file mode 100644 index 0000000..09e3ab6 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/bad/xor.py @@ -0,0 +1,5 @@ +def 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." + ) diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/good/parrot.py b/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/good/parrot.py new file mode 100644 index 0000000..17f316f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/good/parrot.py @@ -0,0 +1,7 @@ +shop = { + # 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 !") diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/good/xor.py b/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/good/xor.py new file mode 100644 index 0000000..79bb641 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/good/xor.py @@ -0,0 +1,5 @@ +def 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." + ) diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/related.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/related.rst new file mode 100644 index 0000000..620ba6d --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-chained-comparison/related.rst @@ -0,0 +1 @@ +- `Comparison Chaining `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-classmethod-argument/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-classmethod-argument/bad.py new file mode 100644 index 0000000..b8c6d02 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-classmethod-argument/bad.py @@ -0,0 +1,4 @@ +class Klass: + @classmethod + def get_instance(self): # [bad-classmethod-argument] + return self() diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-classmethod-argument/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-classmethod-argument/good.py new file mode 100644 index 0000000..6097f1e --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-classmethod-argument/good.py @@ -0,0 +1,4 @@ +class Klass: + @classmethod + def get_instance(cls): + return cls() diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-configuration-section/details.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-configuration-section/details.rst new file mode 100644 index 0000000..86035a5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-configuration-section/details.rst @@ -0,0 +1,2 @@ +This 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). diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/bad.py new file mode 100644 index 0000000..bd800a4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/bad.py @@ -0,0 +1,3 @@ +def foo(): # [bad-docstring-quotes] + "Docstring." + return diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/details.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/details.rst new file mode 100644 index 0000000..2a3add6 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/details.rst @@ -0,0 +1,2 @@ +From `PEP 257`: + "For consistency, always use ``"""triple double quotes"""`` around docstrings." diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/good.py new file mode 100644 index 0000000..e5f6ceb --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/good.py @@ -0,0 +1,3 @@ +def foo(): + """Docstring.""" + return diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/pylintrc b/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/pylintrc new file mode 100644 index 0000000..6acf217 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/pylintrc @@ -0,0 +1,2 @@ +[main] +load-plugins=pylint.extensions.docstyle diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/related.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/related.rst new file mode 100644 index 0000000..bec6174 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-docstring-quotes/related.rst @@ -0,0 +1 @@ +- `PEP 257 – Docstring Conventions `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-dunder-name/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-dunder-name/bad.py new file mode 100644 index 0000000..f01f650 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-dunder-name/bad.py @@ -0,0 +1,6 @@ +class Apples: + def _init_(self): # [bad-dunder-name] + pass + + def __hello__(self): # [bad-dunder-name] + print("hello") diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-dunder-name/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-dunder-name/good.py new file mode 100644 index 0000000..4f0adb9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-dunder-name/good.py @@ -0,0 +1,6 @@ +class Apples: + def __init__(self): + pass + + def hello(self): + print("hello") diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-dunder-name/pylintrc b/src/pylint/pylint-main/doc/data/messages/b/bad-dunder-name/pylintrc new file mode 100644 index 0000000..c709805 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-dunder-name/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins=pylint.extensions.dunder diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-except-order/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-except-order/bad.py new file mode 100644 index 0000000..482b515 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-except-order/bad.py @@ -0,0 +1,8 @@ +try: + 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 diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-except-order/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-except-order/good.py new file mode 100644 index 0000000..e9cd318 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-except-order/good.py @@ -0,0 +1,6 @@ +try: + print(int(input())) +except TypeError: + raise +except Exception: + raise diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-exception-cause/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-exception-cause/bad.py new file mode 100644 index 0000000..ad4228a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-exception-cause/bad.py @@ -0,0 +1,8 @@ +def 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 diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-exception-cause/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-exception-cause/good.py new file mode 100644 index 0000000..3ccc47b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-exception-cause/good.py @@ -0,0 +1,7 @@ +def 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 diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-exception-cause/related.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-exception-cause/related.rst new file mode 100644 index 0000000..a51de77 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-exception-cause/related.rst @@ -0,0 +1,2 @@ +- `The raise statement `_ +- `Explicit Exception Chaining `_ per PEP 3134 diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-file-encoding/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-file-encoding/bad.py new file mode 100644 index 0000000..a4ab46e --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-file-encoding/bad.py @@ -0,0 +1 @@ +# coding: latin_1 # [bad-file-encoding] diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-file-encoding/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-file-encoding/good.py new file mode 100644 index 0000000..e69de29 diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-format-character/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-format-character/bad.py new file mode 100644 index 0000000..3925849 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-format-character/bad.py @@ -0,0 +1 @@ +print("%s %z" % ("hello", "world")) # [bad-format-character] diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-format-character/details.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-format-character/details.rst new file mode 100644 index 0000000..9473396 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-format-character/details.rst @@ -0,0 +1,2 @@ +This check is currently only active for "old-style" string formatting as seen in the examples. +See `Issue #6085 `_ for more information. diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-format-character/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-format-character/good.py new file mode 100644 index 0000000..d8791a7 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-format-character/good.py @@ -0,0 +1 @@ +print("%s %s" % ("hello", "world")) diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-format-character/related.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-format-character/related.rst new file mode 100644 index 0000000..b6aadf5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-format-character/related.rst @@ -0,0 +1,2 @@ +- `Format String Syntax `_ +- `PyFormat `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-format-string-key/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-format-string-key/bad.py new file mode 100644 index 0000000..346d02d --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-format-string-key/bad.py @@ -0,0 +1 @@ +print("%(one)d" % {"one": 1, 2: 2}) # [bad-format-string-key] diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-format-string-key/details.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-format-string-key/details.rst new file mode 100644 index 0000000..321b4a0 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-format-string-key/details.rst @@ -0,0 +1,6 @@ +This 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. diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-format-string-key/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-format-string-key/good.py new file mode 100644 index 0000000..db7cfde --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-format-string-key/good.py @@ -0,0 +1 @@ +print("%(one)d, %(two)d" % {"one": 1, "two": 2}) diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-format-string/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-format-string/bad.py new file mode 100644 index 0000000..4cb8112 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-format-string/bad.py @@ -0,0 +1 @@ +print("{a[0] + a[1]}".format(a=[0, 1])) # [bad-format-string] diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-format-string/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-format-string/good.py new file mode 100644 index 0000000..10475fd --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-format-string/good.py @@ -0,0 +1 @@ +print("{a[0]} + {a[1]}".format(a=[0, 1])) diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-format-string/related.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-format-string/related.rst new file mode 100644 index 0000000..b6aadf5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-format-string/related.rst @@ -0,0 +1,2 @@ +- `Format String Syntax `_ +- `PyFormat `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-indentation/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-indentation/bad.py new file mode 100644 index 0000000..dd5a8d9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-indentation/bad.py @@ -0,0 +1,2 @@ +if input(): + print('yes') # [bad-indentation] diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-indentation/details.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-indentation/details.rst new file mode 100644 index 0000000..1403e99 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-indentation/details.rst @@ -0,0 +1 @@ +The option ``--indent-string`` can be used to set the indentation unit for this check. diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-indentation/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-indentation/good.py new file mode 100644 index 0000000..e7ba80a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-indentation/good.py @@ -0,0 +1,2 @@ +if input(): + print("yes") diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-inline-option/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-inline-option/bad.py new file mode 100644 index 0000000..b244da9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-inline-option/bad.py @@ -0,0 +1,2 @@ +# 2:[bad-inline-option] +# pylint: disable line-too-long diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-inline-option/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-inline-option/good.py new file mode 100644 index 0000000..9799fff --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-inline-option/good.py @@ -0,0 +1 @@ +# pylint: disable=line-too-long diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-mcs-classmethod-argument/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-mcs-classmethod-argument/bad.py new file mode 100644 index 0000000..1cc79be --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-mcs-classmethod-argument/bad.py @@ -0,0 +1,4 @@ +class Meta(type): + @classmethod + def foo(some): # [bad-mcs-classmethod-argument] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-mcs-classmethod-argument/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-mcs-classmethod-argument/good.py new file mode 100644 index 0000000..544fd54 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-mcs-classmethod-argument/good.py @@ -0,0 +1,4 @@ +class Meta(type): + @classmethod + def foo(mcs): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-mcs-method-argument/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-mcs-method-argument/bad.py new file mode 100644 index 0000000..4bf47b2 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-mcs-method-argument/bad.py @@ -0,0 +1,3 @@ +class Meta(type): + def func(some): # [bad-mcs-method-argument] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-mcs-method-argument/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-mcs-method-argument/good.py new file mode 100644 index 0000000..2ba1252 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-mcs-method-argument/good.py @@ -0,0 +1,3 @@ +class Meta(type): + def func(cls): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-open-mode/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-open-mode/bad.py new file mode 100644 index 0000000..59ad392 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-open-mode/bad.py @@ -0,0 +1,3 @@ +def open_and_get_content(file_path): + with open(file_path, "rwx") as file: # [bad-open-mode] + return file.read() diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-open-mode/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-open-mode/good.py new file mode 100644 index 0000000..b892c03 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-open-mode/good.py @@ -0,0 +1,3 @@ +def open_and_get_content(file_path): + with open(file_path, "r") as file: + return file.read() diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-plugin-value/details.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-plugin-value/details.rst new file mode 100644 index 0000000..5beb0bd --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-plugin-value/details.rst @@ -0,0 +1,14 @@ +One 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. diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-reversed-sequence/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-reversed-sequence/bad.py new file mode 100644 index 0000000..19c5d1a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-reversed-sequence/bad.py @@ -0,0 +1 @@ +reversed({1, 2, 3, 4}) # [bad-reversed-sequence] diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-reversed-sequence/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-reversed-sequence/good.py new file mode 100644 index 0000000..d396218 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-reversed-sequence/good.py @@ -0,0 +1 @@ +reversed([1, 2, 3, 4]) diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-staticmethod-argument/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-staticmethod-argument/bad.py new file mode 100644 index 0000000..a46d65a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-staticmethod-argument/bad.py @@ -0,0 +1,4 @@ +class Wolf: + @staticmethod + def eat(self): # [bad-staticmethod-argument] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-staticmethod-argument/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-staticmethod-argument/good.py new file mode 100644 index 0000000..7ad83f4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-staticmethod-argument/good.py @@ -0,0 +1,4 @@ +class Wolf: + @staticmethod + def eat(sheep): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/bad/hello_world.py b/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/bad/hello_world.py new file mode 100644 index 0000000..606ce77 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/bad/hello_world.py @@ -0,0 +1,2 @@ +"Hello World".strip("Hello") # [bad-str-strip-call] +# >>> ' World' diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/bad/remove_abc_from_both_side.py b/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/bad/remove_abc_from_both_side.py new file mode 100644 index 0000000..e2d5f2c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/bad/remove_abc_from_both_side.py @@ -0,0 +1,2 @@ +"abcbc def bacabc".strip("abcbc ") # [bad-str-strip-call] +# >>> 'def' diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/details.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/details.rst new file mode 100644 index 0000000..b2cc942 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/details.rst @@ -0,0 +1,7 @@ +A 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. diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/good/hello_world.py b/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/good/hello_world.py new file mode 100644 index 0000000..f96344f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/good/hello_world.py @@ -0,0 +1,2 @@ +"Hello World".strip("Helo") +# >>> ' World' diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/good/remove_abc_from_both_side.py b/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/good/remove_abc_from_both_side.py new file mode 100644 index 0000000..fea23df --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/good/remove_abc_from_both_side.py @@ -0,0 +1,2 @@ +"abcbc def bacabc".strip("abc ") +# >>> 'def' diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/related.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/related.rst new file mode 100644 index 0000000..db9ab44 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-str-strip-call/related.rst @@ -0,0 +1 @@ +- Documentation: `str.strip([chars]) `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-string-format-type/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-string-format-type/bad.py new file mode 100644 index 0000000..a58a5ba --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-string-format-type/bad.py @@ -0,0 +1 @@ +print("%d" % "1") # [bad-string-format-type] diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-string-format-type/details.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-string-format-type/details.rst new file mode 100644 index 0000000..c607384 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-string-format-type/details.rst @@ -0,0 +1,2 @@ +This check is currently only active for "old-style" string formatting as seen in the examples. +See `Issue #6085 `_ for more information. diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-string-format-type/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-string-format-type/good.py new file mode 100644 index 0000000..00ee8af --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-string-format-type/good.py @@ -0,0 +1 @@ +print("%d" % 1) diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-string-format-type/related.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-string-format-type/related.rst new file mode 100644 index 0000000..b6aadf5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-string-format-type/related.rst @@ -0,0 +1,2 @@ +- `Format String Syntax `_ +- `PyFormat `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-super-call/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-super-call/bad.py new file mode 100644 index 0000000..625a70e --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-super-call/bad.py @@ -0,0 +1,12 @@ +class Animal: + pass + + +class Tree: + pass + + +class Cat(Animal): + def __init__(self): + super(Tree, self).__init__() # [bad-super-call] + super(Animal, self).__init__() diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-super-call/details.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-super-call/details.rst new file mode 100644 index 0000000..e5b0ab5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-super-call/details.rst @@ -0,0 +1,7 @@ +In 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()``. diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-super-call/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-super-call/good.py new file mode 100644 index 0000000..66152bc --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-super-call/good.py @@ -0,0 +1,11 @@ +class Animal: + pass + + +class Tree: + pass + + +class Cat(Animal): + def __init__(self): + super(Animal, self).__init__() diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-super-call/related.rst b/src/pylint/pylint-main/doc/data/messages/b/bad-super-call/related.rst new file mode 100644 index 0000000..5189197 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-super-call/related.rst @@ -0,0 +1 @@ +- `Documentation for super() `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-thread-instantiation/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bad-thread-instantiation/bad.py new file mode 100644 index 0000000..20fa72f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-thread-instantiation/bad.py @@ -0,0 +1,9 @@ +import threading + + +def thread_target(n): + print(n**2) + + +thread = threading.Thread(lambda: None) # [bad-thread-instantiation] +thread.start() diff --git a/src/pylint/pylint-main/doc/data/messages/b/bad-thread-instantiation/good.py b/src/pylint/pylint-main/doc/data/messages/b/bad-thread-instantiation/good.py new file mode 100644 index 0000000..0dce7c3 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bad-thread-instantiation/good.py @@ -0,0 +1,9 @@ +import threading + + +def thread_target(n): + print(n**2) + + +thread = threading.Thread(target=thread_target, args=(10,)) +thread.start() diff --git a/src/pylint/pylint-main/doc/data/messages/b/bare-except/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bare-except/bad.py new file mode 100644 index 0000000..33dea31 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bare-except/bad.py @@ -0,0 +1,4 @@ +try: + import platform_specific_module +except: # [bare-except] + platform_specific_module = None diff --git a/src/pylint/pylint-main/doc/data/messages/b/bare-except/details.rst b/src/pylint/pylint-main/doc/data/messages/b/bare-except/details.rst new file mode 100644 index 0000000..e93c7ea --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bare-except/details.rst @@ -0,0 +1,3 @@ +A 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. diff --git a/src/pylint/pylint-main/doc/data/messages/b/bare-except/good.py b/src/pylint/pylint-main/doc/data/messages/b/bare-except/good.py new file mode 100644 index 0000000..24baac9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bare-except/good.py @@ -0,0 +1,4 @@ +try: + import platform_specific_module +except ImportError: + platform_specific_module = None diff --git a/src/pylint/pylint-main/doc/data/messages/b/bare-except/related.rst b/src/pylint/pylint-main/doc/data/messages/b/bare-except/related.rst new file mode 100644 index 0000000..afbc33f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bare-except/related.rst @@ -0,0 +1,3 @@ +- `Programming recommendation in PEP8 `_ +- `PEP 760 – No More Bare Excepts (Rejected) `_ +- `Discussion about PEP 760 `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/bare-name-capture-pattern/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bare-name-capture-pattern/bad.py new file mode 100644 index 0000000..4fad74f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bare-name-capture-pattern/bad.py @@ -0,0 +1,13 @@ +red = 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 :(") diff --git a/src/pylint/pylint-main/doc/data/messages/b/bare-name-capture-pattern/good.py b/src/pylint/pylint-main/doc/data/messages/b/bare-name-capture-pattern/good.py new file mode 100644 index 0000000..70b18db --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bare-name-capture-pattern/good.py @@ -0,0 +1,17 @@ +from 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 :(") diff --git a/src/pylint/pylint-main/doc/data/messages/b/bare-name-capture-pattern/related.rst b/src/pylint/pylint-main/doc/data/messages/b/bare-name-capture-pattern/related.rst new file mode 100644 index 0000000..bb0fe8f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bare-name-capture-pattern/related.rst @@ -0,0 +1 @@ +- `PEP 636 `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/bidirectional-unicode/bad.py b/src/pylint/pylint-main/doc/data/messages/b/bidirectional-unicode/bad.py new file mode 100644 index 0000000..52f3070 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bidirectional-unicode/bad.py @@ -0,0 +1,2 @@ +# +1: [bidirectional-unicode] +example = "x‏" * 100 # "‏x" is assigned diff --git a/src/pylint/pylint-main/doc/data/messages/b/bidirectional-unicode/good.py b/src/pylint/pylint-main/doc/data/messages/b/bidirectional-unicode/good.py new file mode 100644 index 0000000..4a625dd --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/bidirectional-unicode/good.py @@ -0,0 +1 @@ +example = "x[U+2194]" * 100 diff --git a/src/pylint/pylint-main/doc/data/messages/b/binary-op-exception/bad.py b/src/pylint/pylint-main/doc/data/messages/b/binary-op-exception/bad.py new file mode 100644 index 0000000..8ffd1de --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/binary-op-exception/bad.py @@ -0,0 +1,4 @@ +try: + 1 / 0 +except ZeroDivisionError or ValueError: # [binary-op-exception] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/b/binary-op-exception/good.py b/src/pylint/pylint-main/doc/data/messages/b/binary-op-exception/good.py new file mode 100644 index 0000000..945e422 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/binary-op-exception/good.py @@ -0,0 +1,4 @@ +try: + 1 / 0 +except (ZeroDivisionError, ValueError): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/b/boolean-datetime/bad.py b/src/pylint/pylint-main/doc/data/messages/b/boolean-datetime/bad.py new file mode 100644 index 0000000..c36abd1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/boolean-datetime/bad.py @@ -0,0 +1,8 @@ +import datetime + +if datetime.time(): # [boolean-datetime] + print("It is time.") + + +if datetime.datetime.now().time(): # [boolean-datetime] + print("Now or never.") diff --git a/src/pylint/pylint-main/doc/data/messages/b/boolean-datetime/good.py b/src/pylint/pylint-main/doc/data/messages/b/boolean-datetime/good.py new file mode 100644 index 0000000..b846e0b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/boolean-datetime/good.py @@ -0,0 +1,9 @@ +import 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!") diff --git a/src/pylint/pylint-main/doc/data/messages/b/boolean-datetime/pylintrc b/src/pylint/pylint-main/doc/data/messages/b/boolean-datetime/pylintrc new file mode 100644 index 0000000..8429adc --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/boolean-datetime/pylintrc @@ -0,0 +1,2 @@ +[main] +py-version=3.4 diff --git a/src/pylint/pylint-main/doc/data/messages/b/boolean-datetime/related.rst b/src/pylint/pylint-main/doc/data/messages/b/boolean-datetime/related.rst new file mode 100644 index 0000000..5841313 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/boolean-datetime/related.rst @@ -0,0 +1 @@ +- `Python bug tracker `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/break-in-finally/bad.py b/src/pylint/pylint-main/doc/data/messages/b/break-in-finally/bad.py new file mode 100644 index 0000000..6d36006 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/break-in-finally/bad.py @@ -0,0 +1,5 @@ +while True: + try: + pass + finally: + break # [break-in-finally] diff --git a/src/pylint/pylint-main/doc/data/messages/b/break-in-finally/good.py b/src/pylint/pylint-main/doc/data/messages/b/break-in-finally/good.py new file mode 100644 index 0000000..87189de --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/break-in-finally/good.py @@ -0,0 +1,7 @@ +while True: + try: + pass + except ValueError: + pass + else: + break diff --git a/src/pylint/pylint-main/doc/data/messages/b/break-in-finally/related.rst b/src/pylint/pylint-main/doc/data/messages/b/break-in-finally/related.rst new file mode 100644 index 0000000..6ebcdf4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/break-in-finally/related.rst @@ -0,0 +1,2 @@ +- `Python 3 docs 'finally' clause `_ +- `PEP 765 - Disallow return/break/continue that exit a finally block `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/broad-exception-caught/bad.py b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-caught/bad.py new file mode 100644 index 0000000..67d5d7b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-caught/bad.py @@ -0,0 +1,4 @@ +try: + import platform_specific_module +except Exception: # [broad-exception-caught] + platform_specific_module = None diff --git a/src/pylint/pylint-main/doc/data/messages/b/broad-exception-caught/details.rst b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-caught/details.rst new file mode 100644 index 0000000..ae7f163 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-caught/details.rst @@ -0,0 +1,3 @@ +For 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. diff --git a/src/pylint/pylint-main/doc/data/messages/b/broad-exception-caught/good.py b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-caught/good.py new file mode 100644 index 0000000..24baac9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-caught/good.py @@ -0,0 +1,4 @@ +try: + import platform_specific_module +except ImportError: + platform_specific_module = None diff --git a/src/pylint/pylint-main/doc/data/messages/b/broad-exception-caught/related.rst b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-caught/related.rst new file mode 100644 index 0000000..23c74d2 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-caught/related.rst @@ -0,0 +1 @@ +- `Should I always specify an exception type in 'except' statements? `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/broad-exception-raised/bad.py b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-raised/bad.py new file mode 100644 index 0000000..4c8ff3b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-raised/bad.py @@ -0,0 +1,4 @@ +def small_apple(apple, length): + if len(apple) < length: + raise Exception("Apple is too small!") # [broad-exception-raised] + print(f"{apple} is proper size.") diff --git a/src/pylint/pylint-main/doc/data/messages/b/broad-exception-raised/good.py b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-raised/good.py new file mode 100644 index 0000000..a63b1b3 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-raised/good.py @@ -0,0 +1,4 @@ +def small_apple(apple, length): + if len(apple) < length: + raise ValueError("Apple is too small!") + print(f"{apple} is proper size.") diff --git a/src/pylint/pylint-main/doc/data/messages/b/broad-exception-raised/related.rst b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-raised/related.rst new file mode 100644 index 0000000..978b579 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broad-exception-raised/related.rst @@ -0,0 +1 @@ +- `Programming recommendation in PEP8 `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/broken-collections-callable/bad.py b/src/pylint/pylint-main/doc/data/messages/b/broken-collections-callable/bad.py new file mode 100644 index 0000000..a90a992 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broken-collections-callable/bad.py @@ -0,0 +1,6 @@ +from collections.abc import Callable +from typing import Optional + + +def func() -> Optional[Callable[[int], None]]: # [broken-collections-callable] + ... diff --git a/src/pylint/pylint-main/doc/data/messages/b/broken-collections-callable/good.py b/src/pylint/pylint-main/doc/data/messages/b/broken-collections-callable/good.py new file mode 100644 index 0000000..c89d593 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broken-collections-callable/good.py @@ -0,0 +1,4 @@ +from typing import Callable, Optional + + +def func() -> Optional[Callable[[int], None]]: ... diff --git a/src/pylint/pylint-main/doc/data/messages/b/broken-collections-callable/pylintrc b/src/pylint/pylint-main/doc/data/messages/b/broken-collections-callable/pylintrc new file mode 100644 index 0000000..d075a59 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broken-collections-callable/pylintrc @@ -0,0 +1,3 @@ +[main] +py-version=3.9 +load-plugins=pylint.extensions.typing diff --git a/src/pylint/pylint-main/doc/data/messages/b/broken-collections-callable/related.rst b/src/pylint/pylint-main/doc/data/messages/b/broken-collections-callable/related.rst new file mode 100644 index 0000000..b93a3d9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broken-collections-callable/related.rst @@ -0,0 +1 @@ +- `bpo-42965 `_ diff --git a/src/pylint/pylint-main/doc/data/messages/b/broken-noreturn/bad.py b/src/pylint/pylint-main/doc/data/messages/b/broken-noreturn/bad.py new file mode 100644 index 0000000..77baf76 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broken-noreturn/bad.py @@ -0,0 +1,5 @@ +from typing import NoReturn, Union + + +def exploding_apple(apple) -> Union[None, NoReturn]: # [broken-noreturn] + print(f"{apple} is about to explode") diff --git a/src/pylint/pylint-main/doc/data/messages/b/broken-noreturn/good.py b/src/pylint/pylint-main/doc/data/messages/b/broken-noreturn/good.py new file mode 100644 index 0000000..ce4dc6e --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broken-noreturn/good.py @@ -0,0 +1,6 @@ +from typing import NoReturn + + +def exploding_apple(apple) -> NoReturn: + print(f"{apple} is about to explode") + raise Exception("{apple} exploded !") diff --git a/src/pylint/pylint-main/doc/data/messages/b/broken-noreturn/pylintrc b/src/pylint/pylint-main/doc/data/messages/b/broken-noreturn/pylintrc new file mode 100644 index 0000000..eb28fc7 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/b/broken-noreturn/pylintrc @@ -0,0 +1,3 @@ +[main] +py-version=3.7 +load-plugins=pylint.extensions.typing diff --git a/src/pylint/pylint-main/doc/data/messages/c/c-extension-no-member/details.rst b/src/pylint/pylint-main/doc/data/messages/c/c-extension-no-member/details.rst new file mode 100644 index 0000000..3f19677 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/c-extension-no-member/details.rst @@ -0,0 +1,4 @@ +``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``. diff --git a/src/pylint/pylint-main/doc/data/messages/c/c-extension-no-member/good.py b/src/pylint/pylint-main/doc/data/messages/c/c-extension-no-member/good.py new file mode 100644 index 0000000..c40beb5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/c-extension-no-member/good.py @@ -0,0 +1 @@ +# This is a placeholder for correct code for this message. diff --git a/src/pylint/pylint-main/doc/data/messages/c/catching-non-exception/bad.py b/src/pylint/pylint-main/doc/data/messages/c/catching-non-exception/bad.py new file mode 100644 index 0000000..86fa07b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/catching-non-exception/bad.py @@ -0,0 +1,8 @@ +class FooError: + pass + + +try: + 1 / 0 +except FooError: # [catching-non-exception] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/c/catching-non-exception/good.py b/src/pylint/pylint-main/doc/data/messages/c/catching-non-exception/good.py new file mode 100644 index 0000000..342fada --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/catching-non-exception/good.py @@ -0,0 +1,8 @@ +class FooError(Exception): + pass + + +try: + 1 / 0 +except FooError: + pass diff --git a/src/pylint/pylint-main/doc/data/messages/c/cell-var-from-loop/bad.py b/src/pylint/pylint-main/doc/data/messages/c/cell-var-from-loop/bad.py new file mode 100644 index 0000000..c8b9e92 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/cell-var-from-loop/bad.py @@ -0,0 +1,23 @@ +def 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!" diff --git a/src/pylint/pylint-main/doc/data/messages/c/cell-var-from-loop/good/functools.partial.py b/src/pylint/pylint-main/doc/data/messages/c/cell-var-from-loop/good/functools.partial.py new file mode 100644 index 0000000..596909e --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/cell-var-from-loop/good/functools.partial.py @@ -0,0 +1,23 @@ +import 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!" diff --git a/src/pylint/pylint-main/doc/data/messages/c/cell-var-from-loop/good/new_function.py b/src/pylint/pylint-main/doc/data/messages/c/cell-var-from-loop/good/new_function.py new file mode 100644 index 0000000..002eca2 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/cell-var-from-loop/good/new_function.py @@ -0,0 +1,17 @@ +def 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!" diff --git a/src/pylint/pylint-main/doc/data/messages/c/cell-var-from-loop/related.rst b/src/pylint/pylint-main/doc/data/messages/c/cell-var-from-loop/related.rst new file mode 100644 index 0000000..41129e5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/cell-var-from-loop/related.rst @@ -0,0 +1 @@ +- `Stackoverflow discussion `_ diff --git a/src/pylint/pylint-main/doc/data/messages/c/chained-comparison/bad.py b/src/pylint/pylint-main/doc/data/messages/c/chained-comparison/bad.py new file mode 100644 index 0000000..b04c927 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/chained-comparison/bad.py @@ -0,0 +1,5 @@ +a = int(input()) +b = int(input()) +c = int(input()) +if a < b and b < c: # [chained-comparison] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/c/chained-comparison/good.py b/src/pylint/pylint-main/doc/data/messages/c/chained-comparison/good.py new file mode 100644 index 0000000..9c4abff --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/chained-comparison/good.py @@ -0,0 +1,5 @@ +a = int(input()) +b = int(input()) +c = int(input()) +if a < b < c: + pass diff --git a/src/pylint/pylint-main/doc/data/messages/c/class-variable-slots-conflict/bad.py b/src/pylint/pylint-main/doc/data/messages/c/class-variable-slots-conflict/bad.py new file mode 100644 index 0000000..7705669 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/class-variable-slots-conflict/bad.py @@ -0,0 +1,15 @@ +class 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}.") diff --git a/src/pylint/pylint-main/doc/data/messages/c/class-variable-slots-conflict/good.py b/src/pylint/pylint-main/doc/data/messages/c/class-variable-slots-conflict/good.py new file mode 100644 index 0000000..2428f78 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/class-variable-slots-conflict/good.py @@ -0,0 +1,13 @@ +class 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}.") diff --git a/src/pylint/pylint-main/doc/data/messages/c/comparison-of-constants/bad.py b/src/pylint/pylint-main/doc/data/messages/c/comparison-of-constants/bad.py new file mode 100644 index 0000000..2ea0c42 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/comparison-of-constants/bad.py @@ -0,0 +1,2 @@ +def is_the_answer() -> bool: + return 42 == 42 # [comparison-of-constants] diff --git a/src/pylint/pylint-main/doc/data/messages/c/comparison-of-constants/good.py b/src/pylint/pylint-main/doc/data/messages/c/comparison-of-constants/good.py new file mode 100644 index 0000000..731bb16 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/comparison-of-constants/good.py @@ -0,0 +1,2 @@ +def is_the_answer(meaning_of_life: int) -> bool: + return meaning_of_life == 42 diff --git a/src/pylint/pylint-main/doc/data/messages/c/comparison-with-callable/bad.py b/src/pylint/pylint-main/doc/data/messages/c/comparison-with-callable/bad.py new file mode 100644 index 0000000..1dbdad0 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/comparison-with-callable/bad.py @@ -0,0 +1,7 @@ +def function_returning_a_fruit() -> str: + return "orange" + + +def is_an_orange(fruit: str = "apple"): + # apple == + return fruit == function_returning_a_fruit # [comparison-with-callable] diff --git a/src/pylint/pylint-main/doc/data/messages/c/comparison-with-callable/good.py b/src/pylint/pylint-main/doc/data/messages/c/comparison-with-callable/good.py new file mode 100644 index 0000000..a490071 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/comparison-with-callable/good.py @@ -0,0 +1,7 @@ +def function_returning_a_fruit() -> str: + return "orange" + + +def is_an_orange(fruit: str = "apple"): + # apple == orange + return fruit == function_returning_a_fruit() diff --git a/src/pylint/pylint-main/doc/data/messages/c/comparison-with-itself/bad.py b/src/pylint/pylint-main/doc/data/messages/c/comparison-with-itself/bad.py new file mode 100644 index 0000000..77794bc --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/comparison-with-itself/bad.py @@ -0,0 +1,3 @@ +def is_an_orange(fruit): + an_orange = "orange" + return fruit == fruit # [comparison-with-itself] diff --git a/src/pylint/pylint-main/doc/data/messages/c/comparison-with-itself/good.py b/src/pylint/pylint-main/doc/data/messages/c/comparison-with-itself/good.py new file mode 100644 index 0000000..b2b4296 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/comparison-with-itself/good.py @@ -0,0 +1,3 @@ +def is_an_orange(fruit): + an_orange = "orange" + return an_orange == fruit diff --git a/src/pylint/pylint-main/doc/data/messages/c/condition-evals-to-constant/bad.py b/src/pylint/pylint-main/doc/data/messages/c/condition-evals-to-constant/bad.py new file mode 100644 index 0000000..f52b24f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/condition-evals-to-constant/bad.py @@ -0,0 +1,2 @@ +def is_a_fruit(fruit): + return bool(fruit in {"apple", "orange"} or True) # [condition-evals-to-constant] diff --git a/src/pylint/pylint-main/doc/data/messages/c/condition-evals-to-constant/good.py b/src/pylint/pylint-main/doc/data/messages/c/condition-evals-to-constant/good.py new file mode 100644 index 0000000..37e9754 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/condition-evals-to-constant/good.py @@ -0,0 +1,2 @@ +def is_a_fruit(fruit): + return fruit in {"apple", "orange"} diff --git a/src/pylint/pylint-main/doc/data/messages/c/config-parse-error/details.rst b/src/pylint/pylint-main/doc/data/messages/c/config-parse-error/details.rst new file mode 100644 index 0000000..4fc0fe0 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/config-parse-error/details.rst @@ -0,0 +1 @@ +This is a message linked to a problem in your configuration not your code. diff --git a/src/pylint/pylint-main/doc/data/messages/c/confusing-consecutive-elif/bad.py b/src/pylint/pylint-main/doc/data/messages/c/confusing-consecutive-elif/bad.py new file mode 100644 index 0000000..93e1e2d --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/confusing-consecutive-elif/bad.py @@ -0,0 +1,6 @@ +def 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.") diff --git a/src/pylint/pylint-main/doc/data/messages/c/confusing-consecutive-elif/details.rst b/src/pylint/pylint-main/doc/data/messages/c/confusing-consecutive-elif/details.rst new file mode 100644 index 0000000..bd2ecc4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/confusing-consecutive-elif/details.rst @@ -0,0 +1 @@ +Creating 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. diff --git a/src/pylint/pylint-main/doc/data/messages/c/confusing-consecutive-elif/good.py b/src/pylint/pylint-main/doc/data/messages/c/confusing-consecutive-elif/good.py new file mode 100644 index 0000000..1722a6b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/confusing-consecutive-elif/good.py @@ -0,0 +1,22 @@ +# 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.") diff --git a/src/pylint/pylint-main/doc/data/messages/c/confusing-consecutive-elif/pylintrc b/src/pylint/pylint-main/doc/data/messages/c/confusing-consecutive-elif/pylintrc new file mode 100644 index 0000000..6ceabfd --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/confusing-consecutive-elif/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins=pylint.extensions.confusing_elif diff --git a/src/pylint/pylint-main/doc/data/messages/c/confusing-with-statement/bad.py b/src/pylint/pylint-main/doc/data/messages/c/confusing-with-statement/bad.py new file mode 100644 index 0000000..e6570a5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/confusing-with-statement/bad.py @@ -0,0 +1,2 @@ +with open("file.txt", "w") as fh1, fh2: # [confusing-with-statement] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/c/confusing-with-statement/good.py b/src/pylint/pylint-main/doc/data/messages/c/confusing-with-statement/good.py new file mode 100644 index 0000000..bcedaaf --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/confusing-with-statement/good.py @@ -0,0 +1,3 @@ +with open("file.txt", "w", encoding="utf8") as fh1: + with open("file.txt", "w", encoding="utf8") as fh2: + pass diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-alternative-union-syntax/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-alternative-union-syntax/bad.py new file mode 100644 index 0000000..2f83628 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-alternative-union-syntax/bad.py @@ -0,0 +1,8 @@ +from 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 ""}') diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-alternative-union-syntax/details.rst b/src/pylint/pylint-main/doc/data/messages/c/consider-alternative-union-syntax/details.rst new file mode 100644 index 0000000..c5e1220 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-alternative-union-syntax/details.rst @@ -0,0 +1,6 @@ +Using 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 diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-alternative-union-syntax/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-alternative-union-syntax/good.py new file mode 100644 index 0000000..29f8797 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-alternative-union-syntax/good.py @@ -0,0 +1,2 @@ +def forecast(temp: int | float, unit: str | None) -> None: + print(f'Temperature: {temp}{unit or ""}') diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-alternative-union-syntax/pylintrc b/src/pylint/pylint-main/doc/data/messages/c/consider-alternative-union-syntax/pylintrc new file mode 100644 index 0000000..0c377b2 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-alternative-union-syntax/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins = pylint.extensions.typing diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-iterating-dictionary/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-iterating-dictionary/bad.py new file mode 100644 index 0000000..eb5a97a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-iterating-dictionary/bad.py @@ -0,0 +1,5 @@ +FRUITS = {"apple": 1, "pear": 5, "peach": 10} + + +for fruit in FRUITS.keys(): # [consider-iterating-dictionary] + print(fruit) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-iterating-dictionary/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-iterating-dictionary/good.py new file mode 100644 index 0000000..c67b399 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-iterating-dictionary/good.py @@ -0,0 +1,5 @@ +FRUITS = {"apple": 1, "pear": 5, "peach": 10} + + +for fruit in FRUITS: + print(fruit) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-math-not-float/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-math-not-float/bad.py new file mode 100644 index 0000000..6cab739 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-math-not-float/bad.py @@ -0,0 +1 @@ +swag = float("inf") # [consider-math-not-float] diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-math-not-float/details.rst b/src/pylint/pylint-main/doc/data/messages/c/consider-math-not-float/details.rst new file mode 100644 index 0000000..2e5e09c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-math-not-float/details.rst @@ -0,0 +1,40 @@ +This 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. diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-math-not-float/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-math-not-float/good.py new file mode 100644 index 0000000..711a0f3 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-math-not-float/good.py @@ -0,0 +1,3 @@ +import math + +swag = math.inf diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-math-not-float/pylintrc b/src/pylint/pylint-main/doc/data/messages/c/consider-math-not-float/pylintrc new file mode 100644 index 0000000..8663ab0 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-math-not-float/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins=pylint.extensions.code_style diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-merging-isinstance/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-merging-isinstance/bad.py new file mode 100644 index 0000000..c7b059c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-merging-isinstance/bad.py @@ -0,0 +1,6 @@ +from typing import Any + + +def is_number(value: Any) -> bool: + # +1: [consider-merging-isinstance] + return isinstance(value, int) or isinstance(value, float) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-merging-isinstance/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-merging-isinstance/good.py new file mode 100644 index 0000000..993f690 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-merging-isinstance/good.py @@ -0,0 +1,5 @@ +from typing import Any + + +def is_number(value: Any) -> bool: + return isinstance(value, (int, float)) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-refactoring-into-while-condition/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-refactoring-into-while-condition/bad.py new file mode 100644 index 0000000..edb6fe3 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-refactoring-into-while-condition/bad.py @@ -0,0 +1,7 @@ +fruit_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") diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-refactoring-into-while-condition/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-refactoring-into-while-condition/good.py new file mode 100644 index 0000000..900b9c6 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-refactoring-into-while-condition/good.py @@ -0,0 +1,5 @@ +fruit_basket = ["apple", "orange", "banana", "cherry", "guava"] + +while len(fruit_basket) != 0: + fruit = fruit_basket.pop() + print(f"We removed {fruit} from the basket") diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-refactoring-into-while-condition/pylintrc b/src/pylint/pylint-main/doc/data/messages/c/consider-refactoring-into-while-condition/pylintrc new file mode 100644 index 0000000..7625181 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-refactoring-into-while-condition/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins=pylint.extensions.consider_refactoring_into_while_condition diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-swap-variables/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-swap-variables/bad.py new file mode 100644 index 0000000..2092c99 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-swap-variables/bad.py @@ -0,0 +1,6 @@ +a = 1 +b = 2 + +temp = a # [consider-swap-variables] +a = b +b = temp diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-swap-variables/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-swap-variables/good.py new file mode 100644 index 0000000..1b92dcb --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-swap-variables/good.py @@ -0,0 +1,4 @@ +a = 1 +b = 2 + +a, b = b, a diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-ternary-expression/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-ternary-expression/bad.py new file mode 100644 index 0000000..126b92b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-ternary-expression/bad.py @@ -0,0 +1,5 @@ +x, y = input(), input() +if x >= y: # [consider-ternary-expression] + maximum = x +else: + maximum = y diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-ternary-expression/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-ternary-expression/good.py new file mode 100644 index 0000000..1173240 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-ternary-expression/good.py @@ -0,0 +1,2 @@ +x, y = input(), input() +maximum = x if x >= y else y diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-ternary-expression/pylintrc b/src/pylint/pylint-main/doc/data/messages/c/consider-ternary-expression/pylintrc new file mode 100644 index 0000000..20f7725 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-ternary-expression/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins=pylint.extensions.consider_ternary_expression diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-alias/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-alias/bad.py new file mode 100644 index 0000000..e3d0785 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-alias/bad.py @@ -0,0 +1,3 @@ +import typing + +cats: typing.Dict[str, int] # [consider-using-alias] diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-alias/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-alias/good.py new file mode 100644 index 0000000..4277488 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-alias/good.py @@ -0,0 +1,3 @@ +import typing + +cats: typing.cast(dict[str, int], "string") diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-alias/pylintrc b/src/pylint/pylint-main/doc/data/messages/c/consider-using-alias/pylintrc new file mode 100644 index 0000000..038a94c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-alias/pylintrc @@ -0,0 +1,4 @@ +[main] +load-plugins = pylint.extensions.typing +py-version = 3.7 +runtime-typing=no diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/bad/all_even.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/bad/all_even.py new file mode 100644 index 0000000..53ef540 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/bad/all_even.py @@ -0,0 +1,6 @@ +def 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 diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/bad/any_even.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/bad/any_even.py new file mode 100644 index 0000000..a984674 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/bad/any_even.py @@ -0,0 +1,6 @@ +def 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 diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/good/all_even.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/good/all_even.py new file mode 100644 index 0000000..1fd24ee --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/good/all_even.py @@ -0,0 +1,3 @@ +def all_even(items): + """Return True if the list contains all even numbers""" + return all(item % 2 == 0 for item in items) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/good/any_even.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/good/any_even.py new file mode 100644 index 0000000..e26db4f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/good/any_even.py @@ -0,0 +1,3 @@ +def any_even(items): + """Return True if the list contains any even numbers""" + return any(item % 2 == 0 for item in items) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/pylintrc b/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/pylintrc new file mode 100644 index 0000000..2fc8207 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-any-or-all/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins=pylint.extensions.for_any_all diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-assignment-expr/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-assignment-expr/bad.py new file mode 100644 index 0000000..a700537 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-assignment-expr/bad.py @@ -0,0 +1,4 @@ +apples = 2 + +if apples: # [consider-using-assignment-expr] + print("God apples!") diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-assignment-expr/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-assignment-expr/good.py new file mode 100644 index 0000000..a1e4027 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-assignment-expr/good.py @@ -0,0 +1,2 @@ +if apples := 2: + print("God apples!") diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-assignment-expr/pylintrc b/src/pylint/pylint-main/doc/data/messages/c/consider-using-assignment-expr/pylintrc new file mode 100644 index 0000000..14b316d --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-assignment-expr/pylintrc @@ -0,0 +1,3 @@ +[MAIN] +py-version=3.8 +load-plugins=pylint.extensions.code_style diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-augmented-assign/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-augmented-assign/bad.py new file mode 100644 index 0000000..90b8931 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-augmented-assign/bad.py @@ -0,0 +1,2 @@ +x = 1 +x = x + 1 # [consider-using-augmented-assign] diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-augmented-assign/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-augmented-assign/good.py new file mode 100644 index 0000000..3e34f6b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-augmented-assign/good.py @@ -0,0 +1,2 @@ +x = 1 +x += 1 diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-augmented-assign/pylintrc b/src/pylint/pylint-main/doc/data/messages/c/consider-using-augmented-assign/pylintrc new file mode 100644 index 0000000..5846022 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-augmented-assign/pylintrc @@ -0,0 +1,3 @@ +[MAIN] +load-plugins=pylint.extensions.code_style +enable=consider-using-augmented-assign diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-comprehension/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-comprehension/bad.py new file mode 100644 index 0000000..d9b02c7 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-comprehension/bad.py @@ -0,0 +1,4 @@ +NUMBERS = [1, 2, 3] + +# +1: [consider-using-dict-comprehension] +DOUBLED_NUMBERS = dict([(number, number * 2) for number in NUMBERS]) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-comprehension/details.rst b/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-comprehension/details.rst new file mode 100644 index 0000000..f23dba1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-comprehension/details.rst @@ -0,0 +1,4 @@ +pyupgrade_ or ruff_ can fix this issue automatically. + +.. _pyupgrade: https://github.com/asottile/pyupgrade +.. _ruff: https://docs.astral.sh/ruff/ diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-comprehension/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-comprehension/good.py new file mode 100644 index 0000000..5f91d56 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-comprehension/good.py @@ -0,0 +1,3 @@ +NUMBERS = [1, 2, 3] + +DOUBLED_NUMBERS = {number: number * 2 for number in NUMBERS} diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-items/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-items/bad.py new file mode 100644 index 0000000..ce8d4d4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-items/bad.py @@ -0,0 +1,10 @@ +ORCHESTRA = { + "violin": "strings", + "oboe": "woodwind", + "tuba": "brass", + "gong": "percussion", +} + + +for instrument in ORCHESTRA: # [consider-using-dict-items] + print(f"{instrument}: {ORCHESTRA[instrument]}") diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-items/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-items/good.py new file mode 100644 index 0000000..f719b1a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-dict-items/good.py @@ -0,0 +1,10 @@ +ORCHESTRA = { + "violin": "strings", + "oboe": "woodwind", + "tuba": "brass", + "gong": "percussion", +} + + +for instrument, section in ORCHESTRA.items(): + print(f"{instrument}: {section}") diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-enumerate/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-enumerate/bad.py new file mode 100644 index 0000000..0beee2e --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-enumerate/bad.py @@ -0,0 +1,4 @@ +seasons = ["Spring", "Summer", "Fall", "Winter"] + +for i in range(len(seasons)): # [consider-using-enumerate] + print(i, seasons[i]) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-enumerate/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-enumerate/good.py new file mode 100644 index 0000000..b078e48 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-enumerate/good.py @@ -0,0 +1,4 @@ +seasons = ["Spring", "Summer", "Fall", "Winter"] + +for i, season in enumerate(seasons): + print(i, season) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-f-string/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-f-string/bad.py new file mode 100644 index 0000000..26da6a1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-f-string/bad.py @@ -0,0 +1,16 @@ +from 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] +) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-f-string/details.rst b/src/pylint/pylint-main/doc/data/messages/c/consider-using-f-string/details.rst new file mode 100644 index 0000000..6b2d0e4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-f-string/details.rst @@ -0,0 +1,7 @@ +Formatted 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. diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-f-string/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-f-string/good.py new file mode 100644 index 0000000..f7913fa --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-f-string/good.py @@ -0,0 +1,3 @@ +menu = ("eggs", "spam", 42.4) + +f_string_order = f"{menu[0]} and {menu[1]}: {menu[2]:0.2f} ¤" diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-from-import/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-from-import/bad.py new file mode 100644 index 0000000..ff2f489 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-from-import/bad.py @@ -0,0 +1 @@ +import os.path as path # [consider-using-from-import] diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-from-import/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-from-import/good.py new file mode 100644 index 0000000..cfd7c68 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-from-import/good.py @@ -0,0 +1 @@ +from os import path diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-generator/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-generator/bad.py new file mode 100644 index 0000000..260ec97 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-generator/bad.py @@ -0,0 +1,5 @@ +list([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] diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-generator/details.rst b/src/pylint/pylint-main/doc/data/messages/c/consider-using-generator/details.rst new file mode 100644 index 0000000..ab7a90e --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-generator/details.rst @@ -0,0 +1,5 @@ +Removing ``[]`` 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. diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-generator/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-generator/good.py new file mode 100644 index 0000000..6674167 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-generator/good.py @@ -0,0 +1,5 @@ +list(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))) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-generator/related.rst b/src/pylint/pylint-main/doc/data/messages/c/consider-using-generator/related.rst new file mode 100644 index 0000000..24727cf --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-generator/related.rst @@ -0,0 +1,3 @@ +- `PEP 289 `_ +- `Benchmark and discussion for any/all/list/tuple `_ +- `Benchmark and discussion for sum/max/min `_ diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-get/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-get/bad.py new file mode 100644 index 0000000..b820c56 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-get/bad.py @@ -0,0 +1,6 @@ +knights = {"Gallahad": "the pure", "Robin": "the brave"} + +if "Gallahad" in knights: # [consider-using-get] + DESCRIPTION = knights["Gallahad"] +else: + DESCRIPTION = "" diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-get/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-get/good.py new file mode 100644 index 0000000..eba9976 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-get/good.py @@ -0,0 +1,3 @@ +knights = {"Gallahad": "the pure", "Robin": "the brave"} + +description = knights.get("Gallahad", "") diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-in/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-in/bad.py new file mode 100644 index 0000000..81eddb7 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-in/bad.py @@ -0,0 +1,3 @@ +def fruit_is_round(fruit): + # +1: [consider-using-in] + return fruit == "apple" or fruit == "orange" or fruit == "melon" diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-in/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-in/good.py new file mode 100644 index 0000000..bc308fa --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-in/good.py @@ -0,0 +1,2 @@ +def fruit_is_round(fruit): + return fruit in {"apple", "orange", "melon"} diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-join/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-join/bad.py new file mode 100644 index 0000000..5d5a32f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-join/bad.py @@ -0,0 +1,8 @@ +def 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"])) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-join/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-join/good.py new file mode 100644 index 0000000..1ee43ed --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-join/good.py @@ -0,0 +1 @@ +print("".join(["apple", "pear", "peach"])) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-max-builtin/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-max-builtin/bad.py new file mode 100644 index 0000000..3e66cee --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-max-builtin/bad.py @@ -0,0 +1,7 @@ +def get_max(value1, value2): + if value1 < value2: # [consider-using-max-builtin] + value1 = value2 + return value1 + + +print(get_max(1, 2)) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-max-builtin/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-max-builtin/good.py new file mode 100644 index 0000000..90af411 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-max-builtin/good.py @@ -0,0 +1 @@ +print(max(1, 2)) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-min-builtin/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-min-builtin/bad.py new file mode 100644 index 0000000..007371a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-min-builtin/bad.py @@ -0,0 +1,7 @@ +def get_min(value1, value2): + if value1 > value2: # [consider-using-min-builtin] + value1 = value2 + return value1 + + +print(get_min(1, 2)) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-min-builtin/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-min-builtin/good.py new file mode 100644 index 0000000..1995129 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-min-builtin/good.py @@ -0,0 +1 @@ +print(min(1, 2)) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-namedtuple-or-dataclass/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-namedtuple-or-dataclass/bad.py new file mode 100644 index 0000000..d1f3eba --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-namedtuple-or-dataclass/bad.py @@ -0,0 +1,14 @@ +FELIDAES = { # [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, + }, +} diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-namedtuple-or-dataclass/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-namedtuple-or-dataclass/good.py new file mode 100644 index 0000000..b13713f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-namedtuple-or-dataclass/good.py @@ -0,0 +1,18 @@ +from 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" + ), +} diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-namedtuple-or-dataclass/pylintrc b/src/pylint/pylint-main/doc/data/messages/c/consider-using-namedtuple-or-dataclass/pylintrc new file mode 100644 index 0000000..8663ab0 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-namedtuple-or-dataclass/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins=pylint.extensions.code_style diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-set-comprehension/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-set-comprehension/bad.py new file mode 100644 index 0000000..ffdc9e5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-set-comprehension/bad.py @@ -0,0 +1,4 @@ +NUMBERS = [1, 2, 2, 3, 4, 4] + +# +1: [consider-using-set-comprehension] +UNIQUE_EVEN_NUMBERS = set([number for number in NUMBERS if number % 2 == 0]) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-set-comprehension/details.rst b/src/pylint/pylint-main/doc/data/messages/c/consider-using-set-comprehension/details.rst new file mode 100644 index 0000000..f23dba1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-set-comprehension/details.rst @@ -0,0 +1,4 @@ +pyupgrade_ or ruff_ can fix this issue automatically. + +.. _pyupgrade: https://github.com/asottile/pyupgrade +.. _ruff: https://docs.astral.sh/ruff/ diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-set-comprehension/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-set-comprehension/good.py new file mode 100644 index 0000000..4914fc2 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-set-comprehension/good.py @@ -0,0 +1,3 @@ +NUMBERS = [1, 2, 2, 3, 4, 4] + +UNIQUE_EVEN_NUMBERS = {number for number in NUMBERS if number % 2 == 0} diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-sys-exit/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-sys-exit/bad.py new file mode 100644 index 0000000..1acc22a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-sys-exit/bad.py @@ -0,0 +1,4 @@ +if __name__ == "__main__": + user = input("Enter user name: ") + print(f"Hello, {user}") + exit(0) # [consider-using-sys-exit] diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-sys-exit/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-sys-exit/good.py new file mode 100644 index 0000000..acacd34 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-sys-exit/good.py @@ -0,0 +1,6 @@ +import sys + +if __name__ == "__main__": + user = input("Enter user name: ") + print(f"Hello, {user}") + sys.exit(0) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-ternary/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-ternary/bad.py new file mode 100644 index 0000000..bd69aa9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-ternary/bad.py @@ -0,0 +1,2 @@ +x, y = 1, 2 +maximum = x >= y and x or y # [consider-using-ternary] diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-ternary/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-ternary/good.py new file mode 100644 index 0000000..bcb8446 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-ternary/good.py @@ -0,0 +1,2 @@ +x, y = 1, 2 +maximum = x if x >= y else y diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-tuple/bad.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-tuple/bad.py new file mode 100644 index 0000000..099efb9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-tuple/bad.py @@ -0,0 +1,2 @@ +for i in [1, 2, 3]: # [consider-using-tuple] + print(i) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-tuple/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-tuple/good.py new file mode 100644 index 0000000..c0e2e70 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-tuple/good.py @@ -0,0 +1,2 @@ +for i in (1, 2, 3): + print(i) diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-tuple/pylintrc b/src/pylint/pylint-main/doc/data/messages/c/consider-using-tuple/pylintrc new file mode 100644 index 0000000..8663ab0 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-tuple/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins=pylint.extensions.code_style diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/bad/close.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/bad/close.py new file mode 100644 index 0000000..b3fddc1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/bad/close.py @@ -0,0 +1,3 @@ +file = open("apple.txt", "r", encoding="utf8") # [consider-using-with] +contents = file.read() +file.close() diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/bad/not_even_close.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/bad/not_even_close.py new file mode 100644 index 0000000..a0b51f0 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/bad/not_even_close.py @@ -0,0 +1 @@ +contents = open("apple.txt", "r", encoding="utf8").read() # [consider-using-with] diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/details.rst b/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/details.rst new file mode 100644 index 0000000..58d763f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/details.rst @@ -0,0 +1,10 @@ +Calling ``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 diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/good.py b/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/good.py new file mode 100644 index 0000000..3994259 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/good.py @@ -0,0 +1,2 @@ +with open("apple.txt", "r", encoding="utf8") as file: + contents = file.read() diff --git a/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/related.rst b/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/related.rst new file mode 100644 index 0000000..a2a209c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/consider-using-with/related.rst @@ -0,0 +1,4 @@ +- `Python doc: Reading and writing files `_ +- `PEP 343 `_ +- `Context managers in Python `_ by John Lekberg +- `Rationale `_ diff --git a/src/pylint/pylint-main/doc/data/messages/c/contextmanager-generator-missing-cleanup/bad.py b/src/pylint/pylint-main/doc/data/messages/c/contextmanager-generator-missing-cleanup/bad.py new file mode 100644 index 0000000..b2072f7 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/contextmanager-generator-missing-cleanup/bad.py @@ -0,0 +1,14 @@ +import 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 diff --git a/src/pylint/pylint-main/doc/data/messages/c/contextmanager-generator-missing-cleanup/details.rst b/src/pylint/pylint-main/doc/data/messages/c/contextmanager-generator-missing-cleanup/details.rst new file mode 100644 index 0000000..50b948f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/contextmanager-generator-missing-cleanup/details.rst @@ -0,0 +1,31 @@ +Instantiating 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 diff --git a/src/pylint/pylint-main/doc/data/messages/c/contextmanager-generator-missing-cleanup/good.py b/src/pylint/pylint-main/doc/data/messages/c/contextmanager-generator-missing-cleanup/good.py new file mode 100644 index 0000000..2287e86 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/contextmanager-generator-missing-cleanup/good.py @@ -0,0 +1,61 @@ +import 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 diff --git a/src/pylint/pylint-main/doc/data/messages/c/contextmanager-generator-missing-cleanup/related.rst b/src/pylint/pylint-main/doc/data/messages/c/contextmanager-generator-missing-cleanup/related.rst new file mode 100644 index 0000000..aacc968 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/contextmanager-generator-missing-cleanup/related.rst @@ -0,0 +1,2 @@ +- `Rationale `_ +- `CPython Issue `_ diff --git a/src/pylint/pylint-main/doc/data/messages/c/continue-in-finally/bad.py b/src/pylint/pylint-main/doc/data/messages/c/continue-in-finally/bad.py new file mode 100644 index 0000000..190463f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/continue-in-finally/bad.py @@ -0,0 +1,5 @@ +while True: + try: + pass + finally: + continue # [continue-in-finally] diff --git a/src/pylint/pylint-main/doc/data/messages/c/continue-in-finally/good.py b/src/pylint/pylint-main/doc/data/messages/c/continue-in-finally/good.py new file mode 100644 index 0000000..6b14ef4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/continue-in-finally/good.py @@ -0,0 +1,7 @@ +while True: + try: + pass + except ValueError: + pass + else: + continue diff --git a/src/pylint/pylint-main/doc/data/messages/c/continue-in-finally/related.rst b/src/pylint/pylint-main/doc/data/messages/c/continue-in-finally/related.rst new file mode 100644 index 0000000..6ebcdf4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/continue-in-finally/related.rst @@ -0,0 +1,2 @@ +- `Python 3 docs 'finally' clause `_ +- `PEP 765 - Disallow return/break/continue that exit a finally block `_ diff --git a/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/bad/__init__.py b/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/bad/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/bad/bad.py b/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/bad/bad.py new file mode 100644 index 0000000..75e5e2b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/bad/bad.py @@ -0,0 +1,8 @@ +def count_to_one(): + return 1 + + +def count_to_three(): + from .bad2 import count_to_two + + return count_to_two() + 1 diff --git a/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/bad/bad2.py b/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/bad/bad2.py new file mode 100644 index 0000000..23417a8 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/bad/bad2.py @@ -0,0 +1,5 @@ +from .bad import count_to_one # [cyclic-import] + + +def count_to_two(): + return count_to_one() + 1 diff --git a/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/details.rst b/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/details.rst new file mode 100644 index 0000000..5db7273 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/details.rst @@ -0,0 +1,3 @@ +The 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. diff --git a/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/good.py b/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/good.py new file mode 100644 index 0000000..7924246 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/c/cyclic-import/good.py @@ -0,0 +1,10 @@ +def count_to_one(): + return 1 + + +def count_to_two(): + return count_to_one() + 1 + + +def count_to_three(): + return count_to_two() + 1 diff --git a/src/pylint/pylint-main/doc/data/messages/d/dangerous-default-value/bad.py b/src/pylint/pylint-main/doc/data/messages/d/dangerous-default-value/bad.py new file mode 100644 index 0000000..6ce1223 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/dangerous-default-value/bad.py @@ -0,0 +1,3 @@ +def whats_on_the_telly(penguin=[]): # [dangerous-default-value] + penguin.append("property of the zoo") + return penguin diff --git a/src/pylint/pylint-main/doc/data/messages/d/dangerous-default-value/details.rst b/src/pylint/pylint-main/doc/data/messages/d/dangerous-default-value/details.rst new file mode 100644 index 0000000..2b9a2e6 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/dangerous-default-value/details.rst @@ -0,0 +1,7 @@ +With 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"] diff --git a/src/pylint/pylint-main/doc/data/messages/d/dangerous-default-value/good.py b/src/pylint/pylint-main/doc/data/messages/d/dangerous-default-value/good.py new file mode 100644 index 0000000..605c3ce --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/dangerous-default-value/good.py @@ -0,0 +1,5 @@ +def whats_on_the_telly(penguin=None): + if penguin is None: + penguin = [] + penguin.append("property of the zoo") + return penguin diff --git a/src/pylint/pylint-main/doc/data/messages/d/declare-non-slot/bad.py b/src/pylint/pylint-main/doc/data/messages/d/declare-non-slot/bad.py new file mode 100644 index 0000000..5e39d47 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/declare-non-slot/bad.py @@ -0,0 +1,5 @@ +class Student: + __slots__ = ("name",) + + name: str + surname: str # [declare-non-slot] diff --git a/src/pylint/pylint-main/doc/data/messages/d/declare-non-slot/good.py b/src/pylint/pylint-main/doc/data/messages/d/declare-non-slot/good.py new file mode 100644 index 0000000..1ca1de1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/declare-non-slot/good.py @@ -0,0 +1,5 @@ +class Student: + __slots__ = ("name", "surname") + + name: str + surname: str diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-argument/bad.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-argument/bad.py new file mode 100644 index 0000000..d0b0c25 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-argument/bad.py @@ -0,0 +1 @@ +int(x=1) # [deprecated-argument] diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-argument/details.rst b/src/pylint/pylint-main/doc/data/messages/d/deprecated-argument/details.rst new file mode 100644 index 0000000..46294b9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-argument/details.rst @@ -0,0 +1,2 @@ +The actual replacement needs to be studied on a case by case basis +by reading the deprecation warning or the release notes. diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-argument/good.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-argument/good.py new file mode 100644 index 0000000..8269369 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-argument/good.py @@ -0,0 +1 @@ +int(1) diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-argument/pylintrc b/src/pylint/pylint-main/doc/data/messages/d/deprecated-argument/pylintrc new file mode 100644 index 0000000..e69de29 diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-attribute/bad.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-attribute/bad.py new file mode 100644 index 0000000..ccd4090 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-attribute/bad.py @@ -0,0 +1,4 @@ +from configparser import ParsingError + +err = ParsingError("filename") +source = err.filename # [deprecated-attribute] diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-attribute/details.rst b/src/pylint/pylint-main/doc/data/messages/d/deprecated-attribute/details.rst new file mode 100644 index 0000000..46294b9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-attribute/details.rst @@ -0,0 +1,2 @@ +The actual replacement needs to be studied on a case by case basis +by reading the deprecation warning or the release notes. diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-attribute/good.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-attribute/good.py new file mode 100644 index 0000000..492cd80 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-attribute/good.py @@ -0,0 +1,4 @@ +from configparser import ParsingError + +err = ParsingError("filename") +source = err.source diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-class/bad.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-class/bad.py new file mode 100644 index 0000000..ab96b50 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-class/bad.py @@ -0,0 +1 @@ +from collections import Iterable # [deprecated-class] diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-class/details.rst b/src/pylint/pylint-main/doc/data/messages/d/deprecated-class/details.rst new file mode 100644 index 0000000..46294b9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-class/details.rst @@ -0,0 +1,2 @@ +The actual replacement needs to be studied on a case by case basis +by reading the deprecation warning or the release notes. diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-class/good.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-class/good.py new file mode 100644 index 0000000..775057c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-class/good.py @@ -0,0 +1 @@ +from collections.abc import Iterable diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-decorator/bad.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-decorator/bad.py new file mode 100644 index 0000000..afae4c7 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-decorator/bad.py @@ -0,0 +1,7 @@ +import abc + + +class Animal: + @abc.abstractclassmethod # [deprecated-decorator] + def breath(cls): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-decorator/details.rst b/src/pylint/pylint-main/doc/data/messages/d/deprecated-decorator/details.rst new file mode 100644 index 0000000..46294b9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-decorator/details.rst @@ -0,0 +1,2 @@ +The actual replacement needs to be studied on a case by case basis +by reading the deprecation warning or the release notes. diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-decorator/good.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-decorator/good.py new file mode 100644 index 0000000..3388fde --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-decorator/good.py @@ -0,0 +1,8 @@ +import abc + + +class Animal: + @abc.classmethod + @abc.abstractmethod + def breath(cls): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-decorator/pylintrc b/src/pylint/pylint-main/doc/data/messages/d/deprecated-decorator/pylintrc new file mode 100644 index 0000000..ca649e6 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-decorator/pylintrc @@ -0,0 +1,2 @@ +[main] +py-version = 3.3 diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-method/bad.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-method/bad.py new file mode 100644 index 0000000..78870f3 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-method/bad.py @@ -0,0 +1,3 @@ +import logging + +logging.warn("I'm coming, world !") # [deprecated-method] diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-method/details.rst b/src/pylint/pylint-main/doc/data/messages/d/deprecated-method/details.rst new file mode 100644 index 0000000..46294b9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-method/details.rst @@ -0,0 +1,2 @@ +The actual replacement needs to be studied on a case by case basis +by reading the deprecation warning or the release notes. diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-method/good.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-method/good.py new file mode 100644 index 0000000..e54ea0e --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-method/good.py @@ -0,0 +1,3 @@ +import logging + +logging.warning("I'm coming, world !") diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-module/bad.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-module/bad.py new file mode 100644 index 0000000..fd17f13 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-module/bad.py @@ -0,0 +1,3 @@ +import distutils # [deprecated-module] + +import whatever_you_want # [deprecated-module] diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-module/details.rst b/src/pylint/pylint-main/doc/data/messages/d/deprecated-module/details.rst new file mode 100644 index 0000000..46294b9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-module/details.rst @@ -0,0 +1,2 @@ +The actual replacement needs to be studied on a case by case basis +by reading the deprecation warning or the release notes. diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-module/good.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-module/good.py new file mode 100644 index 0000000..014a76c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-module/good.py @@ -0,0 +1,2 @@ +import setuptools +import whatever_replacement_you_want diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-module/pylintrc b/src/pylint/pylint-main/doc/data/messages/d/deprecated-module/pylintrc new file mode 100644 index 0000000..c72ab24 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-module/pylintrc @@ -0,0 +1,3 @@ +[main] +py-version=3.7 +deprecated-modules=whatever_you_want diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-pragma/bad.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-pragma/bad.py new file mode 100644 index 0000000..133bf89 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-pragma/bad.py @@ -0,0 +1 @@ +# pylint: disable-msg=eval-used # [deprecated-pragma] diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-pragma/good.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-pragma/good.py new file mode 100644 index 0000000..8aebe0b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-pragma/good.py @@ -0,0 +1 @@ +# pylint: disable = eval-used diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-typing-alias/bad.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-typing-alias/bad.py new file mode 100644 index 0000000..cde5564 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-typing-alias/bad.py @@ -0,0 +1,3 @@ +import typing + +item_to_number_of_item: typing.Dict[str, int] # [deprecated-typing-alias] diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-typing-alias/good.py b/src/pylint/pylint-main/doc/data/messages/d/deprecated-typing-alias/good.py new file mode 100644 index 0000000..951fa52 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-typing-alias/good.py @@ -0,0 +1 @@ +item_to_number_of_item: dict[str, int] diff --git a/src/pylint/pylint-main/doc/data/messages/d/deprecated-typing-alias/pylintrc b/src/pylint/pylint-main/doc/data/messages/d/deprecated-typing-alias/pylintrc new file mode 100644 index 0000000..62d3136 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/deprecated-typing-alias/pylintrc @@ -0,0 +1,2 @@ +[main] +load-plugins = pylint.extensions.typing diff --git a/src/pylint/pylint-main/doc/data/messages/d/dict-init-mutate/bad.py b/src/pylint/pylint-main/doc/data/messages/d/dict-init-mutate/bad.py new file mode 100644 index 0000000..d7db9c5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/dict-init-mutate/bad.py @@ -0,0 +1,3 @@ +fruit_prices = {} # [dict-init-mutate] +fruit_prices["apple"] = 1 +fruit_prices["banana"] = 10 diff --git a/src/pylint/pylint-main/doc/data/messages/d/dict-init-mutate/good.py b/src/pylint/pylint-main/doc/data/messages/d/dict-init-mutate/good.py new file mode 100644 index 0000000..02137f2 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/dict-init-mutate/good.py @@ -0,0 +1 @@ +fruit_prices = {"apple": 1, "banana": 10} diff --git a/src/pylint/pylint-main/doc/data/messages/d/dict-init-mutate/pylintrc b/src/pylint/pylint-main/doc/data/messages/d/dict-init-mutate/pylintrc new file mode 100644 index 0000000..bbe6bd1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/dict-init-mutate/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins=pylint.extensions.dict_init_mutate, diff --git a/src/pylint/pylint-main/doc/data/messages/d/dict-iter-missing-items/bad.py b/src/pylint/pylint-main/doc/data/messages/d/dict-iter-missing-items/bad.py new file mode 100644 index 0000000..52efa3a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/dict-iter-missing-items/bad.py @@ -0,0 +1,3 @@ +data = {"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}.") diff --git a/src/pylint/pylint-main/doc/data/messages/d/dict-iter-missing-items/good.py b/src/pylint/pylint-main/doc/data/messages/d/dict-iter-missing-items/good.py new file mode 100644 index 0000000..3eb97f9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/dict-iter-missing-items/good.py @@ -0,0 +1,3 @@ +data = {"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}.") diff --git a/src/pylint/pylint-main/doc/data/messages/d/differing-param-doc/bad.py b/src/pylint/pylint-main/doc/data/messages/d/differing-param-doc/bad.py new file mode 100644 index 0000000..2a48d82 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/differing-param-doc/bad.py @@ -0,0 +1,8 @@ +def add(x, y): # [differing-param-doc] + """Add two numbers. + + :param int x: x value. + :param int z: z value. + """ + + return x + y diff --git a/src/pylint/pylint-main/doc/data/messages/d/differing-param-doc/good.py b/src/pylint/pylint-main/doc/data/messages/d/differing-param-doc/good.py new file mode 100644 index 0000000..8deac67 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/differing-param-doc/good.py @@ -0,0 +1,8 @@ +def add(x, y): + """Add two numbers. + + :param int x: x value. + :param int y: y value. + """ + + return x + y diff --git a/src/pylint/pylint-main/doc/data/messages/d/differing-param-doc/pylintrc b/src/pylint/pylint-main/doc/data/messages/d/differing-param-doc/pylintrc new file mode 100644 index 0000000..4547f98 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/differing-param-doc/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins = pylint.extensions.docparams diff --git a/src/pylint/pylint-main/doc/data/messages/d/differing-type-doc/bad.py b/src/pylint/pylint-main/doc/data/messages/d/differing-type-doc/bad.py new file mode 100644 index 0000000..18d41a9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/differing-type-doc/bad.py @@ -0,0 +1,8 @@ +def add(x: int, y: int): # [differing-type-doc] + """Add two numbers. + + :param int xy: x value. + :param str y: y value. + """ + + return x + y diff --git a/src/pylint/pylint-main/doc/data/messages/d/differing-type-doc/good.py b/src/pylint/pylint-main/doc/data/messages/d/differing-type-doc/good.py new file mode 100644 index 0000000..8deac67 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/differing-type-doc/good.py @@ -0,0 +1,8 @@ +def add(x, y): + """Add two numbers. + + :param int x: x value. + :param int y: y value. + """ + + return x + y diff --git a/src/pylint/pylint-main/doc/data/messages/d/differing-type-doc/pylintrc b/src/pylint/pylint-main/doc/data/messages/d/differing-type-doc/pylintrc new file mode 100644 index 0000000..4547f98 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/differing-type-doc/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins = pylint.extensions.docparams diff --git a/src/pylint/pylint-main/doc/data/messages/d/disallowed-name/bad.py b/src/pylint/pylint-main/doc/data/messages/d/disallowed-name/bad.py new file mode 100644 index 0000000..d28892d --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/disallowed-name/bad.py @@ -0,0 +1,2 @@ +def foo(): # [disallowed-name] + print("apples") diff --git a/src/pylint/pylint-main/doc/data/messages/d/disallowed-name/good.py b/src/pylint/pylint-main/doc/data/messages/d/disallowed-name/good.py new file mode 100644 index 0000000..b584b63 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/disallowed-name/good.py @@ -0,0 +1,2 @@ +def print_fruit(): + print("apples") diff --git a/src/pylint/pylint-main/doc/data/messages/d/disallowed-name/pylintrc b/src/pylint/pylint-main/doc/data/messages/d/disallowed-name/pylintrc new file mode 100644 index 0000000..5e07311 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/disallowed-name/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +bad-names=foo,bar,baz diff --git a/src/pylint/pylint-main/doc/data/messages/d/docstring-first-line-empty/bad.py b/src/pylint/pylint-main/doc/data/messages/d/docstring-first-line-empty/bad.py new file mode 100644 index 0000000..3ec9405 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/docstring-first-line-empty/bad.py @@ -0,0 +1,9 @@ +def 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 + """ diff --git a/src/pylint/pylint-main/doc/data/messages/d/docstring-first-line-empty/good.py b/src/pylint/pylint-main/doc/data/messages/d/docstring-first-line-empty/good.py new file mode 100644 index 0000000..16fdd55 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/docstring-first-line-empty/good.py @@ -0,0 +1,8 @@ +def 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 + """ diff --git a/src/pylint/pylint-main/doc/data/messages/d/docstring-first-line-empty/pylintrc b/src/pylint/pylint-main/doc/data/messages/d/docstring-first-line-empty/pylintrc new file mode 100644 index 0000000..c41e215 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/docstring-first-line-empty/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins = pylint.extensions.docstyle diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-argument-name/bad.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-argument-name/bad.py new file mode 100644 index 0000000..4c9c585 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-argument-name/bad.py @@ -0,0 +1,2 @@ +def get_fruits(apple, banana, apple): # [duplicate-argument-name] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-argument-name/good.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-argument-name/good.py new file mode 100644 index 0000000..9fe6d73 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-argument-name/good.py @@ -0,0 +1,2 @@ +def get_fruits(apple, banana, orange): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-bases/bad.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-bases/bad.py new file mode 100644 index 0000000..a68e390 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-bases/bad.py @@ -0,0 +1,6 @@ +class Animal: + pass + + +class Cat(Animal, Animal): # [duplicate-bases] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-bases/good.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-bases/good.py new file mode 100644 index 0000000..8ed2595 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-bases/good.py @@ -0,0 +1,10 @@ +class Animal: + pass + + +class Bird(Animal): + pass + + +class Cat(Animal): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/bad/__init__.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/bad/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/bad/apple.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/bad/apple.py new file mode 100644 index 0000000..10de7e6 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/bad/apple.py @@ -0,0 +1,14 @@ +class 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.") diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/bad/orange.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/bad/orange.py new file mode 100644 index 0000000..9be3c7b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/bad/orange.py @@ -0,0 +1,16 @@ +class 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.") diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/details.rst b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/details.rst new file mode 100644 index 0000000..07f5c72 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/details.rst @@ -0,0 +1,9 @@ +If 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. diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/good/__init__.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/good/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/good/apple.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/good/apple.py new file mode 100644 index 0000000..2d8cb72 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/good/apple.py @@ -0,0 +1,4 @@ +from fruit import Fruit + + +class Apple(Fruit): ... diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/good/fruit.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/good/fruit.py new file mode 100644 index 0000000..ecbd7ed --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/good/fruit.py @@ -0,0 +1,14 @@ +class 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.") diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/good/orange.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/good/orange.py new file mode 100644 index 0000000..7b5421a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-code/good/orange.py @@ -0,0 +1,8 @@ +from 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) diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-except/bad.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-except/bad.py new file mode 100644 index 0000000..e50b423 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-except/bad.py @@ -0,0 +1,6 @@ +try: + 1 / 0 +except ZeroDivisionError: + pass +except ZeroDivisionError: # [duplicate-except] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-except/good.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-except/good.py new file mode 100644 index 0000000..b02b365 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-except/good.py @@ -0,0 +1,4 @@ +try: + 1 / 0 +except ZeroDivisionError: + pass diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-key/bad.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-key/bad.py new file mode 100644 index 0000000..cfd1b59 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-key/bad.py @@ -0,0 +1 @@ +test_score = {"Mathematics": 85, "Biology": 90, "Mathematics": 75} # [duplicate-key] diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-key/good.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-key/good.py new file mode 100644 index 0000000..75447ce --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-key/good.py @@ -0,0 +1 @@ +test_score = {"Mathematics": 85, "Biology": 90, "History": 75} diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-key/related.rst b/src/pylint/pylint-main/doc/data/messages/d/duplicate-key/related.rst new file mode 100644 index 0000000..76391ea --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-key/related.rst @@ -0,0 +1,2 @@ +- `Python Dictionaries `_ +- `Mapping Types — dict `_ diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-string-formatting-argument/bad.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-string-formatting-argument/bad.py new file mode 100644 index 0000000..23d8aae --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-string-formatting-argument/bad.py @@ -0,0 +1,26 @@ +# 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, +) diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-string-formatting-argument/good.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-string-formatting-argument/good.py new file mode 100644 index 0000000..088c715 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-string-formatting-argument/good.py @@ -0,0 +1,13 @@ +# 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 +) diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-value/bad.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-value/bad.py new file mode 100644 index 0000000..975eebd --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-value/bad.py @@ -0,0 +1 @@ +incorrect_set = {"value1", 23, 5, "value1"} # [duplicate-value] diff --git a/src/pylint/pylint-main/doc/data/messages/d/duplicate-value/good.py b/src/pylint/pylint-main/doc/data/messages/d/duplicate-value/good.py new file mode 100644 index 0000000..beeeb39 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/d/duplicate-value/good.py @@ -0,0 +1 @@ +correct_set = {"value1", 23, 5} diff --git a/src/pylint/pylint-main/doc/data/messages/e/else-if-used/bad.py b/src/pylint/pylint-main/doc/data/messages/e/else-if-used/bad.py new file mode 100644 index 0000000..55cf422 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/else-if-used/bad.py @@ -0,0 +1,7 @@ +if input(): + pass +else: + if len(input()) >= 10: # [else-if-used] + pass + else: + pass diff --git a/src/pylint/pylint-main/doc/data/messages/e/else-if-used/good.py b/src/pylint/pylint-main/doc/data/messages/e/else-if-used/good.py new file mode 100644 index 0000000..39eb3ba --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/else-if-used/good.py @@ -0,0 +1,6 @@ +if input(): + pass +elif len(input()) >= 10: + pass +else: + pass diff --git a/src/pylint/pylint-main/doc/data/messages/e/else-if-used/pylintrc b/src/pylint/pylint-main/doc/data/messages/e/else-if-used/pylintrc new file mode 100644 index 0000000..5c43891 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/else-if-used/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins=pylint.extensions.check_elif diff --git a/src/pylint/pylint-main/doc/data/messages/e/empty-comment/bad.py b/src/pylint/pylint-main/doc/data/messages/e/empty-comment/bad.py new file mode 100644 index 0000000..f9d7f8e --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/empty-comment/bad.py @@ -0,0 +1,5 @@ +# +1:[empty-comment] +# + +# +1:[empty-comment] +x = 0 # diff --git a/src/pylint/pylint-main/doc/data/messages/e/empty-comment/good.py b/src/pylint/pylint-main/doc/data/messages/e/empty-comment/good.py new file mode 100644 index 0000000..f05c63d --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/empty-comment/good.py @@ -0,0 +1,3 @@ +# comment + +x = 0 # comment diff --git a/src/pylint/pylint-main/doc/data/messages/e/empty-comment/pylintrc b/src/pylint/pylint-main/doc/data/messages/e/empty-comment/pylintrc new file mode 100644 index 0000000..a773b55 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/empty-comment/pylintrc @@ -0,0 +1,2 @@ +[main] +load-plugins=pylint.extensions.empty_comment diff --git a/src/pylint/pylint-main/doc/data/messages/e/empty-docstring/bad.py b/src/pylint/pylint-main/doc/data/messages/e/empty-docstring/bad.py new file mode 100644 index 0000000..33dbb5f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/empty-docstring/bad.py @@ -0,0 +1,2 @@ +def foo(): # [empty-docstring] + """""" diff --git a/src/pylint/pylint-main/doc/data/messages/e/empty-docstring/good.py b/src/pylint/pylint-main/doc/data/messages/e/empty-docstring/good.py new file mode 100644 index 0000000..b587ca4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/empty-docstring/good.py @@ -0,0 +1,2 @@ +def foo(): + """A dummy description.""" diff --git a/src/pylint/pylint-main/doc/data/messages/e/eq-without-hash/bad.py b/src/pylint/pylint-main/doc/data/messages/e/eq-without-hash/bad.py new file mode 100644 index 0000000..42df9e8 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/eq-without-hash/bad.py @@ -0,0 +1,6 @@ +class Fruit: # [eq-without-hash] + def __init__(self) -> None: + self.name = "apple" + + def __eq__(self, other: object) -> bool: + return isinstance(other, Fruit) and other.name == self.name diff --git a/src/pylint/pylint-main/doc/data/messages/e/eq-without-hash/good.py b/src/pylint/pylint-main/doc/data/messages/e/eq-without-hash/good.py new file mode 100644 index 0000000..bf62450 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/eq-without-hash/good.py @@ -0,0 +1,9 @@ +class Fruit: + def __init__(self) -> None: + self.name = "apple" + + def __eq__(self, other: object) -> bool: + return isinstance(other, Fruit) and other.name == self.name + + def __hash__(self) -> int: + return hash(self.name) diff --git a/src/pylint/pylint-main/doc/data/messages/e/eq-without-hash/pylintrc b/src/pylint/pylint-main/doc/data/messages/e/eq-without-hash/pylintrc new file mode 100644 index 0000000..6e2e015 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/eq-without-hash/pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins=pylint.extensions.eq_without_hash, diff --git a/src/pylint/pylint-main/doc/data/messages/e/eval-used/bad.py b/src/pylint/pylint-main/doc/data/messages/e/eval-used/bad.py new file mode 100644 index 0000000..db26f17 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/eval-used/bad.py @@ -0,0 +1 @@ +eval("[1, 2, 3]") # [eval-used] diff --git a/src/pylint/pylint-main/doc/data/messages/e/eval-used/good.py b/src/pylint/pylint-main/doc/data/messages/e/eval-used/good.py new file mode 100644 index 0000000..094ecae --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/eval-used/good.py @@ -0,0 +1,3 @@ +from ast import literal_eval + +literal_eval("[1, 2, 3]") diff --git a/src/pylint/pylint-main/doc/data/messages/e/exec-used/bad.py b/src/pylint/pylint-main/doc/data/messages/e/exec-used/bad.py new file mode 100644 index 0000000..72514e3 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/exec-used/bad.py @@ -0,0 +1,4 @@ +username = "Ada" +code_to_execute = f"""input('Enter code to be executed please, {username}: ')""" +program = exec(code_to_execute) # [exec-used] +exec(program) # [exec-used] diff --git a/src/pylint/pylint-main/doc/data/messages/e/exec-used/details.rst b/src/pylint/pylint-main/doc/data/messages/e/exec-used/details.rst new file mode 100644 index 0000000..b803913 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/exec-used/details.rst @@ -0,0 +1,54 @@ +The available methods and variables used in ``exec()`` may introduce a security hole. +You can restrict the use of these variables and methods by passing optional globals +and locals parameters (dictionaries) to the ``exec()`` method. + +However, use of ``exec()`` is still insecure if you allow some functions like +``__import__`` or ``open``. For example, consider the following call that writes a +file to the user's system and then execute code unrestrained by the ``allowed_globals``, +or ``allowed_locals`` parameters: + +.. code-block:: python + + import textwrap + + + def forbid_print(*args): + raise ValueError("This is raised when a print is used") + + + allowed_globals = { + "__builtins__": { + "__import__": __builtins__.__import__, + "open": __builtins__.open, + "print": forbid_print, + } + } + + exec( + textwrap.dedent( + """ + import textwrap + + with open("nefarious.py", "w") as f: + f.write(textwrap.dedent(''' + def connive(): + print("Here's some code as nefarious as imaginable") + ''')) + + import nefarious + + nefarious.connive() # This will NOT raise a ValueError + """ + ), + allowed_globals, + ) + + +The import is used only for readability of the example in this case but it could +import a dangerous functions: + +- ``subprocess.run('echo "print(\"Hello, World!\")" > nefarious.py'`` +- ``pathlib.Path("nefarious.py").write_file("print(\"Hello, World!\")")`` +- ``os.system('echo "print(\"Hello, World!\")" > nefarious.py')`` +- ``logging.basicConfig(filename='nefarious.py'); logging.error('print("Hello, World!")')`` +- etc. diff --git a/src/pylint/pylint-main/doc/data/messages/e/exec-used/good.py b/src/pylint/pylint-main/doc/data/messages/e/exec-used/good.py new file mode 100644 index 0000000..fe247d5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/exec-used/good.py @@ -0,0 +1,11 @@ +def get_user_code(name): + return input(f"Enter code to be executed please, {name}: ") + + +username = "Ada" +# If the globals dictionary does not contain a value for the key __builtins__, +# all builtins are allowed. You need to be explicit about it being disallowed. +allowed_globals = {"__builtins__": {}} +allowed_locals = {} +# pylint: disable-next=exec-used +exec(get_user_code(username), allowed_globals, allowed_locals) diff --git a/src/pylint/pylint-main/doc/data/messages/e/exec-used/related.rst b/src/pylint/pylint-main/doc/data/messages/e/exec-used/related.rst new file mode 100644 index 0000000..e5d4f40 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/exec-used/related.rst @@ -0,0 +1,2 @@ +- `Be careful with exec and eval in Python `_ +- `Python documentation `_ diff --git a/src/pylint/pylint-main/doc/data/messages/e/expression-not-assigned/bad.py b/src/pylint/pylint-main/doc/data/messages/e/expression-not-assigned/bad.py new file mode 100644 index 0000000..fa696d4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/expression-not-assigned/bad.py @@ -0,0 +1 @@ +str(42) == "42" # [expression-not-assigned] diff --git a/src/pylint/pylint-main/doc/data/messages/e/expression-not-assigned/good.py b/src/pylint/pylint-main/doc/data/messages/e/expression-not-assigned/good.py new file mode 100644 index 0000000..fda04a8 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/e/expression-not-assigned/good.py @@ -0,0 +1 @@ +are_equal: bool = str(42) == "42" diff --git a/src/pylint/pylint-main/doc/data/messages/f/f-string-without-interpolation/bad.py b/src/pylint/pylint-main/doc/data/messages/f/f-string-without-interpolation/bad.py new file mode 100644 index 0000000..a317798 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/f-string-without-interpolation/bad.py @@ -0,0 +1,3 @@ +x = 1 +y = 2 +print(f"x + y = x + y") # [f-string-without-interpolation] diff --git a/src/pylint/pylint-main/doc/data/messages/f/f-string-without-interpolation/good.py b/src/pylint/pylint-main/doc/data/messages/f/f-string-without-interpolation/good.py new file mode 100644 index 0000000..9af2f97 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/f-string-without-interpolation/good.py @@ -0,0 +1,3 @@ +x = 1 +y = 2 +print(f"{x} + {y} = {x + y}") diff --git a/src/pylint/pylint-main/doc/data/messages/f/fatal/details.rst b/src/pylint/pylint-main/doc/data/messages/f/fatal/details.rst new file mode 100644 index 0000000..1c43031 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/fatal/details.rst @@ -0,0 +1 @@ +This is a message linked to an internal problem in pylint. There's nothing to change in your code. diff --git a/src/pylint/pylint-main/doc/data/messages/f/file-ignored/bad.py b/src/pylint/pylint-main/doc/data/messages/f/file-ignored/bad.py new file mode 100644 index 0000000..ce04564 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/file-ignored/bad.py @@ -0,0 +1,2 @@ +# pylint: skip-file +# -1: [file-ignored] diff --git a/src/pylint/pylint-main/doc/data/messages/f/file-ignored/details.rst b/src/pylint/pylint-main/doc/data/messages/f/file-ignored/details.rst new file mode 100644 index 0000000..c979ac7 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/file-ignored/details.rst @@ -0,0 +1 @@ +There's no checks at all for a file if it starts by ``# pylint: skip-file``. diff --git a/src/pylint/pylint-main/doc/data/messages/f/file-ignored/good.py b/src/pylint/pylint-main/doc/data/messages/f/file-ignored/good.py new file mode 100644 index 0000000..e69de29 diff --git a/src/pylint/pylint-main/doc/data/messages/f/fixme/bad.py b/src/pylint/pylint-main/doc/data/messages/f/fixme/bad.py new file mode 100644 index 0000000..47955d7 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/fixme/bad.py @@ -0,0 +1 @@ +# TODO: We should fix this at some point # [fixme] diff --git a/src/pylint/pylint-main/doc/data/messages/f/fixme/details.rst b/src/pylint/pylint-main/doc/data/messages/f/fixme/details.rst new file mode 100644 index 0000000..7f073bf --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/fixme/details.rst @@ -0,0 +1,2 @@ +You can use regular expressions and the ``notes-rgx`` option to create some constraints for this message. +See `the following issue `_ for some examples. diff --git a/src/pylint/pylint-main/doc/data/messages/f/fixme/good/bug_tracker.py b/src/pylint/pylint-main/doc/data/messages/f/fixme/good/bug_tracker.py new file mode 100644 index 0000000..b7e08f2 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/fixme/good/bug_tracker.py @@ -0,0 +1 @@ +# The issue was added to the bug tracker: no longer need the comment diff --git a/src/pylint/pylint-main/doc/data/messages/f/fixme/good/fixed.py b/src/pylint/pylint-main/doc/data/messages/f/fixme/good/fixed.py new file mode 100644 index 0000000..8d5a485 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/fixme/good/fixed.py @@ -0,0 +1 @@ +# The issue was fixed: no longer need the comment diff --git a/src/pylint/pylint-main/doc/data/messages/f/fixme/good/no_fix.py b/src/pylint/pylint-main/doc/data/messages/f/fixme/good/no_fix.py new file mode 100644 index 0000000..3f2f3af --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/fixme/good/no_fix.py @@ -0,0 +1 @@ +# We no longer want to fix this: no longer need the comment diff --git a/src/pylint/pylint-main/doc/data/messages/f/forgotten-debug-statement/bad.py b/src/pylint/pylint-main/doc/data/messages/f/forgotten-debug-statement/bad.py new file mode 100644 index 0000000..e371853 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/forgotten-debug-statement/bad.py @@ -0,0 +1,17 @@ +import 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) diff --git a/src/pylint/pylint-main/doc/data/messages/f/forgotten-debug-statement/good.py b/src/pylint/pylint-main/doc/data/messages/f/forgotten-debug-statement/good.py new file mode 100644 index 0000000..7896ff5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/forgotten-debug-statement/good.py @@ -0,0 +1,13 @@ +def 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) diff --git a/src/pylint/pylint-main/doc/data/messages/f/format-combined-specification/bad.py b/src/pylint/pylint-main/doc/data/messages/f/format-combined-specification/bad.py new file mode 100644 index 0000000..f530aa0 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/format-combined-specification/bad.py @@ -0,0 +1 @@ +print("{} {1}".format("hello", "world")) # [format-combined-specification] diff --git a/src/pylint/pylint-main/doc/data/messages/f/format-combined-specification/good/index_formatting.py b/src/pylint/pylint-main/doc/data/messages/f/format-combined-specification/good/index_formatting.py new file mode 100644 index 0000000..e8c1033 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/format-combined-specification/good/index_formatting.py @@ -0,0 +1 @@ +print("{0} {1}".format("hello", "world")) diff --git a/src/pylint/pylint-main/doc/data/messages/f/format-combined-specification/good/order_formatting.py b/src/pylint/pylint-main/doc/data/messages/f/format-combined-specification/good/order_formatting.py new file mode 100644 index 0000000..bbfb210 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/format-combined-specification/good/order_formatting.py @@ -0,0 +1 @@ +print("{} {}".format("hello", "world")) diff --git a/src/pylint/pylint-main/doc/data/messages/f/format-needs-mapping/bad.py b/src/pylint/pylint-main/doc/data/messages/f/format-needs-mapping/bad.py new file mode 100644 index 0000000..b265ccd --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/format-needs-mapping/bad.py @@ -0,0 +1 @@ +print("%(x)d %(y)d" % [1, 2]) # [format-needs-mapping] diff --git a/src/pylint/pylint-main/doc/data/messages/f/format-needs-mapping/good.py b/src/pylint/pylint-main/doc/data/messages/f/format-needs-mapping/good.py new file mode 100644 index 0000000..bed0122 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/format-needs-mapping/good.py @@ -0,0 +1 @@ +print("%(x)d %(y)d" % {"x": 1, "y": 2}) diff --git a/src/pylint/pylint-main/doc/data/messages/f/format-string-without-interpolation/bad.py b/src/pylint/pylint-main/doc/data/messages/f/format-string-without-interpolation/bad.py new file mode 100644 index 0000000..a5ff640 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/format-string-without-interpolation/bad.py @@ -0,0 +1 @@ +print("number".format(1)) # [format-string-without-interpolation] diff --git a/src/pylint/pylint-main/doc/data/messages/f/format-string-without-interpolation/good.py b/src/pylint/pylint-main/doc/data/messages/f/format-string-without-interpolation/good.py new file mode 100644 index 0000000..097f796 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/format-string-without-interpolation/good.py @@ -0,0 +1 @@ +print("number: {}".format(1)) diff --git a/src/pylint/pylint-main/doc/data/messages/f/function-redefined/bad.py b/src/pylint/pylint-main/doc/data/messages/f/function-redefined/bad.py new file mode 100644 index 0000000..0e3c308 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/function-redefined/bad.py @@ -0,0 +1,6 @@ +def get_email(): + pass + + +def get_email(): # [function-redefined] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/f/function-redefined/good.py b/src/pylint/pylint-main/doc/data/messages/f/function-redefined/good.py new file mode 100644 index 0000000..96efb4b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/f/function-redefined/good.py @@ -0,0 +1,2 @@ +def get_email(): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/g/global-at-module-level/bad.py b/src/pylint/pylint-main/doc/data/messages/g/global-at-module-level/bad.py new file mode 100644 index 0000000..e38da25 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/g/global-at-module-level/bad.py @@ -0,0 +1,2 @@ +price = 25 +global price # [global-at-module-level] diff --git a/src/pylint/pylint-main/doc/data/messages/g/global-at-module-level/good.py b/src/pylint/pylint-main/doc/data/messages/g/global-at-module-level/good.py new file mode 100644 index 0000000..4f37296 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/g/global-at-module-level/good.py @@ -0,0 +1 @@ +price = 25 diff --git a/src/pylint/pylint-main/doc/data/messages/g/global-at-module-level/related.rst b/src/pylint/pylint-main/doc/data/messages/g/global-at-module-level/related.rst new file mode 100644 index 0000000..6203356 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/g/global-at-module-level/related.rst @@ -0,0 +1,3 @@ +- `Official Python FAQ - global and local `_ +- `PEP 3104 - Access to Names in Outer Scopes `_ +- `Python global statement `_ diff --git a/src/pylint/pylint-main/doc/data/messages/g/global-statement/bad.py b/src/pylint/pylint-main/doc/data/messages/g/global-statement/bad.py new file mode 100644 index 0000000..aca1dab --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/g/global-statement/bad.py @@ -0,0 +1,11 @@ +var = 1 + + +def foo(): + global var # [global-statement] + var = 10 + print(var) + + +foo() +print(var) diff --git a/src/pylint/pylint-main/doc/data/messages/g/global-statement/good.py b/src/pylint/pylint-main/doc/data/messages/g/global-statement/good.py new file mode 100644 index 0000000..34958b5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/g/global-statement/good.py @@ -0,0 +1,10 @@ +var = 1 + + +def foo(): + print(var) + return 10 + + +var = foo() +print(var) diff --git a/src/pylint/pylint-main/doc/data/messages/g/global-variable-not-assigned/bad.py b/src/pylint/pylint-main/doc/data/messages/g/global-variable-not-assigned/bad.py new file mode 100644 index 0000000..d1d9075 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/g/global-variable-not-assigned/bad.py @@ -0,0 +1,6 @@ +TOMATO = "black cherry" + + +def update_tomato(): + global TOMATO # [global-variable-not-assigned] + print(TOMATO) diff --git a/src/pylint/pylint-main/doc/data/messages/g/global-variable-not-assigned/good.py b/src/pylint/pylint-main/doc/data/messages/g/global-variable-not-assigned/good.py new file mode 100644 index 0000000..0736bb4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/g/global-variable-not-assigned/good.py @@ -0,0 +1,6 @@ +TOMATO = "black cherry" + + +def update_tomato(): + global TOMATO + TOMATO = "moneymaker" diff --git a/src/pylint/pylint-main/doc/data/messages/g/global-variable-undefined/bad.py b/src/pylint/pylint-main/doc/data/messages/g/global-variable-undefined/bad.py new file mode 100644 index 0000000..44e4f3a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/g/global-variable-undefined/bad.py @@ -0,0 +1,3 @@ +def update_tomato(): + global TOMATO # [global-variable-undefined] + TOMATO = "moneymaker" diff --git a/src/pylint/pylint-main/doc/data/messages/g/global-variable-undefined/good.py b/src/pylint/pylint-main/doc/data/messages/g/global-variable-undefined/good.py new file mode 100644 index 0000000..0736bb4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/g/global-variable-undefined/good.py @@ -0,0 +1,6 @@ +TOMATO = "black cherry" + + +def update_tomato(): + global TOMATO + TOMATO = "moneymaker" diff --git a/src/pylint/pylint-main/doc/data/messages/i/implicit-flag-alias/bad.py b/src/pylint/pylint-main/doc/data/messages/i/implicit-flag-alias/bad.py new file mode 100644 index 0000000..1d12e4f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/implicit-flag-alias/bad.py @@ -0,0 +1,7 @@ +from enum import IntFlag + + +class FilePermissions(IntFlag): + READ = 1 + WRITE = 2 + EXECUTE = 3 # [implicit-flag-alias] diff --git a/src/pylint/pylint-main/doc/data/messages/i/implicit-flag-alias/good.py b/src/pylint/pylint-main/doc/data/messages/i/implicit-flag-alias/good.py new file mode 100644 index 0000000..78847d1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/implicit-flag-alias/good.py @@ -0,0 +1,7 @@ +from enum import IntFlag + + +class FilePermissions(IntFlag): + READ = 1 + WRITE = 2 + EXECUTE = 4 diff --git a/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/bad/list.py b/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/bad/list.py new file mode 100644 index 0000000..8d3180e --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/bad/list.py @@ -0,0 +1 @@ +x = ["a" "b"] # [implicit-str-concat] diff --git a/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/bad/open.py b/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/bad/open.py new file mode 100644 index 0000000..7cb4d06 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/bad/open.py @@ -0,0 +1,2 @@ +with open("hello.txt" "r") as f: # [implicit-str-concat] + print(f.read()) diff --git a/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/details.rst b/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/details.rst new file mode 100644 index 0000000..6b3f2c3 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/details.rst @@ -0,0 +1,39 @@ +By 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, + ) diff --git a/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/good/list.py b/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/good/list.py new file mode 100644 index 0000000..5457273 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/good/list.py @@ -0,0 +1 @@ +x = ["a", "b"] diff --git a/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/good/open.py b/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/good/open.py new file mode 100644 index 0000000..c5a337f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/implicit-str-concat/good/open.py @@ -0,0 +1,2 @@ +with open("hello.txt", "r") as f: + print(f.read()) diff --git a/src/pylint/pylint-main/doc/data/messages/i/import-error/bad.py b/src/pylint/pylint-main/doc/data/messages/i/import-error/bad.py new file mode 100644 index 0000000..672564c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/import-error/bad.py @@ -0,0 +1 @@ +from patlib import Path # [import-error] diff --git a/src/pylint/pylint-main/doc/data/messages/i/import-error/details.rst b/src/pylint/pylint-main/doc/data/messages/i/import-error/details.rst new file mode 100644 index 0000000..aaa3edc --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/import-error/details.rst @@ -0,0 +1,3 @@ +This 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. diff --git a/src/pylint/pylint-main/doc/data/messages/i/import-error/good.py b/src/pylint/pylint-main/doc/data/messages/i/import-error/good.py new file mode 100644 index 0000000..2bb88df --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/import-error/good.py @@ -0,0 +1 @@ +from pathlib import Path diff --git a/src/pylint/pylint-main/doc/data/messages/i/import-outside-toplevel/bad.py b/src/pylint/pylint-main/doc/data/messages/i/import-outside-toplevel/bad.py new file mode 100644 index 0000000..5262ba7 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/import-outside-toplevel/bad.py @@ -0,0 +1,4 @@ +def print_python_version(): + import sys # [import-outside-toplevel] + + print(sys.version_info) diff --git a/src/pylint/pylint-main/doc/data/messages/i/import-outside-toplevel/good.py b/src/pylint/pylint-main/doc/data/messages/i/import-outside-toplevel/good.py new file mode 100644 index 0000000..d77c91a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/import-outside-toplevel/good.py @@ -0,0 +1,5 @@ +import sys + + +def print_python_version(): + print(sys.version_info) diff --git a/src/pylint/pylint-main/doc/data/messages/i/import-private-name/bad.py b/src/pylint/pylint-main/doc/data/messages/i/import-private-name/bad.py new file mode 100644 index 0000000..e562e49 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/import-private-name/bad.py @@ -0,0 +1,8 @@ +from argparse import _AttributeHolder, _SubParsersAction # [import-private-name] + +attr_holder = _AttributeHolder() + + +def add_sub_parser(sub_parsers: _SubParsersAction): + sub_parsers.add_parser("my_subparser") + # ... diff --git a/src/pylint/pylint-main/doc/data/messages/i/import-private-name/details.rst b/src/pylint/pylint-main/doc/data/messages/i/import-private-name/details.rst new file mode 100644 index 0000000..48c1089 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/import-private-name/details.rst @@ -0,0 +1,2 @@ +Using private imports expose you to unexpected breaking changes for any version +bump of your dependencies, even in patch versions. diff --git a/src/pylint/pylint-main/doc/data/messages/i/import-private-name/good.py b/src/pylint/pylint-main/doc/data/messages/i/import-private-name/good.py new file mode 100644 index 0000000..810005f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/import-private-name/good.py @@ -0,0 +1,8 @@ +"""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") + # ... diff --git a/src/pylint/pylint-main/doc/data/messages/i/import-private-name/pylintrc b/src/pylint/pylint-main/doc/data/messages/i/import-private-name/pylintrc new file mode 100644 index 0000000..09cf103 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/import-private-name/pylintrc @@ -0,0 +1,2 @@ +[main] +load-plugins = pylint.extensions.private_import diff --git a/src/pylint/pylint-main/doc/data/messages/i/import-self/details.rst b/src/pylint/pylint-main/doc/data/messages/i/import-self/details.rst new file mode 100644 index 0000000..47711bc --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/import-self/details.rst @@ -0,0 +1,12 @@ +Say 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 diff --git a/src/pylint/pylint-main/doc/data/messages/i/inconsistent-mro/bad.py b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-mro/bad.py new file mode 100644 index 0000000..93f9aa5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-mro/bad.py @@ -0,0 +1,10 @@ +class A: + pass + + +class B(A): + pass + + +class C(A, B): # [inconsistent-mro] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/i/inconsistent-mro/good.py b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-mro/good.py new file mode 100644 index 0000000..5fccd63 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-mro/good.py @@ -0,0 +1,10 @@ +class A: + pass + + +class B(A): + pass + + +class C(B): # or 'B, A' or 'A' but not 'A, B' + pass diff --git a/src/pylint/pylint-main/doc/data/messages/i/inconsistent-quotes/bad.py b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-quotes/bad.py new file mode 100644 index 0000000..2a18366 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-quotes/bad.py @@ -0,0 +1,3 @@ +import datetime + +print('Current year: ', datetime.date.today().strftime("%Y")) # [inconsistent-quotes] diff --git a/src/pylint/pylint-main/doc/data/messages/i/inconsistent-quotes/good.py b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-quotes/good.py new file mode 100644 index 0000000..87431bc --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-quotes/good.py @@ -0,0 +1,3 @@ +import datetime + +print("Current year: ", datetime.date.today().strftime("%Y")) diff --git a/src/pylint/pylint-main/doc/data/messages/i/inconsistent-quotes/pylintrc b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-quotes/pylintrc new file mode 100644 index 0000000..5d2f27f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-quotes/pylintrc @@ -0,0 +1,2 @@ +[main] +check-quote-consistency=yes diff --git a/src/pylint/pylint-main/doc/data/messages/i/inconsistent-return-statements/bad.py b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-return-statements/bad.py new file mode 100644 index 0000000..32bf948 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-return-statements/bad.py @@ -0,0 +1,3 @@ +def get_the_answer(value: str) -> str | None: # [inconsistent-return-statements] + if value: + return value diff --git a/src/pylint/pylint-main/doc/data/messages/i/inconsistent-return-statements/good.py b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-return-statements/good.py new file mode 100644 index 0000000..991527b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/inconsistent-return-statements/good.py @@ -0,0 +1,4 @@ +def get_the_answer(value: str) -> str | None: + if value: + return value + return None diff --git a/src/pylint/pylint-main/doc/data/messages/i/inherit-non-class/bad.py b/src/pylint/pylint-main/doc/data/messages/i/inherit-non-class/bad.py new file mode 100644 index 0000000..4a7926c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/inherit-non-class/bad.py @@ -0,0 +1,2 @@ +class Fruit(bool): # [inherit-non-class] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/i/inherit-non-class/good.py b/src/pylint/pylint-main/doc/data/messages/i/inherit-non-class/good.py new file mode 100644 index 0000000..dc48bd0 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/inherit-non-class/good.py @@ -0,0 +1,3 @@ +class Fruit: + def __bool__(self): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/i/init-is-generator/bad.py b/src/pylint/pylint-main/doc/data/messages/i/init-is-generator/bad.py new file mode 100644 index 0000000..415b94c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/init-is-generator/bad.py @@ -0,0 +1,6 @@ +class Fruit: + def __init__(self, worms): # [init-is-generator] + yield from worms + + +apple = Fruit(["Fahad", "Anisha", "Tabatha"]) diff --git a/src/pylint/pylint-main/doc/data/messages/i/init-is-generator/good.py b/src/pylint/pylint-main/doc/data/messages/i/init-is-generator/good.py new file mode 100644 index 0000000..1f5bf00 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/init-is-generator/good.py @@ -0,0 +1,11 @@ +class Fruit: + def __init__(self, worms): + self.__worms = worms + + def worms(self): + yield from self.__worms + + +apple = Fruit(["Fahad", "Anisha", "Tabatha"]) +for worm in apple.worms(): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-all-format/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-all-format/bad.py new file mode 100644 index 0000000..c891377 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-all-format/bad.py @@ -0,0 +1,3 @@ +__all__ = "CONST" # [invalid-all-format] + +CONST = 42 diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-all-format/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-all-format/good.py new file mode 100644 index 0000000..bb64b60 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-all-format/good.py @@ -0,0 +1,3 @@ +__all__ = ("CONST",) + +CONST = 42 diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-all-object/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-all-object/bad.py new file mode 100644 index 0000000..0450972 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-all-object/bad.py @@ -0,0 +1,13 @@ +__all__ = ( + None, # [invalid-all-object] + Fruit, + Worm, +) + + +class Fruit: + pass + + +class Worm: + pass diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-all-object/details.rst b/src/pylint/pylint-main/doc/data/messages/i/invalid-all-object/details.rst new file mode 100644 index 0000000..db3d100 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-all-object/details.rst @@ -0,0 +1,2 @@ +From `The Python Language Reference – The import statement `_: + "The `public names` defined by a module are determined by checking the module's namespace for a variable named ``__all__``; if defined, it must be a sequence of strings which are names defined or imported by that module." diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-all-object/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-all-object/good.py new file mode 100644 index 0000000..351cfa1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-all-object/good.py @@ -0,0 +1,9 @@ +__all__ = ["Fruit", "Worm"] + + +class Fruit: + pass + + +class Worm: + pass diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-all-object/related.rst b/src/pylint/pylint-main/doc/data/messages/i/invalid-all-object/related.rst new file mode 100644 index 0000000..fff337e --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-all-object/related.rst @@ -0,0 +1 @@ +- `PEP 8 – Style Guide for Python Code `_ diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-bool-returned/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-bool-returned/bad.py new file mode 100644 index 0000000..74c0000 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-bool-returned/bad.py @@ -0,0 +1,5 @@ +class CustomBool: + """__bool__ returns an int""" + + def __bool__(self): # [invalid-bool-returned] + return 1 diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-bool-returned/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-bool-returned/good.py new file mode 100644 index 0000000..9bca165 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-bool-returned/good.py @@ -0,0 +1,5 @@ +class CustomBool: + """__bool__ returns `bool`""" + + def __bool__(self): + return True diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-bytes-returned/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-bytes-returned/bad.py new file mode 100644 index 0000000..e20e590 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-bytes-returned/bad.py @@ -0,0 +1,5 @@ +class CustomBytes: + """__bytes__ returns """ + + def __bytes__(self): # [invalid-bytes-returned] + return "123" diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-bytes-returned/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-bytes-returned/good.py new file mode 100644 index 0000000..548303d --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-bytes-returned/good.py @@ -0,0 +1,5 @@ +class CustomBytes: + """__bytes__ returns """ + + def __bytes__(self): + return b"some bytes" diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-backspace/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-backspace/bad.py new file mode 100644 index 0000000..ac9ed67 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-backspace/bad.py @@ -0,0 +1 @@ +STRING = "Invalid character backspace " # [invalid-character-backspace] diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-backspace/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-backspace/good.py new file mode 100644 index 0000000..3381c5f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-backspace/good.py @@ -0,0 +1 @@ +STRING = "Valid character backspace \b" diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-carriage-return/details.rst b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-carriage-return/details.rst new file mode 100644 index 0000000..283e7b5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-carriage-return/details.rst @@ -0,0 +1,5 @@ +This message exists because one of our checkers is very generic, but it's never going to +raise during normal use as it's a ``syntax-error`` that would prevent the python ast +(and thus pylint) from constructing a code representation of the file. + +You could encounter it by feeding a properly constructed node directly to the checker. diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-carriage-return/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-carriage-return/good.py new file mode 100644 index 0000000..ae08661 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-carriage-return/good.py @@ -0,0 +1 @@ +STRING = "Valid carriage return: \r" diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-esc/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-esc/bad.py new file mode 100644 index 0000000..0d50cab --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-esc/bad.py @@ -0,0 +1 @@ +STRING = "Invalid escape character " # [invalid-character-esc] diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-esc/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-esc/good.py new file mode 100644 index 0000000..48ed2d8 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-esc/good.py @@ -0,0 +1 @@ +STRING = "Valid escape character \x1b" diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-nul/details.rst b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-nul/details.rst new file mode 100644 index 0000000..c131132 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-nul/details.rst @@ -0,0 +1,2 @@ +There's no need to use end-of-string characters. String objects maintain their +own length. diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-nul/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-nul/good.py new file mode 100644 index 0000000..97e1a3b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-nul/good.py @@ -0,0 +1 @@ +STRING = "Valid nul terminator: \x00" diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-nul/related.rst b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-nul/related.rst new file mode 100644 index 0000000..2f08c33 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-nul/related.rst @@ -0,0 +1 @@ +- `Null terminator in python `_ diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-sub/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-sub/bad.py new file mode 100644 index 0000000..313066d --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-sub/bad.py @@ -0,0 +1 @@ +STRING = "Invalid character sub " # [invalid-character-sub] diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-sub/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-sub/good.py new file mode 100644 index 0000000..5dd4aa4 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-sub/good.py @@ -0,0 +1 @@ +STRING = "Valid character sub x1A" diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-zero-width-space/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-zero-width-space/bad.py new file mode 100644 index 0000000..99160fc --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-zero-width-space/bad.py @@ -0,0 +1 @@ +STRING = "Invalid character zero-width-space ​" # [invalid-character-zero-width-space] diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-character-zero-width-space/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-zero-width-space/good.py new file mode 100644 index 0000000..391bcf0 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-character-zero-width-space/good.py @@ -0,0 +1 @@ +STRING = "Valid character zero-width-space u200B" diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-characters-in-docstring/details.rst b/src/pylint/pylint-main/doc/data/messages/i/invalid-characters-in-docstring/details.rst new file mode 100644 index 0000000..9977db1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-characters-in-docstring/details.rst @@ -0,0 +1,2 @@ +This is a message linked to an internal problem in enchant. There's nothing to change in your code, +but maybe in pylint's configuration or the way you installed the 'enchant' system library. diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-class-object/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-class-object/bad.py new file mode 100644 index 0000000..5c6a6f8 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-class-object/bad.py @@ -0,0 +1,5 @@ +class Apple: + pass + + +Apple.__class__ = 1 # [invalid-class-object] diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-class-object/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-class-object/good.py new file mode 100644 index 0000000..3b50097 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-class-object/good.py @@ -0,0 +1,9 @@ +class Apple: + pass + + +class RedDelicious: + pass + + +Apple.__class__ = RedDelicious diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-enum-extension/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-enum-extension/bad.py new file mode 100644 index 0000000..2a2a010 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-enum-extension/bad.py @@ -0,0 +1,10 @@ +from enum import Enum + + +class Color(Enum): + ORANGE = 1 + CHERRY = 2 + + +class Fruit(Color): # [invalid-enum-extension] + APPLE = 3 diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-enum-extension/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-enum-extension/good.py new file mode 100644 index 0000000..80a4115 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-enum-extension/good.py @@ -0,0 +1,12 @@ +from enum import Enum + + +class Color(Enum): + ORANGE = 1 + CHERRY = 2 + + +class Fruit(Enum): + ORANGE = 1 + CHERRY = 2 + APPLE = 3 diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-envvar-default/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-envvar-default/bad.py new file mode 100644 index 0000000..9b564b9 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-envvar-default/bad.py @@ -0,0 +1,3 @@ +import os + +env = os.getenv("SECRET_KEY", 1) # [invalid-envvar-default] diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-envvar-default/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-envvar-default/good.py new file mode 100644 index 0000000..1039259 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-envvar-default/good.py @@ -0,0 +1,3 @@ +import os + +env = os.getenv("SECRET_KEY", "1") diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-envvar-value/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-envvar-value/bad.py new file mode 100644 index 0000000..56e60fe --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-envvar-value/bad.py @@ -0,0 +1,3 @@ +import os + +os.getenv(1) # [invalid-envvar-value] diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-envvar-value/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-envvar-value/good.py new file mode 100644 index 0000000..fd082ec --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-envvar-value/good.py @@ -0,0 +1,3 @@ +import os + +os.getenv("1") diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-field-call/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-field-call/bad.py new file mode 100644 index 0000000..56e3575 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-field-call/bad.py @@ -0,0 +1,16 @@ +from dataclasses import dataclass, field + + +@dataclass +class C: + a: float + b: float + c: float + + field(init=False) # [invalid-field-call] + + def __post_init__(self): + self.c = self.a + self.b + + +print(field(init=False)) # [invalid-field-call] diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-field-call/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-field-call/good.py new file mode 100644 index 0000000..8a8d891 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-field-call/good.py @@ -0,0 +1,17 @@ +from dataclasses import dataclass, field, make_dataclass + +C = make_dataclass( + "C", + [("x", int), "y", ("z", int, field(default=5))], + namespace={"add_one": lambda self: self.x + 1}, +) + + +@dataclass +class C: + a: float + b: float + c: float = field(init=False) + + def __post_init__(self): + self.c = self.a + self.b diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-format-index/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-format-index/bad.py new file mode 100644 index 0000000..74e6502 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-format-index/bad.py @@ -0,0 +1,2 @@ +not_enough_fruits = ["apple"] +print('The second fruit is a {fruits[1]}'.format(fruits=not_enough_fruits)) # [invalid-format-index] diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-format-index/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-format-index/good.py new file mode 100644 index 0000000..6955798 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-format-index/good.py @@ -0,0 +1,2 @@ +enough_fruits = ["apple", "banana"] +print("The second fruit is a {fruits[1]}".format(fruits=enough_fruits)) diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-format-returned/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-format-returned/bad.py new file mode 100644 index 0000000..8281084 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-format-returned/bad.py @@ -0,0 +1,5 @@ +class CustomFormat: + """__format__ returns """ + + def __format__(self, format_spec): # [invalid-format-returned] + return 1 diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-format-returned/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-format-returned/good.py new file mode 100644 index 0000000..66b13cc --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-format-returned/good.py @@ -0,0 +1,5 @@ +class CustomFormat: + """__format__ returns """ + + def __format__(self, format_spec): + return "hello!" diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-getnewargs-ex-returned/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-getnewargs-ex-returned/bad.py new file mode 100644 index 0000000..e07bdd7 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-getnewargs-ex-returned/bad.py @@ -0,0 +1,5 @@ +class CustomGetNewArgsEx: + """__getnewargs_ex__ returns tuple with incorrect arg length""" + + def __getnewargs_ex__(self): # [invalid-getnewargs-ex-returned] + return (tuple(1), dict(x="y"), 1) diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-getnewargs-ex-returned/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-getnewargs-ex-returned/good.py new file mode 100644 index 0000000..9d6e31c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-getnewargs-ex-returned/good.py @@ -0,0 +1,5 @@ +class CustomGetNewArgsEx: + """__getnewargs_ex__ returns """ + + def __getnewargs_ex__(self): + return ((1,), {"2": 2}) diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-getnewargs-returned/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-getnewargs-returned/bad.py new file mode 100644 index 0000000..e82523b --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-getnewargs-returned/bad.py @@ -0,0 +1,5 @@ +class CustomGetNewArgs: + """__getnewargs__ returns an integer""" + + def __getnewargs__(self): # [invalid-getnewargs-returned] + return 1 diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-getnewargs-returned/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-getnewargs-returned/good.py new file mode 100644 index 0000000..e61376c --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-getnewargs-returned/good.py @@ -0,0 +1,5 @@ +class CustomGetNewArgs: + """__getnewargs__ returns """ + + def __getnewargs__(self): + return (1, 2) diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-hash-returned/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-hash-returned/bad.py new file mode 100644 index 0000000..2c4508f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-hash-returned/bad.py @@ -0,0 +1,5 @@ +class CustomHash: + """__hash__ returns dict""" + + def __hash__(self): # [invalid-hash-returned] + return {} diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-hash-returned/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-hash-returned/good.py new file mode 100644 index 0000000..b18ebc1 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-hash-returned/good.py @@ -0,0 +1,5 @@ +class CustomHash: + """__hash__ returns `int`""" + + def __hash__(self): + return 19 diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-index-returned/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-index-returned/bad.py new file mode 100644 index 0000000..922abdf --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-index-returned/bad.py @@ -0,0 +1,5 @@ +class CustomIndex: + """__index__ returns a dict""" + + def __index__(self): # [invalid-index-returned] + return {"19": "19"} diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-index-returned/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-index-returned/good.py new file mode 100644 index 0000000..3b166be --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-index-returned/good.py @@ -0,0 +1,5 @@ +class CustomIndex: + """__index__ returns """ + + def __index__(self): + return 19 diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-length-hint-returned/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-length-hint-returned/bad.py new file mode 100644 index 0000000..ef33425 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-length-hint-returned/bad.py @@ -0,0 +1,5 @@ +class CustomLengthHint: + """__length_hint__ returns non-int""" + + def __length_hint__(self): # [invalid-length-hint-returned] + return 3.0 diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-length-hint-returned/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-length-hint-returned/good.py new file mode 100644 index 0000000..8c80a29 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-length-hint-returned/good.py @@ -0,0 +1,5 @@ +class CustomLengthHint: + """__length_hint__ returns """ + + def __length_hint__(self): + return 10 diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-length-returned/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-length-returned/bad.py new file mode 100644 index 0000000..2ae1396 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-length-returned/bad.py @@ -0,0 +1,6 @@ +class FruitBasket: + def __init__(self, fruits): + self.fruits = ["Apple", "Banana", "Orange"] + + def __len__(self): # [invalid-length-returned] + return -len(self.fruits) diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-length-returned/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-length-returned/good.py new file mode 100644 index 0000000..1af7189 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-length-returned/good.py @@ -0,0 +1,6 @@ +class FruitBasket: + def __init__(self, fruits): + self.fruits = ["Apple", "Banana", "Orange"] + + def __len__(self): + return len(self.fruits) diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-match-args-definition/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-match-args-definition/bad.py new file mode 100644 index 0000000..de18156 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-match-args-definition/bad.py @@ -0,0 +1,6 @@ +class Book: + __match_args__ = ["title", "year"] # [invalid-match-args-definition] + + def __init__(self, title, year): + self.title = title + self.year = year diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-match-args-definition/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-match-args-definition/good.py new file mode 100644 index 0000000..7edfc8a --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-match-args-definition/good.py @@ -0,0 +1,6 @@ +class Book: + __match_args__ = ("title", "year") + + def __init__(self, title, year): + self.title = title + self.year = year diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-match-args-definition/related.rst b/src/pylint/pylint-main/doc/data/messages/i/invalid-match-args-definition/related.rst new file mode 100644 index 0000000..d96d113 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-match-args-definition/related.rst @@ -0,0 +1 @@ +- `Python documentation `_ diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-metaclass/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-metaclass/bad.py new file mode 100644 index 0000000..301b4f2 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-metaclass/bad.py @@ -0,0 +1,2 @@ +class Apple(metaclass=int): # [invalid-metaclass] + pass diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-metaclass/good.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-metaclass/good.py new file mode 100644 index 0000000..07c907f --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-metaclass/good.py @@ -0,0 +1,6 @@ +class Plant: + pass + + +class Apple(Plant): + pass diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-name/bad.py b/src/pylint/pylint-main/doc/data/messages/i/invalid-name/bad.py new file mode 100644 index 0000000..b40ee47 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-name/bad.py @@ -0,0 +1,7 @@ +class cat: # [invalid-name] + def Meow(self, NUMBER_OF_MEOW): # [invalid-name, invalid-name] + print("Meow" * NUMBER_OF_MEOW) + return NUMBER_OF_MEOW + + +Cat = cat().Meow(42) # [invalid-name] diff --git a/src/pylint/pylint-main/doc/data/messages/i/invalid-name/details.rst b/src/pylint/pylint-main/doc/data/messages/i/invalid-name/details.rst new file mode 100644 index 0000000..140eeb5 --- /dev/null +++ b/src/pylint/pylint-main/doc/data/messages/i/invalid-name/details.rst @@ -0,0 +1,212 @@ +Pylint 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=