lintro 0.13.1__tar.gz → 0.13.3__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.1/lintro.egg-info → lintro-0.13.3}/PKG-INFO +5 -3
  2. {lintro-0.13.1 → lintro-0.13.3}/README.md +3 -1
  3. {lintro-0.13.1 → lintro-0.13.3}/assets/images/coverage-badge.svg +2 -2
  4. {lintro-0.13.1 → lintro-0.13.3}/lintro/__init__.py +1 -1
  5. lintro-0.13.3/lintro/parsers/__init__.py +72 -0
  6. lintro-0.13.3/lintro/parsers/bandit/__init__.py +6 -0
  7. lintro-0.13.3/lintro/parsers/bandit/bandit_issue.py +49 -0
  8. lintro-0.13.3/lintro/parsers/bandit/bandit_parser.py +99 -0
  9. {lintro-0.13.1 → lintro-0.13.3/lintro.egg-info}/PKG-INFO +5 -3
  10. {lintro-0.13.1 → lintro-0.13.3}/lintro.egg-info/SOURCES.txt +5 -0
  11. {lintro-0.13.1 → lintro-0.13.3}/pyproject.toml +3 -3
  12. lintro-0.13.3/tests/integration/test_built_package.py +112 -0
  13. lintro-0.13.3/tests/unit/test_package_imports.py +222 -0
  14. lintro-0.13.1/lintro/parsers/__init__.py +0 -21
  15. {lintro-0.13.1 → lintro-0.13.3}/LICENSE +0 -0
  16. {lintro-0.13.1 → lintro-0.13.3}/MANIFEST.in +0 -0
  17. {lintro-0.13.1 → lintro-0.13.3}/assets/images/lintro.png +0 -0
  18. {lintro-0.13.1 → lintro-0.13.3}/docs/README.md +0 -0
  19. {lintro-0.13.1 → lintro-0.13.3}/docs/configuration.md +0 -0
  20. {lintro-0.13.1 → lintro-0.13.3}/docs/contributing.md +0 -0
  21. {lintro-0.13.1 → lintro-0.13.3}/docs/coverage-setup.md +0 -0
  22. {lintro-0.13.1 → lintro-0.13.3}/docs/docker.md +0 -0
  23. {lintro-0.13.1 → lintro-0.13.3}/docs/getting-started.md +0 -0
  24. {lintro-0.13.1 → lintro-0.13.3}/docs/github-integration.md +0 -0
  25. {lintro-0.13.1 → lintro-0.13.3}/docs/lintro-self-use.md +0 -0
  26. {lintro-0.13.1 → lintro-0.13.3}/docs/security/assurance.md +0 -0
  27. {lintro-0.13.1 → lintro-0.13.3}/docs/security/requirements.md +0 -0
  28. {lintro-0.13.1 → lintro-0.13.3}/docs/style-guide.md +0 -0
  29. {lintro-0.13.1 → lintro-0.13.3}/docs/tool-analysis/README.md +0 -0
  30. {lintro-0.13.1 → lintro-0.13.3}/docs/tool-analysis/actionlint-analysis.md +0 -0
  31. {lintro-0.13.1 → lintro-0.13.3}/docs/tool-analysis/bandit-analysis.md +0 -0
  32. {lintro-0.13.1 → lintro-0.13.3}/docs/tool-analysis/black-analysis.md +0 -0
  33. {lintro-0.13.1 → lintro-0.13.3}/docs/tool-analysis/darglint-analysis.md +0 -0
  34. {lintro-0.13.1 → lintro-0.13.3}/docs/tool-analysis/hadolint-analysis.md +0 -0
  35. {lintro-0.13.1 → lintro-0.13.3}/docs/tool-analysis/prettier-analysis.md +0 -0
  36. {lintro-0.13.1 → lintro-0.13.3}/docs/tool-analysis/ruff-analysis.md +0 -0
  37. {lintro-0.13.1 → lintro-0.13.3}/docs/tool-analysis/yamllint-analysis.md +0 -0
  38. {lintro-0.13.1 → lintro-0.13.3}/lintro/__main__.py +0 -0
  39. {lintro-0.13.1 → lintro-0.13.3}/lintro/ascii-art/fail.txt +0 -0
  40. {lintro-0.13.1 → lintro-0.13.3}/lintro/ascii-art/success.txt +0 -0
  41. {lintro-0.13.1 → lintro-0.13.3}/lintro/cli.py +0 -0
  42. {lintro-0.13.1 → lintro-0.13.3}/lintro/cli_utils/__init__.py +0 -0
  43. {lintro-0.13.1 → lintro-0.13.3}/lintro/cli_utils/commands/__init__.py +0 -0
  44. {lintro-0.13.1 → lintro-0.13.3}/lintro/cli_utils/commands/check.py +0 -0
  45. {lintro-0.13.1 → lintro-0.13.3}/lintro/cli_utils/commands/format.py +0 -0
  46. {lintro-0.13.1 → lintro-0.13.3}/lintro/cli_utils/commands/list_tools.py +0 -0
  47. {lintro-0.13.1 → lintro-0.13.3}/lintro/enums/__init__.py +0 -0
  48. {lintro-0.13.1 → lintro-0.13.3}/lintro/enums/action.py +0 -0
  49. {lintro-0.13.1 → lintro-0.13.3}/lintro/enums/darglint_strictness.py +0 -0
  50. {lintro-0.13.1 → lintro-0.13.3}/lintro/enums/group_by.py +0 -0
  51. {lintro-0.13.1 → lintro-0.13.3}/lintro/enums/hadolint_enums.py +0 -0
  52. {lintro-0.13.1 → lintro-0.13.3}/lintro/enums/output_format.py +0 -0
  53. {lintro-0.13.1 → lintro-0.13.3}/lintro/enums/tool_name.py +0 -0
  54. {lintro-0.13.1 → lintro-0.13.3}/lintro/enums/tool_type.py +0 -0
  55. {lintro-0.13.1 → lintro-0.13.3}/lintro/enums/yamllint_format.py +0 -0
  56. {lintro-0.13.1 → lintro-0.13.3}/lintro/exceptions/__init__.py +0 -0
  57. {lintro-0.13.1 → lintro-0.13.3}/lintro/exceptions/errors.py +0 -0
  58. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/__init__.py +0 -0
  59. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/core/__init__.py +0 -0
  60. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/core/output_style.py +0 -0
  61. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/core/table_descriptor.py +0 -0
  62. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/styles/__init__.py +0 -0
  63. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/styles/csv.py +0 -0
  64. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/styles/grid.py +0 -0
  65. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/styles/html.py +0 -0
  66. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/styles/json.py +0 -0
  67. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/styles/markdown.py +0 -0
  68. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/styles/plain.py +0 -0
  69. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/tools/__init__.py +0 -0
  70. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/tools/actionlint_formatter.py +0 -0
  71. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/tools/bandit_formatter.py +0 -0
  72. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/tools/black_formatter.py +0 -0
  73. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/tools/darglint_formatter.py +0 -0
  74. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/tools/hadolint_formatter.py +0 -0
  75. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/tools/prettier_formatter.py +0 -0
  76. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/tools/ruff_formatter.py +0 -0
  77. {lintro-0.13.1 → lintro-0.13.3}/lintro/formatters/tools/yamllint_formatter.py +0 -0
  78. {lintro-0.13.1 → lintro-0.13.3}/lintro/models/__init__.py +0 -0
  79. {lintro-0.13.1 → lintro-0.13.3}/lintro/models/core/__init__.py +0 -0
  80. {lintro-0.13.1 → lintro-0.13.3}/lintro/models/core/tool.py +0 -0
  81. {lintro-0.13.1 → lintro-0.13.3}/lintro/models/core/tool_config.py +0 -0
  82. {lintro-0.13.1 → lintro-0.13.3}/lintro/models/core/tool_result.py +0 -0
  83. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/actionlint/__init__.py +0 -0
  84. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/actionlint/actionlint_issue.py +0 -0
  85. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/actionlint/actionlint_parser.py +0 -0
  86. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/black/black_issue.py +0 -0
  87. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/black/black_parser.py +0 -0
  88. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/darglint/__init__.py +0 -0
  89. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/darglint/darglint_issue.py +0 -0
  90. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/darglint/darglint_parser.py +0 -0
  91. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/hadolint/__init__.py +0 -0
  92. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/hadolint/hadolint_issue.py +0 -0
  93. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/hadolint/hadolint_parser.py +0 -0
  94. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/prettier/__init__.py +0 -0
  95. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/prettier/prettier_issue.py +0 -0
  96. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/prettier/prettier_parser.py +0 -0
  97. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/ruff/__init__.py +0 -0
  98. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/ruff/ruff_issue.py +0 -0
  99. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/ruff/ruff_parser.py +0 -0
  100. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/yamllint/__init__.py +0 -0
  101. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/yamllint/yamllint_issue.py +0 -0
  102. {lintro-0.13.1 → lintro-0.13.3}/lintro/parsers/yamllint/yamllint_parser.py +0 -0
  103. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/__init__.py +0 -0
  104. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/core/__init__.py +0 -0
  105. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/core/tool_base.py +0 -0
  106. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/core/tool_manager.py +0 -0
  107. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/implementations/__init__.py +0 -0
  108. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/implementations/tool_actionlint.py +0 -0
  109. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/implementations/tool_bandit.py +0 -0
  110. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/implementations/tool_black.py +0 -0
  111. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/implementations/tool_darglint.py +0 -0
  112. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/implementations/tool_hadolint.py +0 -0
  113. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/implementations/tool_prettier.py +0 -0
  114. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/implementations/tool_ruff.py +0 -0
  115. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/implementations/tool_yamllint.py +0 -0
  116. {lintro-0.13.1 → lintro-0.13.3}/lintro/tools/tool_enum.py +0 -0
  117. {lintro-0.13.1 → lintro-0.13.3}/lintro/utils/__init__.py +0 -0
  118. {lintro-0.13.1 → lintro-0.13.3}/lintro/utils/ascii_normalize_cli.py +0 -0
  119. {lintro-0.13.1 → lintro-0.13.3}/lintro/utils/config.py +0 -0
  120. {lintro-0.13.1 → lintro-0.13.3}/lintro/utils/console_logger.py +0 -0
  121. {lintro-0.13.1 → lintro-0.13.3}/lintro/utils/formatting.py +0 -0
  122. {lintro-0.13.1 → lintro-0.13.3}/lintro/utils/output_manager.py +0 -0
  123. {lintro-0.13.1 → lintro-0.13.3}/lintro/utils/path_utils.py +0 -0
  124. {lintro-0.13.1 → lintro-0.13.3}/lintro/utils/tool_executor.py +0 -0
  125. {lintro-0.13.1 → lintro-0.13.3}/lintro/utils/tool_utils.py +0 -0
  126. {lintro-0.13.1 → lintro-0.13.3}/lintro.egg-info/dependency_links.txt +0 -0
  127. {lintro-0.13.1 → lintro-0.13.3}/lintro.egg-info/entry_points.txt +0 -0
  128. {lintro-0.13.1 → lintro-0.13.3}/lintro.egg-info/requires.txt +0 -0
  129. {lintro-0.13.1 → lintro-0.13.3}/lintro.egg-info/top_level.txt +0 -0
  130. {lintro-0.13.1 → lintro-0.13.3}/setup.cfg +0 -0
  131. {lintro-0.13.1 → lintro-0.13.3}/test_samples/Dockerfile.violations +0 -0
  132. {lintro-0.13.1 → lintro-0.13.3}/test_samples/actionlint_violations.yml +0 -0
  133. {lintro-0.13.1 → lintro-0.13.3}/test_samples/bandit_violations.py +0 -0
  134. {lintro-0.13.1 → lintro-0.13.3}/test_samples/darglint_violations.py +0 -0
  135. {lintro-0.13.1 → lintro-0.13.3}/test_samples/prettier_violations.js +0 -0
  136. {lintro-0.13.1 → lintro-0.13.3}/test_samples/ruff_annotations_violations.py +0 -0
  137. {lintro-0.13.1 → lintro-0.13.3}/test_samples/ruff_black_e501_wrappable.py +0 -0
  138. {lintro-0.13.1 → lintro-0.13.3}/test_samples/ruff_bugbear_violations.py +0 -0
  139. {lintro-0.13.1 → lintro-0.13.3}/test_samples/ruff_c4_comprehensions_violations.py +0 -0
  140. {lintro-0.13.1 → lintro-0.13.3}/test_samples/ruff_clean.py +0 -0
  141. {lintro-0.13.1 → lintro-0.13.3}/test_samples/ruff_naming_violations.py +0 -0
  142. {lintro-0.13.1 → lintro-0.13.3}/test_samples/ruff_sim_simplify_violations.py +0 -0
  143. {lintro-0.13.1 → lintro-0.13.3}/test_samples/ruff_violations.py +0 -0
  144. {lintro-0.13.1 → lintro-0.13.3}/test_samples/yaml_violations.yml +0 -0
  145. {lintro-0.13.1 → lintro-0.13.3}/tests/__init__.py +0 -0
  146. {lintro-0.13.1 → lintro-0.13.3}/tests/cli/__init__.py +0 -0
  147. {lintro-0.13.1 → lintro-0.13.3}/tests/cli/conftest.py +0 -0
  148. {lintro-0.13.1 → lintro-0.13.3}/tests/cli/test_cli.py +0 -0
  149. {lintro-0.13.1 → lintro-0.13.3}/tests/conftest.py +0 -0
  150. {lintro-0.13.1 → lintro-0.13.3}/tests/formatters/__init__.py +0 -0
  151. {lintro-0.13.1 → lintro-0.13.3}/tests/formatters/conftest.py +0 -0
  152. {lintro-0.13.1 → lintro-0.13.3}/tests/formatters/test_formatters.py +0 -0
  153. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/__init__.py +0 -0
  154. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/conftest.py +0 -0
  155. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/test_actionlint_integration.py +0 -0
  156. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/test_bandit_integration.py +0 -0
  157. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/test_darglint_integration.py +0 -0
  158. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/test_hadolint_integration.py +0 -0
  159. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/test_prettier_integration.py +0 -0
  160. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/test_ruff_additional_coverage.py +0 -0
  161. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/test_ruff_annotations.py +0 -0
  162. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/test_ruff_black_policy.py +0 -0
  163. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/test_ruff_bugbear.py +0 -0
  164. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/test_ruff_integration.py +0 -0
  165. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/test_ruff_naming.py +0 -0
  166. {lintro-0.13.1 → lintro-0.13.3}/tests/integration/test_yamllint_integration.py +0 -0
  167. {lintro-0.13.1 → lintro-0.13.3}/tests/scripts/__init__.py +0 -0
  168. {lintro-0.13.1 → lintro-0.13.3}/tests/scripts/test_ci_post_pr_comment.py +0 -0
  169. {lintro-0.13.1 → lintro-0.13.3}/tests/scripts/test_delete_previous_lintro_comments.py +0 -0
  170. {lintro-0.13.1 → lintro-0.13.3}/tests/scripts/test_extract_version.py +0 -0
  171. {lintro-0.13.1 → lintro-0.13.3}/tests/scripts/test_ghcr_prune_untagged.py +0 -0
  172. {lintro-0.13.1 → lintro-0.13.3}/tests/scripts/test_github_comment_utilities.py +0 -0
  173. {lintro-0.13.1 → lintro-0.13.3}/tests/scripts/test_script_environment.py +0 -0
  174. {lintro-0.13.1 → lintro-0.13.3}/tests/scripts/test_semantic_release_compute_next.py +0 -0
  175. {lintro-0.13.1 → lintro-0.13.3}/tests/scripts/test_shell_scripts.py +0 -0
  176. {lintro-0.13.1 → lintro-0.13.3}/tests/test_documentation.py +0 -0
  177. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/__init__.py +0 -0
  178. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_ascii_normalize.py +0 -0
  179. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_bandit_command_building.py +0 -0
  180. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_bandit_config_hydration.py +0 -0
  181. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_bandit_formatter_mapping.py +0 -0
  182. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_bandit_parsing.py +0 -0
  183. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_black_formatter.py +0 -0
  184. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_black_parser.py +0 -0
  185. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_black_tool.py +0 -0
  186. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_black_tool_more.py +0 -0
  187. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_cli_commands.py +0 -0
  188. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_cli_commands_more.py +0 -0
  189. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_cli_programmatic.py +0 -0
  190. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_compatibility_ruff_black.py +0 -0
  191. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_config_loader.py +0 -0
  192. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_config_loader_more.py +0 -0
  193. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_console_logger.py +0 -0
  194. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_console_logger_more.py +0 -0
  195. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_enums_and_normalizers.py +0 -0
  196. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_exceptions.py +0 -0
  197. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_formatters_tables.py +0 -0
  198. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_output_manager_reports.py +0 -0
  199. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_parsers_actionlint.py +0 -0
  200. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_ruff_parser_additional.py +0 -0
  201. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_ruff_parser_more.py +0 -0
  202. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_subprocess_validator.py +0 -0
  203. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_tool_base_subprocess.py +0 -0
  204. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_tool_executor.py +0 -0
  205. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_tool_executor_fmt_exclusion.py +0 -0
  206. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_tool_executor_more.py +0 -0
  207. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_tool_executor_post_checks.py +0 -0
  208. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_tool_manager.py +0 -0
  209. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_tool_utils.py +0 -0
  210. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_tool_utils_fallbacks.py +0 -0
  211. {lintro-0.13.1 → lintro-0.13.3}/tests/unit/test_tool_utils_more.py +0 -0
  212. {lintro-0.13.1 → lintro-0.13.3}/tests/utils/__init__.py +0 -0
  213. {lintro-0.13.1 → lintro-0.13.3}/tests/utils/conftest.py +0 -0
  214. {lintro-0.13.1 → lintro-0.13.3}/tests/utils/test_formatting.py +0 -0
  215. {lintro-0.13.1 → lintro-0.13.3}/tests/utils/test_output_manager.py +0 -0
  216. {lintro-0.13.1 → lintro-0.13.3}/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.1
