lintro 0.13.2__tar.gz → 0.14.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.

Files changed (216) hide show
  1. {lintro-0.13.2/lintro.egg-info → lintro-0.14.0}/PKG-INFO +1 -1
  2. {lintro-0.13.2 → lintro-0.14.0}/assets/images/coverage-badge.svg +2 -2
  3. {lintro-0.13.2 → lintro-0.14.0}/lintro/__init__.py +1 -1
  4. lintro-0.14.0/lintro/parsers/__init__.py +72 -0
  5. lintro-0.14.0/lintro/parsers/bandit/__init__.py +6 -0
  6. lintro-0.14.0/lintro/parsers/bandit/bandit_issue.py +49 -0
  7. lintro-0.14.0/lintro/parsers/bandit/bandit_parser.py +99 -0
  8. {lintro-0.13.2 → lintro-0.14.0/lintro.egg-info}/PKG-INFO +1 -1
  9. {lintro-0.13.2 → lintro-0.14.0}/lintro.egg-info/SOURCES.txt +3 -0
  10. {lintro-0.13.2 → lintro-0.14.0}/pyproject.toml +2 -2
  11. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_package_imports.py +72 -0
  12. lintro-0.13.2/lintro/parsers/__init__.py +0 -21
  13. {lintro-0.13.2 → lintro-0.14.0}/LICENSE +0 -0
  14. {lintro-0.13.2 → lintro-0.14.0}/MANIFEST.in +0 -0
  15. {lintro-0.13.2 → lintro-0.14.0}/README.md +0 -0
  16. {lintro-0.13.2 → lintro-0.14.0}/assets/images/lintro.png +0 -0
  17. {lintro-0.13.2 → lintro-0.14.0}/docs/README.md +0 -0
  18. {lintro-0.13.2 → lintro-0.14.0}/docs/configuration.md +0 -0
  19. {lintro-0.13.2 → lintro-0.14.0}/docs/contributing.md +0 -0
  20. {lintro-0.13.2 → lintro-0.14.0}/docs/coverage-setup.md +0 -0
  21. {lintro-0.13.2 → lintro-0.14.0}/docs/docker.md +0 -0
  22. {lintro-0.13.2 → lintro-0.14.0}/docs/getting-started.md +0 -0
  23. {lintro-0.13.2 → lintro-0.14.0}/docs/github-integration.md +0 -0
  24. {lintro-0.13.2 → lintro-0.14.0}/docs/lintro-self-use.md +0 -0
  25. {lintro-0.13.2 → lintro-0.14.0}/docs/security/assurance.md +0 -0
  26. {lintro-0.13.2 → lintro-0.14.0}/docs/security/requirements.md +0 -0
  27. {lintro-0.13.2 → lintro-0.14.0}/docs/style-guide.md +0 -0
  28. {lintro-0.13.2 → lintro-0.14.0}/docs/tool-analysis/README.md +0 -0
  29. {lintro-0.13.2 → lintro-0.14.0}/docs/tool-analysis/actionlint-analysis.md +0 -0
  30. {lintro-0.13.2 → lintro-0.14.0}/docs/tool-analysis/bandit-analysis.md +0 -0
  31. {lintro-0.13.2 → lintro-0.14.0}/docs/tool-analysis/black-analysis.md +0 -0
  32. {lintro-0.13.2 → lintro-0.14.0}/docs/tool-analysis/darglint-analysis.md +0 -0
  33. {lintro-0.13.2 → lintro-0.14.0}/docs/tool-analysis/hadolint-analysis.md +0 -0
  34. {lintro-0.13.2 → lintro-0.14.0}/docs/tool-analysis/prettier-analysis.md +0 -0
  35. {lintro-0.13.2 → lintro-0.14.0}/docs/tool-analysis/ruff-analysis.md +0 -0
  36. {lintro-0.13.2 → lintro-0.14.0}/docs/tool-analysis/yamllint-analysis.md +0 -0
  37. {lintro-0.13.2 → lintro-0.14.0}/lintro/__main__.py +0 -0
  38. {lintro-0.13.2 → lintro-0.14.0}/lintro/ascii-art/fail.txt +0 -0
  39. {lintro-0.13.2 → lintro-0.14.0}/lintro/ascii-art/success.txt +0 -0
  40. {lintro-0.13.2 → lintro-0.14.0}/lintro/cli.py +0 -0
  41. {lintro-0.13.2 → lintro-0.14.0}/lintro/cli_utils/__init__.py +0 -0
  42. {lintro-0.13.2 → lintro-0.14.0}/lintro/cli_utils/commands/__init__.py +0 -0
  43. {lintro-0.13.2 → lintro-0.14.0}/lintro/cli_utils/commands/check.py +0 -0
  44. {lintro-0.13.2 → lintro-0.14.0}/lintro/cli_utils/commands/format.py +0 -0
  45. {lintro-0.13.2 → lintro-0.14.0}/lintro/cli_utils/commands/list_tools.py +0 -0
  46. {lintro-0.13.2 → lintro-0.14.0}/lintro/enums/__init__.py +0 -0
  47. {lintro-0.13.2 → lintro-0.14.0}/lintro/enums/action.py +0 -0
  48. {lintro-0.13.2 → lintro-0.14.0}/lintro/enums/darglint_strictness.py +0 -0
  49. {lintro-0.13.2 → lintro-0.14.0}/lintro/enums/group_by.py +0 -0
  50. {lintro-0.13.2 → lintro-0.14.0}/lintro/enums/hadolint_enums.py +0 -0
  51. {lintro-0.13.2 → lintro-0.14.0}/lintro/enums/output_format.py +0 -0
  52. {lintro-0.13.2 → lintro-0.14.0}/lintro/enums/tool_name.py +0 -0
  53. {lintro-0.13.2 → lintro-0.14.0}/lintro/enums/tool_type.py +0 -0
  54. {lintro-0.13.2 → lintro-0.14.0}/lintro/enums/yamllint_format.py +0 -0
  55. {lintro-0.13.2 → lintro-0.14.0}/lintro/exceptions/__init__.py +0 -0
  56. {lintro-0.13.2 → lintro-0.14.0}/lintro/exceptions/errors.py +0 -0
  57. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/__init__.py +0 -0
  58. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/core/__init__.py +0 -0
  59. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/core/output_style.py +0 -0
  60. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/core/table_descriptor.py +0 -0
  61. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/styles/__init__.py +0 -0
  62. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/styles/csv.py +0 -0
  63. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/styles/grid.py +0 -0
  64. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/styles/html.py +0 -0
  65. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/styles/json.py +0 -0
  66. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/styles/markdown.py +0 -0
  67. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/styles/plain.py +0 -0
  68. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/tools/__init__.py +0 -0
  69. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/tools/actionlint_formatter.py +0 -0
  70. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/tools/bandit_formatter.py +0 -0
  71. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/tools/black_formatter.py +0 -0
  72. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/tools/darglint_formatter.py +0 -0
  73. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/tools/hadolint_formatter.py +0 -0
  74. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/tools/prettier_formatter.py +0 -0
  75. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/tools/ruff_formatter.py +0 -0
  76. {lintro-0.13.2 → lintro-0.14.0}/lintro/formatters/tools/yamllint_formatter.py +0 -0
  77. {lintro-0.13.2 → lintro-0.14.0}/lintro/models/__init__.py +0 -0
  78. {lintro-0.13.2 → lintro-0.14.0}/lintro/models/core/__init__.py +0 -0
  79. {lintro-0.13.2 → lintro-0.14.0}/lintro/models/core/tool.py +0 -0
  80. {lintro-0.13.2 → lintro-0.14.0}/lintro/models/core/tool_config.py +0 -0
  81. {lintro-0.13.2 → lintro-0.14.0}/lintro/models/core/tool_result.py +0 -0
  82. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/actionlint/__init__.py +0 -0
  83. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/actionlint/actionlint_issue.py +0 -0
  84. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/actionlint/actionlint_parser.py +0 -0
  85. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/black/black_issue.py +0 -0
  86. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/black/black_parser.py +0 -0
  87. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/darglint/__init__.py +0 -0
  88. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/darglint/darglint_issue.py +0 -0
  89. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/darglint/darglint_parser.py +0 -0
  90. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/hadolint/__init__.py +0 -0
  91. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/hadolint/hadolint_issue.py +0 -0
  92. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/hadolint/hadolint_parser.py +0 -0
  93. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/prettier/__init__.py +0 -0
  94. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/prettier/prettier_issue.py +0 -0
  95. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/prettier/prettier_parser.py +0 -0
  96. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/ruff/__init__.py +0 -0
  97. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/ruff/ruff_issue.py +0 -0
  98. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/ruff/ruff_parser.py +0 -0
  99. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/yamllint/__init__.py +0 -0
  100. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/yamllint/yamllint_issue.py +0 -0
  101. {lintro-0.13.2 → lintro-0.14.0}/lintro/parsers/yamllint/yamllint_parser.py +0 -0
  102. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/__init__.py +0 -0
  103. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/core/__init__.py +0 -0
  104. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/core/tool_base.py +0 -0
  105. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/core/tool_manager.py +0 -0
  106. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/implementations/__init__.py +0 -0
  107. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/implementations/tool_actionlint.py +0 -0
  108. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/implementations/tool_bandit.py +0 -0
  109. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/implementations/tool_black.py +0 -0
  110. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/implementations/tool_darglint.py +0 -0
  111. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/implementations/tool_hadolint.py +0 -0
  112. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/implementations/tool_prettier.py +0 -0
  113. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/implementations/tool_ruff.py +0 -0
  114. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/implementations/tool_yamllint.py +0 -0
  115. {lintro-0.13.2 → lintro-0.14.0}/lintro/tools/tool_enum.py +0 -0
  116. {lintro-0.13.2 → lintro-0.14.0}/lintro/utils/__init__.py +0 -0
  117. {lintro-0.13.2 → lintro-0.14.0}/lintro/utils/ascii_normalize_cli.py +0 -0
  118. {lintro-0.13.2 → lintro-0.14.0}/lintro/utils/config.py +0 -0
  119. {lintro-0.13.2 → lintro-0.14.0}/lintro/utils/console_logger.py +0 -0
  120. {lintro-0.13.2 → lintro-0.14.0}/lintro/utils/formatting.py +0 -0
  121. {lintro-0.13.2 → lintro-0.14.0}/lintro/utils/output_manager.py +0 -0
  122. {lintro-0.13.2 → lintro-0.14.0}/lintro/utils/path_utils.py +0 -0
  123. {lintro-0.13.2 → lintro-0.14.0}/lintro/utils/tool_executor.py +0 -0
  124. {lintro-0.13.2 → lintro-0.14.0}/lintro/utils/tool_utils.py +0 -0
  125. {lintro-0.13.2 → lintro-0.14.0}/lintro.egg-info/dependency_links.txt +0 -0
  126. {lintro-0.13.2 → lintro-0.14.0}/lintro.egg-info/entry_points.txt +0 -0
  127. {lintro-0.13.2 → lintro-0.14.0}/lintro.egg-info/requires.txt +0 -0
  128. {lintro-0.13.2 → lintro-0.14.0}/lintro.egg-info/top_level.txt +0 -0
  129. {lintro-0.13.2 → lintro-0.14.0}/setup.cfg +0 -0
  130. {lintro-0.13.2 → lintro-0.14.0}/test_samples/Dockerfile.violations +0 -0
  131. {lintro-0.13.2 → lintro-0.14.0}/test_samples/actionlint_violations.yml +0 -0
  132. {lintro-0.13.2 → lintro-0.14.0}/test_samples/bandit_violations.py +0 -0
  133. {lintro-0.13.2 → lintro-0.14.0}/test_samples/darglint_violations.py +0 -0
  134. {lintro-0.13.2 → lintro-0.14.0}/test_samples/prettier_violations.js +0 -0
  135. {lintro-0.13.2 → lintro-0.14.0}/test_samples/ruff_annotations_violations.py +0 -0
  136. {lintro-0.13.2 → lintro-0.14.0}/test_samples/ruff_black_e501_wrappable.py +0 -0
  137. {lintro-0.13.2 → lintro-0.14.0}/test_samples/ruff_bugbear_violations.py +0 -0
  138. {lintro-0.13.2 → lintro-0.14.0}/test_samples/ruff_c4_comprehensions_violations.py +0 -0
  139. {lintro-0.13.2 → lintro-0.14.0}/test_samples/ruff_clean.py +0 -0
  140. {lintro-0.13.2 → lintro-0.14.0}/test_samples/ruff_naming_violations.py +0 -0
  141. {lintro-0.13.2 → lintro-0.14.0}/test_samples/ruff_sim_simplify_violations.py +0 -0
  142. {lintro-0.13.2 → lintro-0.14.0}/test_samples/ruff_violations.py +0 -0
  143. {lintro-0.13.2 → lintro-0.14.0}/test_samples/yaml_violations.yml +0 -0
  144. {lintro-0.13.2 → lintro-0.14.0}/tests/__init__.py +0 -0
  145. {lintro-0.13.2 → lintro-0.14.0}/tests/cli/__init__.py +0 -0
  146. {lintro-0.13.2 → lintro-0.14.0}/tests/cli/conftest.py +0 -0
  147. {lintro-0.13.2 → lintro-0.14.0}/tests/cli/test_cli.py +0 -0
  148. {lintro-0.13.2 → lintro-0.14.0}/tests/conftest.py +0 -0
  149. {lintro-0.13.2 → lintro-0.14.0}/tests/formatters/__init__.py +0 -0
  150. {lintro-0.13.2 → lintro-0.14.0}/tests/formatters/conftest.py +0 -0
  151. {lintro-0.13.2 → lintro-0.14.0}/tests/formatters/test_formatters.py +0 -0
  152. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/__init__.py +0 -0
  153. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/conftest.py +0 -0
  154. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_actionlint_integration.py +0 -0
  155. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_bandit_integration.py +0 -0
  156. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_built_package.py +0 -0
  157. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_darglint_integration.py +0 -0
  158. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_hadolint_integration.py +0 -0
  159. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_prettier_integration.py +0 -0
  160. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_ruff_additional_coverage.py +0 -0
  161. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_ruff_annotations.py +0 -0
  162. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_ruff_black_policy.py +0 -0
  163. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_ruff_bugbear.py +0 -0
  164. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_ruff_integration.py +0 -0
  165. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_ruff_naming.py +0 -0
  166. {lintro-0.13.2 → lintro-0.14.0}/tests/integration/test_yamllint_integration.py +0 -0
  167. {lintro-0.13.2 → lintro-0.14.0}/tests/scripts/__init__.py +0 -0
  168. {lintro-0.13.2 → lintro-0.14.0}/tests/scripts/test_ci_post_pr_comment.py +0 -0
  169. {lintro-0.13.2 → lintro-0.14.0}/tests/scripts/test_delete_previous_lintro_comments.py +0 -0
  170. {lintro-0.13.2 → lintro-0.14.0}/tests/scripts/test_extract_version.py +0 -0
  171. {lintro-0.13.2 → lintro-0.14.0}/tests/scripts/test_ghcr_prune_untagged.py +0 -0
  172. {lintro-0.13.2 → lintro-0.14.0}/tests/scripts/test_github_comment_utilities.py +0 -0
  173. {lintro-0.13.2 → lintro-0.14.0}/tests/scripts/test_script_environment.py +0 -0
  174. {lintro-0.13.2 → lintro-0.14.0}/tests/scripts/test_semantic_release_compute_next.py +0 -0
  175. {lintro-0.13.2 → lintro-0.14.0}/tests/scripts/test_shell_scripts.py +0 -0
  176. {lintro-0.13.2 → lintro-0.14.0}/tests/test_documentation.py +0 -0
  177. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/__init__.py +0 -0
  178. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_ascii_normalize.py +0 -0
  179. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_bandit_command_building.py +0 -0
  180. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_bandit_config_hydration.py +0 -0
  181. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_bandit_formatter_mapping.py +0 -0
  182. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_bandit_parsing.py +0 -0
  183. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_black_formatter.py +0 -0
  184. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_black_parser.py +0 -0
  185. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_black_tool.py +0 -0
  186. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_black_tool_more.py +0 -0
  187. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_cli_commands.py +0 -0
  188. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_cli_commands_more.py +0 -0
  189. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_cli_programmatic.py +0 -0
  190. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_compatibility_ruff_black.py +0 -0
  191. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_config_loader.py +0 -0
  192. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_config_loader_more.py +0 -0
  193. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_console_logger.py +0 -0
  194. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_console_logger_more.py +0 -0
  195. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_enums_and_normalizers.py +0 -0
  196. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_exceptions.py +0 -0
  197. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_formatters_tables.py +0 -0
  198. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_output_manager_reports.py +0 -0
  199. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_parsers_actionlint.py +0 -0
  200. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_ruff_parser_additional.py +0 -0
  201. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_ruff_parser_more.py +0 -0
  202. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_subprocess_validator.py +0 -0
  203. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_tool_base_subprocess.py +0 -0
  204. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_tool_executor.py +0 -0
  205. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_tool_executor_fmt_exclusion.py +0 -0
  206. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_tool_executor_more.py +0 -0
  207. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_tool_executor_post_checks.py +0 -0
  208. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_tool_manager.py +0 -0
  209. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_tool_utils.py +0 -0
  210. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_tool_utils_fallbacks.py +0 -0
  211. {lintro-0.13.2 → lintro-0.14.0}/tests/unit/test_tool_utils_more.py +0 -0
  212. {lintro-0.13.2 → lintro-0.14.0}/tests/utils/__init__.py +0 -0
  213. {lintro-0.13.2 → lintro-0.14.0}/tests/utils/conftest.py +0 -0
  214. {lintro-0.13.2 → lintro-0.14.0}/tests/utils/test_formatting.py +0 -0
  215. {lintro-0.13.2 → lintro-0.14.0}/tests/utils/test_output_manager.py +0 -0
  216. {lintro-0.13.2 → lintro-0.14.0}/tests/utils/test_path_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lintro
