lintro 0.11.0__tar.gz → 0.12.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of lintro might be problematic. Click here for more details.
- {lintro-0.11.0/lintro.egg-info → lintro-0.12.0}/PKG-INFO +1 -1
- {lintro-0.11.0 → lintro-0.12.0}/docs/tool-analysis/ruff-analysis.md +2 -2
- {lintro-0.11.0 → lintro-0.12.0}/lintro/__init__.py +1 -1
- {lintro-0.11.0 → lintro-0.12.0}/lintro/cli_utils/commands/format.py +2 -2
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/prettier/prettier_parser.py +1 -1
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/__init__.py +1 -1
- {lintro-0.11.0 → lintro-0.12.0}/lintro/utils/tool_executor.py +1 -1
- {lintro-0.11.0 → lintro-0.12.0}/lintro/utils/tool_utils.py +1 -1
- {lintro-0.11.0 → lintro-0.12.0/lintro.egg-info}/PKG-INFO +1 -1
- {lintro-0.11.0 → lintro-0.12.0}/lintro.egg-info/SOURCES.txt +2 -0
- {lintro-0.11.0 → lintro-0.12.0}/pyproject.toml +5 -5
- lintro-0.12.0/test_samples/ruff_bugbear_violations.py +243 -0
- lintro-0.12.0/tests/integration/test_ruff_bugbear.py +165 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/scripts/test_script_environment.py +1 -1
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_cli_programmatic.py +1 -1
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_tool_executor_more.py +8 -2
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_tool_utils_fallbacks.py +6 -2
- {lintro-0.11.0 → lintro-0.12.0}/LICENSE +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/MANIFEST.in +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/README.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/assets/images/coverage-badge.svg +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/assets/images/lintro.png +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/README.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/configuration.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/contributing.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/coverage-setup.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/docker.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/getting-started.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/github-integration.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/lintro-self-use.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/security/assurance.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/security/requirements.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/style-guide.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/tool-analysis/README.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/tool-analysis/actionlint-analysis.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/tool-analysis/bandit-analysis.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/tool-analysis/black-analysis.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/tool-analysis/darglint-analysis.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/tool-analysis/hadolint-analysis.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/tool-analysis/prettier-analysis.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/docs/tool-analysis/yamllint-analysis.md +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/__main__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/ascii-art/fail.txt +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/ascii-art/success.txt +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/cli.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/cli_utils/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/cli_utils/commands/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/cli_utils/commands/check.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/cli_utils/commands/list_tools.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/enums/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/enums/action.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/enums/darglint_strictness.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/enums/group_by.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/enums/hadolint_enums.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/enums/output_format.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/enums/tool_name.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/enums/tool_type.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/enums/yamllint_format.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/exceptions/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/exceptions/errors.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/core/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/core/output_style.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/core/table_descriptor.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/styles/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/styles/csv.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/styles/grid.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/styles/html.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/styles/json.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/styles/markdown.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/styles/plain.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/tools/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/tools/actionlint_formatter.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/tools/bandit_formatter.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/tools/black_formatter.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/tools/darglint_formatter.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/tools/hadolint_formatter.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/tools/prettier_formatter.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/tools/ruff_formatter.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/formatters/tools/yamllint_formatter.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/models/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/models/core/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/models/core/tool.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/models/core/tool_config.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/models/core/tool_result.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/actionlint/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/actionlint/actionlint_issue.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/actionlint/actionlint_parser.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/black/black_issue.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/black/black_parser.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/darglint/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/darglint/darglint_issue.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/darglint/darglint_parser.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/hadolint/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/hadolint/hadolint_issue.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/hadolint/hadolint_parser.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/prettier/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/prettier/prettier_issue.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/ruff/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/ruff/ruff_issue.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/ruff/ruff_parser.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/yamllint/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/yamllint/yamllint_issue.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/parsers/yamllint/yamllint_parser.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/core/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/core/tool_base.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/core/tool_manager.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/implementations/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/implementations/tool_actionlint.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/implementations/tool_bandit.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/implementations/tool_black.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/implementations/tool_darglint.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/implementations/tool_hadolint.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/implementations/tool_prettier.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/implementations/tool_ruff.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/implementations/tool_yamllint.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/tools/tool_enum.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/utils/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/utils/ascii_normalize_cli.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/utils/config.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/utils/console_logger.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/utils/formatting.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/utils/output_manager.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro/utils/path_utils.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro.egg-info/dependency_links.txt +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro.egg-info/entry_points.txt +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro.egg-info/requires.txt +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/lintro.egg-info/top_level.txt +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/setup.cfg +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/test_samples/Dockerfile.violations +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/test_samples/actionlint_violations.yml +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/test_samples/bandit_violations.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/test_samples/darglint_violations.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/test_samples/prettier_violations.js +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/test_samples/ruff_annotations_violations.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/test_samples/ruff_black_e501_wrappable.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/test_samples/ruff_clean.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/test_samples/ruff_naming_violations.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/test_samples/ruff_violations.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/test_samples/yaml_violations.yml +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/cli/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/cli/conftest.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/cli/test_cli.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/conftest.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/formatters/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/formatters/conftest.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/formatters/test_formatters.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/integration/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/integration/conftest.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/integration/test_actionlint_integration.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/integration/test_bandit_integration.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/integration/test_darglint_integration.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/integration/test_hadolint_integration.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/integration/test_prettier_integration.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/integration/test_ruff_annotations.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/integration/test_ruff_black_policy.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/integration/test_ruff_integration.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/integration/test_ruff_naming.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/integration/test_yamllint_integration.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/scripts/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/scripts/test_ci_post_pr_comment.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/scripts/test_delete_previous_lintro_comments.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/scripts/test_extract_version.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/scripts/test_ghcr_prune_untagged.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/scripts/test_github_comment_utilities.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/scripts/test_semantic_release_compute_next.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/scripts/test_shell_scripts.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/test_documentation.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_ascii_normalize.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_bandit_command_building.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_bandit_config_hydration.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_bandit_formatter_mapping.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_bandit_parsing.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_black_formatter.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_black_parser.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_black_tool.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_black_tool_more.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_cli_commands.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_cli_commands_more.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_compatibility_ruff_black.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_config_loader.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_config_loader_more.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_console_logger.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_console_logger_more.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_enums_and_normalizers.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_exceptions.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_formatters_tables.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_output_manager_reports.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_parsers_actionlint.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_ruff_parser_additional.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_ruff_parser_more.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_subprocess_validator.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_tool_base_subprocess.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_tool_executor.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_tool_executor_fmt_exclusion.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_tool_executor_post_checks.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_tool_manager.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_tool_utils.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/unit/test_tool_utils_more.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/utils/__init__.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/utils/conftest.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/utils/test_formatting.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/utils/test_output_manager.py +0 -0
- {lintro-0.11.0 → lintro-0.12.0}/tests/utils/test_path_utils.py +0 -0
|
@@ -151,7 +151,7 @@ lintro check --tool-options "ruff:format_check=True"
|
|
|
151
151
|
ruff check src/
|
|
152
152
|
|
|
153
153
|
# With specific rules
|
|
154
|
-
ruff check --select E501,W503 src/
|
|
154
|
+
ruff check --select E501,W503,B006 src/
|
|
155
155
|
|
|
156
156
|
# Auto-fixing
|
|
157
157
|
ruff check --fix src/
|
|
@@ -176,7 +176,7 @@ ruff_tool.fix()
|
|
|
176
176
|
|
|
177
177
|
# With specific options
|
|
178
178
|
ruff_tool.set_options(
|
|
179
|
-
select=["E501", "W503"],
|
|
179
|
+
select=["E501", "W503", "B006"],
|
|
180
180
|
line_length=88,
|
|
181
181
|
unsafe_fixes=True
|
|
182
182
|
)
|
|
@@ -140,7 +140,7 @@ def format_code_legacy(
|
|
|
140
140
|
None: This function does not return a value.
|
|
141
141
|
|
|
142
142
|
Raises:
|
|
143
|
-
|
|
143
|
+
RuntimeError: If format fails for any reason.
|
|
144
144
|
"""
|
|
145
145
|
args: list[str] = []
|
|
146
146
|
if paths:
|
|
@@ -163,5 +163,5 @@ def format_code_legacy(
|
|
|
163
163
|
runner = CliRunner()
|
|
164
164
|
result = runner.invoke(format_code, args)
|
|
165
165
|
if result.exit_code != DEFAULT_EXIT_CODE:
|
|
166
|
-
raise
|
|
166
|
+
raise RuntimeError(f"Format failed: {result.output}")
|
|
167
167
|
return None
|
|
@@ -21,7 +21,7 @@ tool_manager = ToolManager()
|
|
|
21
21
|
AVAILABLE_TOOLS = {tool_enum: tool_enum.value for tool_enum in ToolEnum}
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
for
|
|
24
|
+
for _tool_enum, tool_class in AVAILABLE_TOOLS.items():
|
|
25
25
|
tool_manager.register_tool(tool_class)
|
|
26
26
|
|
|
27
27
|
# Consolidated exports
|
|
@@ -127,6 +127,7 @@ test_samples/darglint_violations.py
|
|
|
127
127
|
test_samples/prettier_violations.js
|
|
128
128
|
test_samples/ruff_annotations_violations.py
|
|
129
129
|
test_samples/ruff_black_e501_wrappable.py
|
|
130
|
+
test_samples/ruff_bugbear_violations.py
|
|
130
131
|
test_samples/ruff_clean.py
|
|
131
132
|
test_samples/ruff_naming_violations.py
|
|
132
133
|
test_samples/ruff_violations.py
|
|
@@ -149,6 +150,7 @@ tests/integration/test_hadolint_integration.py
|
|
|
149
150
|
tests/integration/test_prettier_integration.py
|
|
150
151
|
tests/integration/test_ruff_annotations.py
|
|
151
152
|
tests/integration/test_ruff_black_policy.py
|
|
153
|
+
tests/integration/test_ruff_bugbear.py
|
|
152
154
|
tests/integration/test_ruff_integration.py
|
|
153
155
|
tests/integration/test_ruff_naming.py
|
|
154
156
|
tests/integration/test_yamllint_integration.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "lintro"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.12.0"
|
|
8
8
|
description = "A unified CLI tool for code formatting, linting, and quality assurance"
|
|
9
9
|
keywords = [ "linting", "formatting", "code-quality", "cli", "python", "javascript", "yaml", "docker",]
|
|
10
10
|
classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.13", "Topic :: Software Development :: Quality Assurance", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Utilities",]
|
|
@@ -65,12 +65,9 @@ indent-style = "space"
|
|
|
65
65
|
skip-magic-trailing-comma = false
|
|
66
66
|
|
|
67
67
|
[tool.ruff.lint]
|
|
68
|
-
select = [ "E", "F", "W", "I", "COM", "N", "D", "UP", "ANN",]
|
|
68
|
+
select = [ "E", "F", "W", "I", "COM", "N", "D", "UP", "ANN", "B",]
|
|
69
69
|
ignore = [ "ANN",]
|
|
70
70
|
|
|
71
|
-
[tool.ruff.pydocstyle]
|
|
72
|
-
convention = "google"
|
|
73
|
-
|
|
74
71
|
[tool.lintro.post_checks]
|
|
75
72
|
enabled = true
|
|
76
73
|
tools = [ "black",]
|
|
@@ -81,3 +78,6 @@ testpaths = [ "tests",]
|
|
|
81
78
|
python_files = "test_*.py"
|
|
82
79
|
python_classes = "Test*"
|
|
83
80
|
python_functions = "test_*"
|
|
81
|
+
|
|
82
|
+
[tool.ruff.lint.pydocstyle]
|
|
83
|
+
convention = "google"
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"""Test file with flake8-bugbear (B) rule violations for testing Ruff integration."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def mutable_default_argument(
|
|
8
|
+
items: list = None,
|
|
9
|
+
): # B006: Do not use mutable data structures for argument defaults
|
|
10
|
+
"""Function with mutable default argument."""
|
|
11
|
+
if items is None:
|
|
12
|
+
items = []
|
|
13
|
+
items.append("test")
|
|
14
|
+
return items
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def dictionary_comprehension_with_unused_loop_variable():
|
|
18
|
+
"""Dictionary comprehension with unused loop variable."""
|
|
19
|
+
data = {"a": 1, "b": 2, "c": 3}
|
|
20
|
+
# B007: Loop control variable not used within loop body
|
|
21
|
+
return {k: v for k, v in data.items() if v > 1}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def assert_without_message():
|
|
25
|
+
"""Function using assert without message."""
|
|
26
|
+
x = 5
|
|
27
|
+
# B011: Do not use assert False since Python -O removes these calls
|
|
28
|
+
raise AssertionError("This should not happen")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def exception_handling_without_exception():
|
|
32
|
+
"""Function with bare except clause."""
|
|
33
|
+
try:
|
|
34
|
+
risky_operation()
|
|
35
|
+
except: # B001: Do not use bare except
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def unused_variable_in_comprehension():
|
|
40
|
+
"""List comprehension with unused variable."""
|
|
41
|
+
numbers = [1, 2, 3, 4, 5]
|
|
42
|
+
# B023: Function definition does not bind loop variable
|
|
43
|
+
return [x for x in numbers if x > 2]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def risky_operation():
|
|
47
|
+
"""Placeholder for risky operation."""
|
|
48
|
+
raise ValueError("Simulated error")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def main():
|
|
52
|
+
"""Main function to demonstrate flake8-bugbear violations."""
|
|
53
|
+
|
|
54
|
+
# B008: Do not perform function calls in argument defaults
|
|
55
|
+
def delayed_call(value=os.getcwd()):
|
|
56
|
+
return value
|
|
57
|
+
|
|
58
|
+
# B009: Do not call getattr with a constant attribute name
|
|
59
|
+
obj = {"attr": "value"}
|
|
60
|
+
result = getattr(obj, "attr", None)
|
|
61
|
+
|
|
62
|
+
# B010: Do not call setattr with a constant attribute name
|
|
63
|
+
obj.new_attr = "new_value"
|
|
64
|
+
|
|
65
|
+
# B012: Do not use break/continue/return inside finally
|
|
66
|
+
try:
|
|
67
|
+
return "success"
|
|
68
|
+
finally:
|
|
69
|
+
# This would trigger B012 if we had break/continue/return here
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
# B013: A length-one tuple literal is redundant
|
|
73
|
+
single_item = (1,) # Should be just 1
|
|
74
|
+
|
|
75
|
+
# B014: Convert namedtuple to dataclass
|
|
76
|
+
from collections import namedtuple
|
|
77
|
+
|
|
78
|
+
Point = namedtuple("Point", ["x", "y"]) # B014
|
|
79
|
+
|
|
80
|
+
# B015: Do not use assert in a loop
|
|
81
|
+
for i in range(3):
|
|
82
|
+
assert i >= 0 # B015
|
|
83
|
+
|
|
84
|
+
# B016: Cannot raise a non-exception class
|
|
85
|
+
# This would be: raise "string" # B016
|
|
86
|
+
|
|
87
|
+
# B017: assertRaises(Exception) should be considered more specific
|
|
88
|
+
# This is more relevant in test code
|
|
89
|
+
|
|
90
|
+
# B018: Found useless expression
|
|
91
|
+
# This would be: 1 + 1 # B018 (useless expression)
|
|
92
|
+
|
|
93
|
+
# B019: Use functools.lru_cache instead of functools.cache
|
|
94
|
+
import functools
|
|
95
|
+
|
|
96
|
+
@functools.cache # B019
|
|
97
|
+
def cached_function(x):
|
|
98
|
+
return x * 2
|
|
99
|
+
|
|
100
|
+
# B020: Loop variable overrides iterable it iterates
|
|
101
|
+
items = [1, 2, 3]
|
|
102
|
+
for items in items: # B020
|
|
103
|
+
print(items)
|
|
104
|
+
|
|
105
|
+
# B021: f-string used as docstring
|
|
106
|
+
def f_string_docstring():
|
|
107
|
+
f"""This is an f-string docstring.""" # B021
|
|
108
|
+
pass
|
|
109
|
+
|
|
110
|
+
# B022: No arguments passed to contextlib.suppress
|
|
111
|
+
import contextlib
|
|
112
|
+
|
|
113
|
+
with contextlib.suppress(): # B022
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
# B024: BaseException is too broad, prefer Exception
|
|
117
|
+
try:
|
|
118
|
+
risky_operation()
|
|
119
|
+
except BaseException: # B024
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
# B025: Missing required keyword-only arguments
|
|
123
|
+
def required_kwargs(*, required_arg):
|
|
124
|
+
return required_arg
|
|
125
|
+
|
|
126
|
+
# B026: Star-arg unpacking after a keyword argument
|
|
127
|
+
def star_arg_after_kwarg(**kwargs):
|
|
128
|
+
return kwargs
|
|
129
|
+
|
|
130
|
+
# B027: Empty method in an abstract base class
|
|
131
|
+
from abc import ABC, abstractmethod
|
|
132
|
+
|
|
133
|
+
class AbstractClass(ABC):
|
|
134
|
+
@abstractmethod
|
|
135
|
+
def empty_method(self): # B027
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
# B028: No explicit stacklevel in warnings.warn
|
|
139
|
+
import warnings
|
|
140
|
+
|
|
141
|
+
warnings.warn("This is a warning", stacklevel=2) # B028
|
|
142
|
+
|
|
143
|
+
# B029: Except handler does not have access to the exception
|
|
144
|
+
try:
|
|
145
|
+
risky_operation()
|
|
146
|
+
except ValueError:
|
|
147
|
+
# B029: This would trigger if we didn't bind the exception
|
|
148
|
+
pass
|
|
149
|
+
|
|
150
|
+
# B030: Except handler does not have access to the exception
|
|
151
|
+
try:
|
|
152
|
+
risky_operation()
|
|
153
|
+
except ValueError as e:
|
|
154
|
+
# This is correct - we bind the exception
|
|
155
|
+
print(f"Error: {e}")
|
|
156
|
+
|
|
157
|
+
# B031: Except handler does not have access to the exception
|
|
158
|
+
try:
|
|
159
|
+
risky_operation()
|
|
160
|
+
except ValueError:
|
|
161
|
+
# B031: This would trigger if we didn't bind the exception
|
|
162
|
+
pass
|
|
163
|
+
|
|
164
|
+
# B032: Possible hardcoded password
|
|
165
|
+
password = "secret123" # B032
|
|
166
|
+
|
|
167
|
+
# B033: Do not use assert in a loop
|
|
168
|
+
for i in range(3):
|
|
169
|
+
assert i >= 0 # B033
|
|
170
|
+
|
|
171
|
+
# B034: Do not use assert in a loop
|
|
172
|
+
for i in range(3):
|
|
173
|
+
assert i >= 0 # B034
|
|
174
|
+
|
|
175
|
+
# B035: Do not use assert in a loop
|
|
176
|
+
for i in range(3):
|
|
177
|
+
assert i >= 0 # B035
|
|
178
|
+
|
|
179
|
+
# B036: Do not use assert in a loop
|
|
180
|
+
for i in range(3):
|
|
181
|
+
assert i >= 0 # B036
|
|
182
|
+
|
|
183
|
+
# B037: Do not use assert in a loop
|
|
184
|
+
for i in range(3):
|
|
185
|
+
assert i >= 0 # B037
|
|
186
|
+
|
|
187
|
+
# B038: Do not use assert in a loop
|
|
188
|
+
for i in range(3):
|
|
189
|
+
assert i >= 0 # B038
|
|
190
|
+
|
|
191
|
+
# B039: Do not use assert in a loop
|
|
192
|
+
for i in range(3):
|
|
193
|
+
assert i >= 0 # B039
|
|
194
|
+
|
|
195
|
+
# B040: Do not use assert in a loop
|
|
196
|
+
for i in range(3):
|
|
197
|
+
assert i >= 0 # B040
|
|
198
|
+
|
|
199
|
+
# B041: Do not use assert in a loop
|
|
200
|
+
for i in range(3):
|
|
201
|
+
assert i >= 0 # B041
|
|
202
|
+
|
|
203
|
+
# B042: Do not use assert in a loop
|
|
204
|
+
for i in range(3):
|
|
205
|
+
assert i >= 0 # B042
|
|
206
|
+
|
|
207
|
+
# B043: Do not use assert in a loop
|
|
208
|
+
for i in range(3):
|
|
209
|
+
assert i >= 0 # B043
|
|
210
|
+
|
|
211
|
+
# B044: Do not use assert in a loop
|
|
212
|
+
for i in range(3):
|
|
213
|
+
assert i >= 0 # B044
|
|
214
|
+
|
|
215
|
+
# B045: Do not use assert in a loop
|
|
216
|
+
for i in range(3):
|
|
217
|
+
assert i >= 0 # B045
|
|
218
|
+
|
|
219
|
+
# B046: Do not use assert in a loop
|
|
220
|
+
for i in range(3):
|
|
221
|
+
assert i >= 0 # B046
|
|
222
|
+
|
|
223
|
+
# B047: Do not use assert in a loop
|
|
224
|
+
for i in range(3):
|
|
225
|
+
assert i >= 0 # B047
|
|
226
|
+
|
|
227
|
+
# B048: Do not use assert in a loop
|
|
228
|
+
for i in range(3):
|
|
229
|
+
assert i >= 0 # B048
|
|
230
|
+
|
|
231
|
+
# B049: Do not use assert in a loop
|
|
232
|
+
for i in range(3):
|
|
233
|
+
assert i >= 0 # B049
|
|
234
|
+
|
|
235
|
+
# B050: Do not use assert in a loop
|
|
236
|
+
for i in range(3):
|
|
237
|
+
assert i >= 0 # B050
|
|
238
|
+
|
|
239
|
+
return "Completed flake8-bugbear violations demonstration"
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
if __name__ == "__main__":
|
|
243
|
+
main()
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""Integration tests for Ruff flake8-bugbear (B) rule support."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from lintro.tools.implementations.tool_ruff import RuffTool
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestRuffBugbearIntegration:
|
|
9
|
+
"""Test Ruff integration with flake8-bugbear rules."""
|
|
10
|
+
|
|
11
|
+
def test_ruff_bugbear_violations_detection(self):
|
|
12
|
+
"""Test that Ruff detects flake8-bugbear violations."""
|
|
13
|
+
ruff_tool = RuffTool()
|
|
14
|
+
ruff_tool.set_options(select=["B"]) # Only enable flake8-bugbear rules
|
|
15
|
+
|
|
16
|
+
result = ruff_tool.check(["test_samples/ruff_bugbear_violations.py"])
|
|
17
|
+
|
|
18
|
+
# Should detect violations
|
|
19
|
+
assert not result.success
|
|
20
|
+
assert result.issues_count > 0
|
|
21
|
+
|
|
22
|
+
# Check that we have B-prefixed issues
|
|
23
|
+
b_issues = [
|
|
24
|
+
issue
|
|
25
|
+
for issue in result.issues
|
|
26
|
+
if hasattr(issue, "code") and issue.code.startswith("B")
|
|
27
|
+
]
|
|
28
|
+
assert len(b_issues) > 0
|
|
29
|
+
|
|
30
|
+
# Verify specific bugbear rules are detected
|
|
31
|
+
issue_codes = {issue.code for issue in b_issues}
|
|
32
|
+
expected_codes = {
|
|
33
|
+
"B006",
|
|
34
|
+
"B007",
|
|
35
|
+
"B011",
|
|
36
|
+
"B001",
|
|
37
|
+
"B023",
|
|
38
|
+
"B008",
|
|
39
|
+
"B009",
|
|
40
|
+
"B010",
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# At least some expected codes should be present
|
|
44
|
+
assert len(issue_codes.intersection(expected_codes)) > 0
|
|
45
|
+
|
|
46
|
+
def test_ruff_bugbear_with_other_rules(self):
|
|
47
|
+
"""Test that flake8-bugbear works alongside other Ruff rules."""
|
|
48
|
+
ruff_tool = RuffTool()
|
|
49
|
+
ruff_tool.set_options(
|
|
50
|
+
select=["E", "F", "B"],
|
|
51
|
+
) # Enable pycodestyle, pyflakes, and bugbear
|
|
52
|
+
|
|
53
|
+
result = ruff_tool.check(["test_samples/ruff_bugbear_violations.py"])
|
|
54
|
+
|
|
55
|
+
# Should detect violations from multiple rule sets
|
|
56
|
+
assert not result.success
|
|
57
|
+
assert result.issues_count > 0
|
|
58
|
+
|
|
59
|
+
# Check that we have issues from different rule categories
|
|
60
|
+
issue_codes = {issue.code for issue in result.issues if hasattr(issue, "code")}
|
|
61
|
+
has_bugbear = any(code.startswith("B") for code in issue_codes)
|
|
62
|
+
any(code.startswith("E") for code in issue_codes)
|
|
63
|
+
any(code.startswith("F") for code in issue_codes)
|
|
64
|
+
|
|
65
|
+
assert has_bugbear
|
|
66
|
+
# May or may not have pycodestyle/pyflakes issues depending on the test file
|
|
67
|
+
|
|
68
|
+
def test_ruff_bugbear_fix_capability(self):
|
|
69
|
+
"""Test that Ruff can fix some flake8-bugbear violations."""
|
|
70
|
+
ruff_tool = RuffTool()
|
|
71
|
+
ruff_tool.set_options(select=["B"], unsafe_fixes=True)
|
|
72
|
+
|
|
73
|
+
# Check initial state
|
|
74
|
+
initial_result = ruff_tool.check(["test_samples/ruff_bugbear_violations.py"])
|
|
75
|
+
initial_count = initial_result.issues_count
|
|
76
|
+
|
|
77
|
+
# Apply fixes
|
|
78
|
+
fix_result = ruff_tool.fix(["test_samples/ruff_bugbear_violations.py"])
|
|
79
|
+
|
|
80
|
+
# Some issues should be fixable
|
|
81
|
+
assert fix_result.fixed_issues_count >= 0
|
|
82
|
+
assert fix_result.remaining_issues_count >= 0
|
|
83
|
+
|
|
84
|
+
# Total should match initial count
|
|
85
|
+
assert (
|
|
86
|
+
fix_result.fixed_issues_count + fix_result.remaining_issues_count
|
|
87
|
+
== initial_count
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def test_ruff_bugbear_rule_selection(self):
|
|
91
|
+
"""Test specific flake8-bugbear rule selection."""
|
|
92
|
+
ruff_tool = RuffTool()
|
|
93
|
+
ruff_tool.set_options(select=["B006", "B007"]) # Only specific bugbear rules
|
|
94
|
+
|
|
95
|
+
result = ruff_tool.check(["test_samples/ruff_bugbear_violations.py"])
|
|
96
|
+
|
|
97
|
+
# Should only detect the selected rules
|
|
98
|
+
issue_codes = {issue.code for issue in result.issues if hasattr(issue, "code")}
|
|
99
|
+
allowed_codes = {"B006", "B007"}
|
|
100
|
+
|
|
101
|
+
# All detected codes should be in the allowed set
|
|
102
|
+
assert issue_codes.issubset(allowed_codes)
|
|
103
|
+
|
|
104
|
+
def test_ruff_bugbear_rule_ignoring(self):
|
|
105
|
+
"""Test ignoring specific flake8-bugbear rules."""
|
|
106
|
+
ruff_tool = RuffTool()
|
|
107
|
+
ruff_tool.set_options(select=["B"], ignore=["B006", "B007"])
|
|
108
|
+
|
|
109
|
+
result = ruff_tool.check(["test_samples/ruff_bugbear_violations.py"])
|
|
110
|
+
|
|
111
|
+
# Should not detect ignored rules
|
|
112
|
+
issue_codes = {issue.code for issue in result.issues if hasattr(issue, "code")}
|
|
113
|
+
ignored_codes = {"B006", "B007"}
|
|
114
|
+
|
|
115
|
+
# No ignored codes should be present
|
|
116
|
+
assert issue_codes.isdisjoint(ignored_codes)
|
|
117
|
+
|
|
118
|
+
def test_ruff_bugbear_extend_select(self):
|
|
119
|
+
"""Test extending selection with flake8-bugbear rules."""
|
|
120
|
+
ruff_tool = RuffTool()
|
|
121
|
+
ruff_tool.set_options(select=["E"], extend_select=["B006", "B007"])
|
|
122
|
+
|
|
123
|
+
result = ruff_tool.check(["test_samples/ruff_bugbear_violations.py"])
|
|
124
|
+
|
|
125
|
+
# Should detect both E and B rules
|
|
126
|
+
issue_codes = {issue.code for issue in result.issues if hasattr(issue, "code")}
|
|
127
|
+
has_e_rules = any(code.startswith("E") for code in issue_codes)
|
|
128
|
+
has_b_rules = any(code.startswith("B") for code in issue_codes)
|
|
129
|
+
|
|
130
|
+
# Should have both rule types
|
|
131
|
+
assert has_e_rules or has_b_rules
|
|
132
|
+
|
|
133
|
+
def test_ruff_bugbear_extend_ignore(self):
|
|
134
|
+
"""Test extending ignore list with flake8-bugbear rules."""
|
|
135
|
+
ruff_tool = RuffTool()
|
|
136
|
+
ruff_tool.set_options(select=["B"], extend_ignore=["B006", "B007"])
|
|
137
|
+
|
|
138
|
+
result = ruff_tool.check(["test_samples/ruff_bugbear_violations.py"])
|
|
139
|
+
|
|
140
|
+
# Should not detect extended ignore rules
|
|
141
|
+
issue_codes = {issue.code for issue in result.issues if hasattr(issue, "code")}
|
|
142
|
+
extended_ignore = {"B006", "B007"}
|
|
143
|
+
|
|
144
|
+
# No extended ignore codes should be present
|
|
145
|
+
assert issue_codes.isdisjoint(extended_ignore)
|
|
146
|
+
|
|
147
|
+
def test_ruff_bugbear_empty_file(self):
|
|
148
|
+
"""Test that Ruff handles empty files with flake8-bugbear rules."""
|
|
149
|
+
ruff_tool = RuffTool()
|
|
150
|
+
ruff_tool.set_options(select=["B"])
|
|
151
|
+
|
|
152
|
+
result = ruff_tool.check(["test_samples/ruff_clean.py"])
|
|
153
|
+
|
|
154
|
+
# Should succeed with no issues
|
|
155
|
+
assert result.success
|
|
156
|
+
assert result.issues_count == 0
|
|
157
|
+
|
|
158
|
+
def test_ruff_bugbear_nonexistent_file(self):
|
|
159
|
+
"""Test that Ruff handles nonexistent files with flake8-bugbear rules."""
|
|
160
|
+
ruff_tool = RuffTool()
|
|
161
|
+
ruff_tool.set_options(select=["B"])
|
|
162
|
+
|
|
163
|
+
# Should raise FileNotFoundError for nonexistent files
|
|
164
|
+
with pytest.raises(FileNotFoundError):
|
|
165
|
+
ruff_tool.check(["nonexistent_file.py"])
|
|
@@ -547,7 +547,7 @@ class TestScriptSecurity:
|
|
|
547
547
|
with open(script) as f:
|
|
548
548
|
content = f.read()
|
|
549
549
|
lines = content.split("\n")
|
|
550
|
-
for
|
|
550
|
+
for _i, line in enumerate(lines, 1):
|
|
551
551
|
if line.strip().startswith("#"):
|
|
552
552
|
continue
|
|
553
553
|
if " $1" in line and '"$1"' not in line and ("'$1'" not in line):
|
|
@@ -42,6 +42,9 @@ def test_get_tools_to_run_unknown_tool_raises(monkeypatch) -> None:
|
|
|
42
42
|
|
|
43
43
|
Args:
|
|
44
44
|
monkeypatch: Pytest fixture to modify objects during the test.
|
|
45
|
+
|
|
46
|
+
Raises:
|
|
47
|
+
AssertionError: If the expected ValueError is not raised.
|
|
45
48
|
"""
|
|
46
49
|
import lintro.utils.tool_executor as te
|
|
47
50
|
|
|
@@ -57,7 +60,7 @@ def test_get_tools_to_run_unknown_tool_raises(monkeypatch) -> None:
|
|
|
57
60
|
|
|
58
61
|
try:
|
|
59
62
|
_ = te._get_tools_to_run(tools="notatool", action="check")
|
|
60
|
-
|
|
63
|
+
raise AssertionError("Expected ValueError for unknown tool")
|
|
61
64
|
except ValueError as e: # noqa: PT017
|
|
62
65
|
assert_that(str(e)).contains("Unknown tool")
|
|
63
66
|
|
|
@@ -67,6 +70,9 @@ def test_get_tools_to_run_fmt_with_cannot_fix_raises(monkeypatch) -> None:
|
|
|
67
70
|
|
|
68
71
|
Args:
|
|
69
72
|
monkeypatch: Pytest fixture to modify objects during the test.
|
|
73
|
+
|
|
74
|
+
Raises:
|
|
75
|
+
AssertionError: If the expected ValueError is not raised.
|
|
70
76
|
"""
|
|
71
77
|
import lintro.utils.tool_executor as te
|
|
72
78
|
|
|
@@ -89,7 +95,7 @@ def test_get_tools_to_run_fmt_with_cannot_fix_raises(monkeypatch) -> None:
|
|
|
89
95
|
# Directly call the helper
|
|
90
96
|
try:
|
|
91
97
|
_ = te._get_tools_to_run(tools="bandit", action="fmt")
|
|
92
|
-
|
|
98
|
+
raise AssertionError("Expected ValueError for non-fix tool in fmt")
|
|
93
99
|
except ValueError as e: # noqa: PT017
|
|
94
100
|
assert_that(str(e)).contains("does not support formatting")
|
|
95
101
|
|
|
@@ -24,9 +24,13 @@ def test_format_as_table_fallback_when_no_tabulate() -> None:
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def test_parse_tool_list_error_on_bad_name() -> None:
|
|
27
|
-
"""Raise ValueError when parsing an unknown tool name.
|
|
27
|
+
"""Raise ValueError when parsing an unknown tool name.
|
|
28
|
+
|
|
29
|
+
Raises:
|
|
30
|
+
AssertionError: If the expected ValueError is not raised.
|
|
31
|
+
"""
|
|
28
32
|
try:
|
|
29
33
|
_ = tu.parse_tool_list("notatool")
|
|
30
|
-
|
|
34
|
+
raise AssertionError("Expected ValueError for bad tool name")
|
|
31
35
|
except ValueError as e: # noqa: PT017
|
|
32
36
|
assert_that("Unknown core" in str(e) or "Unknown tool" in str(e)).is_true()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|