3
+ Version: 0.13.3
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
@@ -36,7 +36,7 @@ Classifier: Programming Language :: Python :: 3.13
36
36
  Classifier: Topic :: Software Development :: Quality Assurance
37
37
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
38
38
  Classifier: Topic :: Utilities
39
- Requires-Python: ==3.13.7
39
+ Requires-Python: >=3.13
40
40
  Description-Content-Type: text/markdown
41
41
  License-File: LICENSE
42
42
  Requires-Dist: click==8.1.8
@@ -169,8 +169,10 @@ grype sbom:main-*-py-lintro-sbom.spdx-2.3.json
169
169
 
170
170
  #### From PyPI (Recommended)
171
171
 
172
+ ⚠️ **Important**: Versions prior to 0.13.2 contain a circular import bug that prevents installation as a dependency. Please use version 0.13.2 or later.
173
+
172
174
  ```bash
173
- pip install lintro
175
+ pip install lintro>=0.13.2
174
176
  ```
175
177
 
176
178
  #### Development Installation
@@ -95,8 +95,10 @@ grype sbom:main-*-py-lintro-sbom.spdx-2.3.json
95
95
 
96
96
  #### From PyPI (Recommended)
97
97
 
98
+ ⚠️ **Important**: Versions prior to 0.13.2 contain a circular import bug that prevents installation as a dependency. Please use version 0.13.2 or later.
99
+
98
100
  ```bash
99
- pip install lintro
101
+ pip install lintro>=0.13.2
100
102
  ```