3
- Version: 0.13.2
3
+ Version: 0.14.0
4
4
  Summary: A unified CLI tool for code formatting, linting, and quality assurance
5
5
  Author-email: TurboCoder13 <turbocoder13@gmail.com>
6
6
  License: MIT License
@@ -15,7 +15,7 @@
15
15
  <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
16
16
  <text x="325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">coverage</text>
17
17
  <text x="325" y="140" transform="scale(.1)" textLength="530">coverage</text>
18
- <text x="800" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="260">84.8%</text>
19
- <text x="800" y="140" transform="scale(.1)" textLength="260">84.8%</text>
18
+ <text x="800" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="260">84.7%</text>
19
+ <text x="800" y="140" transform="scale(.1)" textLength="260">84.7%</text>
20
20
  </g>
21
21
  </svg>
@@ -1,3 +1,3 @@
1
1
  """Lintro - A unified CLI core for code formatting, linting, and quality assurance."""
2
2
 
3
- __version__ = "0.13.2"
3
+ __version__ = "0.14.0"
@@ -0,0 +1,72 @@
1
+ """Parser modules for Lintro tools."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from importlib import import_module
6
+ from typing import TYPE_CHECKING
7
+
8
+ if TYPE_CHECKING:
9
+ # Type checking imports
10
+ from lintro.parsers import (
11
+ actionlint,
12
+ bandit,
13
+ darglint,
14
+ hadolint,
15
+ prettier,
16
+ ruff,
17
+ yamllint,
18
+ )
19
+
20
+ __all__ = [
21
+ "actionlint",
22
+ "bandit",
23
+ "darglint",
24
+ "hadolint",
25
+ "prettier",
26
+ "ruff",
27
+ "yamllint",
28
+ ]
29
+
30
+ # Lazy-load parser submodules to avoid circular imports
31
+ _SUBMODULES = {
32
+ "actionlint",
33
+ "bandit",
34
+ "darglint",
35
+ "hadolint",
36
+ "prettier",
37
+ "ruff",
38
+ "yamllint",
39
+ }
40
+
41
+
42
+ def __getattr__(name: str) -> object:
43
+ """Lazy-load parser submodules to avoid circular import issues.
44
+
45
+ This function is called when an attribute is accessed that doesn't exist
46
+ in the module. It allows accessing parser submodules without eagerly
47
+ importing them all at package initialization time.
48
+
49
+ Args:
50
+ name: The name of the attribute being accessed.
51
+
52
+ Returns:
53
+ The imported submodule.
54
+
55
+ Raises:
56
+ AttributeError: If the requested name is not a known submodule.
57
+ """
58
+ if name in _SUBMODULES:
59
+ module = import_module(f".{name}", __package__)
60
+ # Cache the module in this module's namespace for future access
61
+ globals()[name] = module
62
+ return module
63
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
64
+
65
+
66
+ def __dir__() -> list[str]:
67
+ """Return list of available attributes for this module.
68
+
69
+ Returns:
70
+ List of submodule names and other module attributes.
71
+ """
72
+ return list(__all__)
@@ -0,0 +1,6 @@
1
+ """Bandit parser module."""
2
+
3
+ from lintro.parsers.bandit.bandit_issue import BanditIssue
4
+ from lintro.parsers.bandit.bandit_parser import parse_bandit_output
5
+
6
+ __all__ = ["BanditIssue", "parse_bandit_output"]
@@ -0,0 +1,49 @@
1
+ """Bandit issue model for security vulnerabilities."""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any
5
+
6
+
7
+ @dataclass
8
+ class BanditIssue:
9
+ """Represents a security issue found by Bandit.
10
+
11
+ Attributes:
12
+ file: str: Path to the file containing the issue.
13
+ line: int: Line number where the issue was found.
14
+ col_offset: int: Column offset of the issue.
15
+ issue_severity: str: Severity level (LOW, MEDIUM, HIGH).
16
+ issue_confidence: str: Confidence level (LOW, MEDIUM, HIGH).
17
+ test_id: str: Bandit test ID (e.g., B602, B301).
18
+ test_name: str: Name of the test that found the issue.
19
+ issue_text: str: Description of the security issue.
20
+ more_info: str: URL with more information about the issue.
21
+ cwe: dict[str, Any] | None: CWE (Common Weakness Enumeration) information.
22
+ code: str: Code snippet containing the issue.
23
+ line_range: list[int]: Range of lines containing the issue.
24
+ """
25
+
26
+ file: str
27
+ line: int
28
+ col_offset: int
29
+ issue_severity: str
30
+ issue_confidence: str
31
+ test_id: str
32
+ test_name: str
33
+ issue_text: str
34
+ more_info: str
35
+ cwe: dict[str, Any] | None = None
36
+ code: str | None = None
37
+ line_range: list[int] | None = None
38
+
39
+ @property
40
+ def message(self) -> str:
41
+ """Get a human-readable message for the issue.
42
+
43
+ Returns:
44
+ str: Formatted issue message.
45
+ """
46
+ return (
47
+ f"[{self.test_id}:{self.test_name}] {self.issue_severity} severity, "
48
+ f"{self.issue_confidence} confidence: {self.issue_text}"
49
+ )
@@ -0,0 +1,99 @@
1
+ """Bandit output parser for security issues."""
2
+
3
+ from typing import Any
4
+
5
+ from loguru import logger
6
+
7
+ from lintro.parsers.bandit.bandit_issue import BanditIssue
8
+
9
+
10
+ def parse_bandit_output(bandit_data: dict[str, Any]) -> list[BanditIssue]:
11
+ """Parse Bandit JSON output into BanditIssue objects.
12
+
13
+ Args:
14
+ bandit_data: dict[str, Any]: JSON data from Bandit output.
15
+
16
+ Returns:
17
+ list[BanditIssue]: List of parsed security issues.
18
+
19
+ Raises:
20
+ ValueError: If the bandit data structure is invalid.
21
+ """
22
+ if not isinstance(bandit_data, dict):
23
+ raise ValueError("Bandit data must be a dictionary")
24
+
25
+ results = bandit_data.get("results", [])
26
+ if not isinstance(results, list):
27
+ raise ValueError("Bandit results must be a list")
28
+
29
+ issues: list[BanditIssue] = []
30
+
31
+ for result in results:
32
+ if not isinstance(result, dict):
33
+ continue
34
+
35
+ try:
36
+ filename = result.get("filename", "")
37
+ line_number = result.get("line_number", 0)
38
+ col_offset = result.get("col_offset", 0)
39
+ issue_severity = result.get("issue_severity", "UNKNOWN")
40
+ issue_confidence = result.get("issue_confidence", "UNKNOWN")
41
+ test_id = result.get("test_id", "")
42
+ test_name = result.get("test_name", "")
43
+ issue_text = result.get("issue_text", "")
44
+ more_info = result.get("more_info", "")
45
+ cwe = result.get("issue_cwe")
46
+ code = result.get("code")
47
+ line_range = result.get("line_range")
48
+
49
+ # Validate critical fields; skip malformed entries
50
+ if not isinstance(filename, str):
51
+ logger.warning("Skipping issue with non-string filename")
52
+ continue
53
+ if not isinstance(line_number, int):
54
+ logger.warning("Skipping issue with non-integer line_number")
55
+ continue
56
+ if not isinstance(col_offset, int):
57
+ col_offset = 0
58
+
59
+ sev = (
60
+ str(issue_severity).upper() if issue_severity is not None else "UNKNOWN"
61
+ )
62
+ conf = (
63
+ str(issue_confidence).upper()
64
+ if issue_confidence is not None
65
+ else "UNKNOWN"
66
+ )
67
+
68
+ test_id = test_id if isinstance(test_id, str) else ""
69
+ test_name = test_name if isinstance(test_name, str) else ""
70
+ issue_text = issue_text if isinstance(issue_text, str) else ""
71
+ more_info = more_info if isinstance(more_info, str) else ""
72
+
73
+ # Normalize line_range to list[int] when provided
74
+ if isinstance(line_range, list):
75
+ line_range = [x for x in line_range if isinstance(x, int)] or None
76
+ else:
77
+ line_range = None
78
+
79
+ issue = BanditIssue(
80
+ file=filename,
81
+ line=line_number,
82
+ col_offset=col_offset,
83
+ issue_severity=sev,
84
+ issue_confidence=conf,
85
+ test_id=test_id,
86
+ test_name=test_name,
87
+ issue_text=issue_text,
88
+ more_info=more_info,
89
+ cwe=cwe if isinstance(cwe, dict) else None,
90
+ code=code if isinstance(code, str) else None,
91
+ line_range=line_range,
92
+ )
93
+ issues.append(issue)
94
+ except (KeyError, TypeError, ValueError) as e:
95
+ # Log warning but continue processing other issues
96
+ logger.warning(f"Failed to parse bandit issue: {e}")
97
+ continue
98
+
99
+ return issues
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lintro
3
- Version: 0.13.2
3
+ Version: 0.14.0
4
4
  Summary: A unified CLI tool for code formatting, linting, and quality assurance
5
5
  Author-email: TurboCoder13 <turbocoder13@gmail.com>
6
6
  License: MIT License
@@ -80,6 +80,9 @@ lintro/parsers/__init__.py
80
80
  lintro/parsers/actionlint/__init__.py
81
81
  lintro/parsers/actionlint/actionlint_issue.py
82
82
  lintro/parsers/actionlint/actionlint_parser.py
83
+ lintro/parsers/bandit/__init__.py
84
+ lintro/parsers/bandit/bandit_issue.py
85
+ lintro/parsers/bandit/bandit_parser.py
83
86
  lintro/parsers/black/black_issue.py
84
87
  lintro/parsers/black/black_parser.py
85
88
  lintro/parsers/darglint/__init__.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "lintro"
7
- version = "0.13.2"
7
+ version = "0.14.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",]
@@ -38,7 +38,7 @@ Documentation = "https://github.com/TurboCoder13/py-lintro/docs"
38
38
  Source = "https://github.com/TurboCoder13/py-lintro"
39
39
 
40
40
  [tool.setuptools]
41
- packages = [ "lintro", "lintro.cli_utils", "lintro.cli_utils.commands", "lintro.enums", "lintro.exceptions", "lintro.formatters", "lintro.formatters.core", "lintro.formatters.styles", "lintro.formatters.tools", "lintro.models", "lintro.models.core", "lintro.parsers", "lintro.parsers.black", "lintro.parsers.darglint", "lintro.parsers.hadolint", "lintro.parsers.prettier", "lintro.parsers.ruff", "lintro.parsers.yamllint", "lintro.parsers.actionlint", "lintro.tools", "lintro.tools.core", "lintro.tools.implementations", "lintro.utils",]
41
+ packages = [ "lintro", "lintro.cli_utils", "lintro.cli_utils.commands", "lintro.enums", "lintro.exceptions", "lintro.formatters", "lintro.formatters.core", "lintro.formatters.styles", "lintro.formatters.tools", "lintro.models", "lintro.models.core", "lintro.parsers", "lintro.parsers.actionlint", "lintro.parsers.bandit", "lintro.parsers.black", "lintro.parsers.darglint", "lintro.parsers.hadolint", "lintro.parsers.prettier", "lintro.parsers.ruff", "lintro.parsers.yamllint", "lintro.tools", "lintro.tools.core", "lintro.tools.implementations", "lintro.utils",]
42
42
 
43
43
  [tool.semantic_release]
44
44
  branch = "main"
@@ -13,6 +13,8 @@ is installed as a built distribution. However, these tests serve as:
13
13
 
14
14
  from __future__ import annotations
15
15
 
16
+ import pytest
17
+
16
18
 
17
19
  def test_main_package_import() -> None:
18
20
  """Test that the main lintro package can be imported."""
@@ -148,3 +150,73 @@ def test_cross_package_imports() -> None:
148
150
  assert bandit is not None
149
151
  assert BanditTool is not None
150
152
  assert BanditTableDescriptor is not None
153
+
154
+
155
+ def test_bandit_parser_direct_import() -> None:
156
+ """Test that bandit parser can be imported directly.
157
+
158
+ This test specifically catches circular import issues that would occur
159
+ when lintro is installed as a built package (wheel). The issue manifests
160
+ when trying to import bandit parser submodules before the formatters
161
+ have loaded, which triggers a specific circular dependency pattern.
162
+ """
163
+ # This import sequence triggers the circular import that was fixed
164
+ from lintro.parsers.bandit import bandit_issue, bandit_parser
165
+
166
+ assert bandit_issue is not None
167
+ assert bandit_parser is not None
168
+
169
+
170
+ def test_parser_lazy_loading() -> None:
171
+ """Test that parser submodules are lazily loaded, not eagerly imported.
172
+
173
+ Verifies that accessing parser submodules through the parent package
174
+ works via __getattr__ and doesn't cause circular imports.
175
+ """
176
+ import lintro.parsers
177
+
178
+ # Access submodules via attribute access (triggers __getattr__)
179
+ bandit = lintro.parsers.bandit
180
+ actionlint = lintro.parsers.actionlint
181
+
182
+ assert bandit is not None
183
+ assert actionlint is not None
184
+
185
+
186
+ def test_parser_lazy_loading_attribute_error() -> None:
187
+ """Test that accessing non-existent parser raises AttributeError.
188
+
189
+ Verifies that the __getattr__ error handling works correctly.
190
+ """
191
+ import lintro.parsers
192
+
193
+ # Accessing a non-existent submodule should raise AttributeError
194
+ with pytest.raises(AttributeError) as exc_info:
195
+ _ = lintro.parsers.nonexistent_parser
196
+
197
+ assert "nonexistent_parser" in str(exc_info.value)
198
+
199
+
200
+ def test_parser_dir_function() -> None:
201
+ """Test that dir() works on parsers module.
202
+
203
+ Verifies that the __dir__ function returns all available submodules.
204
+ """
205
+ import lintro.parsers
206
+
207
+ # Get the directory listing of the parsers module
208
+ dir_listing = dir(lintro.parsers)
209
+
210
+ # All expected submodules should be in the directory
211
+ expected_modules = {
212
+ "actionlint",
213
+ "bandit",
214
+ "darglint",
215
+ "hadolint",
216
+ "prettier",
217
+ "ruff",
218
+ "yamllint",
219
+ }
220
+
221
+ for module in expected_modules:
222
+ assert module in dir_listing
@@ -1,21 +0,0 @@
1
- """Parser modules for Lintro tools."""
2
-
3
- from . import (
4
- actionlint,
5
- bandit,
6
- darglint,
7
- hadolint,
8
- prettier,
9
- ruff,
10
- yamllint,
11
- )
12
-
13
- __all__ = [
14
- "actionlint",
15
- "bandit",
16
- "darglint",
17
- "hadolint",
18
- "prettier",
19
- "ruff",
20
- "yamllint",
21
- ]
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