101
103
 
102
104
  #### Development Installation
@@ -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.2%</text>
19
- <text x="800" y="140" transform="scale(.1)" textLength="260">84.2%</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.1"
3
+ __version__ = "0.13.3"
@@ -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.1
3
+ Version: 0.13.3
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
@@ -36,7 +36,7 @@ Classifier: Programming Language :: Python :: 3.13
36
36
  Classifier: Topic :: Software Development :: Quality Assurance
37
37
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
38
38
  Classifier: Topic :: Utilities
39
- Requires-Python: ==3.13.7
39
+ Requires-Python: >=3.13
40
40
  Description-Content-Type: text/markdown
41
41
  License-File: LICENSE
42
42
  Requires-Dist: click==8.1.8
@@ -169,8 +169,10 @@ grype sbom:main-*-py-lintro-sbom.spdx-2.3.json
169
169
 
170
170
  #### From PyPI (Recommended)
171
171
 
172
+ ⚠️ **Important**: Versions prior to 0.13.2 contain a circular import bug that prevents installation as a dependency. Please use version 0.13.2 or later.
173
+
172
174
  ```bash
173
- pip install lintro
175
+ pip install lintro>=0.13.2
174
176
  ```
175
177
 
176
178
  #### Development Installation
@@ -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
@@ -147,6 +150,7 @@ tests/integration/__init__.py
147
150
  tests/integration/conftest.py
148
151
  tests/integration/test_actionlint_integration.py
149
152
  tests/integration/test_bandit_integration.py
153
+ tests/integration/test_built_package.py
150
154
  tests/integration/test_darglint_integration.py
151
155
  tests/integration/test_hadolint_integration.py
152
156
  tests/integration/test_prettier_integration.py
@@ -188,6 +192,7 @@ tests/unit/test_enums_and_normalizers.py
188
192
  tests/unit/test_exceptions.py
189
193
  tests/unit/test_formatters_tables.py
190
194
  tests/unit/test_output_manager_reports.py
195
+ tests/unit/test_package_imports.py
191
196
  tests/unit/test_parsers_actionlint.py
192
197
  tests/unit/test_ruff_parser_additional.py
193
198
  tests/unit/test_ruff_parser_more.py
@@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "lintro"
7
- version = "0.13.1"
7
+ version = "0.13.3"
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",]
11
- requires-python = "==3.13.7"
11
+ requires-python = ">=3.13"
12
12
  dependencies = [ "click==8.1.8", "coverage-badge==1.1.2", "darglint==1.8.1", "loguru==0.7.3", "tabulate==0.9.0", "yamllint==1.37.1", "httpx==0.28.1", "toml==0.10.2", "defusedxml==0.7.1",]
13
13
  [[project.authors]]
14
14
  name = "TurboCoder13"
@@ -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"
@@ -0,0 +1,112 @@
1
+ """Integration test for built package installation.
2
+
3
+ This module tests that lintro can be installed as a built wheel distribution
4
+ and imported successfully, catching circular import issues that only manifest
5
+ when the package is installed (not in editable mode).
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import subprocess
11
+ import sys
12
+ import tempfile
13
+ from pathlib import Path
14
+
15
+ import pytest
16
+ from assertpy import assert_that
17
+
18
+
19
+ @pytest.mark.slow
20
+ def test_built_wheel_imports() -> None:
21
+ """Test that lintro can be built and imported as a wheel.
22
+
23
+ This test:
24
+ 1. Builds lintro as a wheel
25
+ 2. Installs it in a fresh virtual environment
26
+ 3. Attempts to import critical modules
27
+ 4. Verifies no circular import errors occur
28
+
29
+ This catches issues that only manifest when lintro is installed as a
30
+ dependency (built distribution) rather than in editable mode.
31
+ """
32
+ project_root = Path(__file__).parent.parent.parent
33
+
34
+ with tempfile.TemporaryDirectory() as tmpdir:
35
+ tmpdir_path = Path(tmpdir)
36
+ venv_path = tmpdir_path / "test_venv"
37
+ dist_dir = tmpdir_path / "dist"
38
+
39
+ # Step 1: Build the wheel
40
+ build_result = subprocess.run(
41
+ ["uv", "build", "--out-dir", str(dist_dir)],
42
+ cwd=str(project_root),
43
+ capture_output=True,
44
+ text=True,
45
+ timeout=60,
46
+ )
47
+ assert_that(build_result.returncode).is_equal_to(0)
48
+ assert_that(dist_dir.exists()).is_true()
49
+
50
+ # Find the built wheel
51
+ wheels = list(dist_dir.glob("*.whl"))
52
+ assert_that(wheels).is_not_empty()
53
+ wheel_path = wheels[0]
54
+
55
+ # Step 2: Create a fresh virtual environment
56
+ venv_result = subprocess.run(
57
+ [sys.executable, "-m", "venv", str(venv_path)],
58
+ capture_output=True,
59
+ text=True,
60
+ timeout=30,
61
+ )
62
+ assert_that(venv_result.returncode).is_equal_to(0)
63
+
64
+ # Determine the Python executable in the venv
65
+ if sys.platform == "win32":
66
+ python_exe = venv_path / "Scripts" / "python.exe"
67
+ else:
68
+ python_exe = venv_path / "bin" / "python"
69
+
70
+ assert_that(python_exe.exists()).is_true()
71
+
72
+ # Step 3: Install the wheel in the venv
73
+ install_result = subprocess.run(
74
+ [str(python_exe), "-m", "pip", "install", str(wheel_path)],
75
+ capture_output=True,
76
+ text=True,
77
+ timeout=60,
78
+ )
79
+ assert_that(install_result.returncode).is_equal_to(0)
80
+
81
+ # Step 4: Test importing lintro modules (this is where circular imports fail)
82
+ test_imports = [
83
+ "import lintro",
84
+ "import lintro.parsers",
85
+ "from lintro.parsers import bandit",
86
+ "from lintro.parsers.actionlint.actionlint_parser import parse_actionlint_output", # noqa: E501
87
+ "from lintro.tools.implementations.tool_actionlint import ActionlintTool",
88
+ "from lintro.cli import cli",
89
+ ]
90
+
91
+ for import_statement in test_imports:
92
+ import_result = subprocess.run(
93
+ [str(python_exe), "-c", import_statement],
94
+ capture_output=True,
95
+ text=True,
96
+ timeout=10,
97
+ )
98
+ assert_that(import_result.returncode).described_as(
99
+ f"Import failed: {import_statement}\n"
100
+ f"stdout: {import_result.stdout}\n"
101
+ f"stderr: {import_result.stderr}",
102
+ ).is_equal_to(0)
103
+
104
+ # Step 5: Test that lintro CLI works
105
+ cli_result = subprocess.run(
106
+ [str(python_exe), "-m", "lintro", "--version"],
107
+ capture_output=True,
108
+ text=True,
109
+ timeout=10,
110
+ )
111
+ assert_that(cli_result.returncode).is_equal_to(0)
112
+ assert_that(cli_result.stdout).contains("lintro")