pyvbaanalysis 2.2.1__tar.gz → 2.3.1__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.
Files changed (237) hide show
  1. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/.github/workflows/ci.yml +6 -6
  2. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/.github/workflows/publish.yml +34 -4
  3. pyvbaanalysis-2.3.1/.github/workflows/security.yml +141 -0
  4. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/CHANGELOG.md +158 -0
  5. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/CONTRIBUTING.md +17 -1
  6. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/PKG-INFO +15 -1
  7. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/README.md +14 -0
  8. pyvbaanalysis-2.3.1/SECURITY.md +39 -0
  9. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/docs/diagnostics-catalogue.md +40 -6
  10. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/docs/usage.md +3 -1
  11. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/__init__.py +1 -1
  12. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/cli.py +12 -2
  13. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/completion/member_access.py +363 -86
  14. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/conditional/__init__.py +2 -0
  15. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/conditional/conditional_compilation.py +50 -22
  16. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/constants/integer_constant_expression.py +23 -9
  17. pyvbaanalysis-2.3.1/pyvbaanalysis/data/access_host_model.json +1 -0
  18. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/data/diagnostic_influence_audit.json +516 -3
  19. pyvbaanalysis-2.3.1/pyvbaanalysis/data/excel_host_model.json +1 -0
  20. pyvbaanalysis-2.3.1/pyvbaanalysis/data/host_closed_types.json +646 -0
  21. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/data/manifest.json +79 -11
  22. pyvbaanalysis-2.3.1/pyvbaanalysis/data/powerpoint_host_model.json +1 -0
  23. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/data/rule_metadata.json +395 -2
  24. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/data/vba_runtime_tables.json +1 -1
  25. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/data/vbe_oracle_cases.json +2146 -0
  26. pyvbaanalysis-2.3.1/pyvbaanalysis/data/word_host_model.json +1 -0
  27. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/analyze_module.py +31 -8
  28. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/argument_inference.py +73 -9
  29. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/call_extraction.py +6 -0
  30. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/callable_signatures.py +37 -2
  31. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/context.py +5 -0
  32. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/dataflow.py +101 -48
  33. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/exprwalk.py +31 -30
  34. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/known_locals.py +274 -0
  35. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/module_analysis.py +106 -0
  36. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/registry.py +48 -5
  37. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/arrays.py +572 -86
  38. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/assignments.py +176 -15
  39. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/collection_state.py +399 -0
  40. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/control_flow.py +104 -81
  41. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/dead_code.py +85 -73
  42. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/declaration_forms.py +211 -0
  43. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/declarations.py +120 -46
  44. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/directive_forms.py +105 -0
  45. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/duplicates.py +38 -0
  46. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/expressions.py +387 -17
  47. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/file_statements.py +397 -0
  48. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/handler_flow.py +345 -0
  49. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/host_arguments.py +749 -0
  50. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/implements_members.py +275 -0
  51. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/late_bound_members.py +234 -0
  52. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/line_continuations.py +127 -0
  53. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/module_kind.py +28 -0
  54. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/numeric_literals.py +277 -0
  55. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/object_state.py +146 -14
  56. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/overflow.py +1025 -0
  57. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/runtime_values.py +964 -0
  58. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/shared.py +27 -25
  59. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/statement_forms.py +190 -0
  60. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/stray_tokens.py +162 -0
  61. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/type_of_is.py +113 -22
  62. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/undeclared.py +90 -10
  63. pyvbaanalysis-2.3.1/pyvbaanalysis/diagnostics/rules/variant_values.py +189 -0
  64. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/walker.py +18 -22
  65. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/flow/procedure_labels.py +22 -11
  66. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/flow/procedure_unstructured.py +6 -13
  67. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/host/__init__.py +2 -0
  68. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/host/host_model.py +13 -0
  69. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/host/type_extensibility.py +36 -12
  70. pyvbaanalysis-2.3.1/pyvbaanalysis/js_compat.py +111 -0
  71. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/lexer/keyword_table.py +7 -1
  72. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/lexer/token_kinds.py +3 -1
  73. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/lexer/tokenize.py +20 -0
  74. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/parser/nodes.py +54 -1
  75. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/parser/parse_module.py +233 -39
  76. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/parser/parser_state.py +49 -1
  77. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/runtime/vba_runtime.py +12 -1
  78. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/symbols/build_module_symbols.py +3 -7
  79. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/symbols/name_resolution.py +25 -6
  80. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/symbols/project_index.py +34 -6
  81. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/symbols/symbol_model.py +5 -0
  82. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/types/type_inference.py +9 -5
  83. pyvbaanalysis-2.3.1/tests/test_analyzer_lexes_module_once.py +52 -0
  84. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_cli.py +18 -0
  85. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_conditional_arms.py +3 -2
  86. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_dataflow.py +16 -0
  87. pyvbaanalysis-2.3.1/tests/test_deep_nesting.py +171 -0
  88. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_diagnostics_engine.py +3 -1
  89. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_evidence.py +2 -2
  90. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_host_libraries.py +3 -1
  91. pyvbaanalysis-2.3.1/tests/test_member_access_chains.py +176 -0
  92. pyvbaanalysis-2.3.1/tests/test_module_analysis.py +122 -0
  93. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_registry_parity.py +12 -4
  94. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rule_metadata.py +5 -5
  95. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_argument_types.py +9 -2
  96. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_assignments_types.py +5 -1
  97. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_control_flow.py +8 -3
  98. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_declarations.py +3 -1
  99. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_property_setter_value_parameters.py +10 -12
  100. pyvbaanalysis-2.3.1/tests/test_upstream_sync_10_12_0.py +721 -0
  101. pyvbaanalysis-2.3.1/tests/test_upstream_sync_10_13_0.py +45 -0
  102. pyvbaanalysis-2.3.1/tests/test_upstream_sync_10_14_0.py +294 -0
  103. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_upstream_sync_10_6_0.py +3 -3
  104. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tools/extract_host_model.mjs +18 -6
  105. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tools/generate_manifest.py +5 -2
  106. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tools/vendor_data.py +8 -7
  107. pyvbaanalysis-2.2.1/pyvbaanalysis/data/access_host_model.json +0 -1
  108. pyvbaanalysis-2.2.1/pyvbaanalysis/data/excel_closed_types.json +0 -31
  109. pyvbaanalysis-2.2.1/pyvbaanalysis/data/excel_host_model.json +0 -1
  110. pyvbaanalysis-2.2.1/pyvbaanalysis/data/powerpoint_host_model.json +0 -1
  111. pyvbaanalysis-2.2.1/pyvbaanalysis/data/word_host_model.json +0 -1
  112. pyvbaanalysis-2.2.1/pyvbaanalysis/diagnostics/rules/numeric_literals.py +0 -49
  113. pyvbaanalysis-2.2.1/pyvbaanalysis/diagnostics/rules/runtime_values.py +0 -384
  114. pyvbaanalysis-2.2.1/tests/test_member_access_chains.py +0 -45
  115. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/.gitattributes +0 -0
  116. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/.github/dependabot.yml +0 -0
  117. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/.gitignore +0 -0
  118. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/LICENSE +0 -0
  119. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/docs/api-reference.md +0 -0
  120. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyproject.toml +0 -0
  121. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/__main__.py +0 -0
  122. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/call/__init__.py +0 -0
  123. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/call/call_context.py +0 -0
  124. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/completion/__init__.py +0 -0
  125. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/completion/cursor_context.py +0 -0
  126. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/completion/event_handlers.py +0 -0
  127. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/completion/type_completion.py +0 -0
  128. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/constants/__init__.py +0 -0
  129. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/data/event_definitions.json +0 -0
  130. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/data/msforms_members.json +0 -0
  131. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/data/vb6_host_model.json +0 -0
  132. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/__init__.py +0 -0
  133. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/const_expr.py +0 -0
  134. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/inline_suppression.py +0 -0
  135. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/model.py +0 -0
  136. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rule_metadata.py +0 -0
  137. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/__init__.py +0 -0
  138. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/argument_shape.py +0 -0
  139. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/argument_types.py +0 -0
  140. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/binary_operand_scalar.py +0 -0
  141. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/call_arity.py +0 -0
  142. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/doc_comments.py +0 -0
  143. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/late_binding.py +0 -0
  144. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/lexical.py +0 -0
  145. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/missing_reference.py +0 -0
  146. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/diagnostics/rules/parameter_defaults.py +0 -0
  147. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/docs/__init__.py +0 -0
  148. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/docs/doc_comment.py +0 -0
  149. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/evidence.py +0 -0
  150. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/flow/__init__.py +0 -0
  151. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/host/host_libraries.py +0 -0
  152. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/host/host_registry.py +0 -0
  153. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/host/msforms.py +0 -0
  154. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/identity_cache.py +0 -0
  155. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/lexer/__init__.py +0 -0
  156. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/lexer/contextual_keywords.py +0 -0
  157. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/lexer/stripped_lines.py +0 -0
  158. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/lexer/token_helpers.py +0 -0
  159. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/lexer/trivia.py +0 -0
  160. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/parser/__init__.py +0 -0
  161. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/parser/fixed_length_string.py +0 -0
  162. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/parser/parse_expression.py +0 -0
  163. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/parser/type_declaration_suffix.py +0 -0
  164. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/project.py +0 -0
  165. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/py.typed +0 -0
  166. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/reader/__init__.py +0 -0
  167. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/reader/loose_file.py +0 -0
  168. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/reader/vbe_module.py +0 -0
  169. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/reader/workbook.py +0 -0
  170. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/references/__init__.py +0 -0
  171. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/references/reference_kinds.py +0 -0
  172. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/runtime/__init__.py +0 -0
  173. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/symbols/__init__.py +0 -0
  174. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/symbols/user_form_controls.py +0 -0
  175. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/types/__init__.py +0 -0
  176. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/pyvbaanalysis/types/type_names.py +0 -0
  177. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/conftest.py +0 -0
  178. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/oracle_support.py +0 -0
  179. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_conditional_compilation.py +0 -0
  180. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_host_model.py +0 -0
  181. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_host_seam.py +0 -0
  182. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_inline_suppression.py +0 -0
  183. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_integer_constant_expression.py +0 -0
  184. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_language_matrix.py +0 -0
  185. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_lexer.py +0 -0
  186. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_parser.py +0 -0
  187. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_project.py +0 -0
  188. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_project_index.py +0 -0
  189. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_public_api.py +0 -0
  190. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_reader.py +0 -0
  191. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_real_world_false_positives.py +0 -0
  192. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_reference_kinds.py +0 -0
  193. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_ambiguous_enum_member.py +0 -0
  194. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_argument_shape.py +0 -0
  195. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_arrays.py +0 -0
  196. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_assignments.py +0 -0
  197. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_binary_operand_scalar.py +0 -0
  198. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_call_arity.py +0 -0
  199. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_dead_code.py +0 -0
  200. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_division_by_zero.py +0 -0
  201. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_doc_comments.py +0 -0
  202. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_duplicates.py +0 -0
  203. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_event_handler_module_scope.py +0 -0
  204. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_expression_calls.py +0 -0
  205. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_expressions.py +0 -0
  206. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_invalid_as_type_names.py +0 -0
  207. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_is_operator_non_object.py +0 -0
  208. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_late_binding.py +0 -0
  209. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_lexical.py +0 -0
  210. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_member_not_found.py +0 -0
  211. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_missing_reference.py +0 -0
  212. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_module_kind.py +0 -0
  213. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_numeric_literals.py +0 -0
  214. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_object_state.py +0 -0
  215. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_parameter_defaults.py +0 -0
  216. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_runtime_values.py +0 -0
  217. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_scalar_and_foreach.py +0 -0
  218. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_type_of_is.py +0 -0
  219. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_typeof_is_always_false.py +0 -0
  220. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_rules_undeclared.py +0 -0
  221. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_runtime_tables.py +0 -0
  222. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_statement_token_derivation.py +0 -0
  223. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_stripped_lines.py +0 -0
  224. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_symbols.py +0 -0
  225. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_token_helpers.py +0 -0
  226. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_type_completion.py +0 -0
  227. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_type_names.py +0 -0
  228. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_upstream_sync_10_5_0.py +0 -0
  229. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_upstream_sync_10_7_1.py +0 -0
  230. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tests/test_upstream_sync_6_1_2.py +0 -0
  231. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tools/extract_event_definitions.mjs +0 -0
  232. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tools/extract_rule_metadata.mjs +0 -0
  233. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tools/extract_runtime_tables.mjs +0 -0
  234. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tools/generate_diagnostics_catalogue.py +0 -0
  235. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tools/oracle/build_combining_mark_probe.py +0 -0
  236. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tools/pin_analyzer.py +0 -0
  237. {pyvbaanalysis-2.2.1 → pyvbaanalysis-2.3.1}/tools/xlide_source.mjs +0 -0
@@ -21,8 +21,8 @@ jobs:
21
21
  name: Lint and type check
22
22
  runs-on: ubuntu-latest
23
23
  steps:
24
- - uses: actions/checkout@v7
25
- - uses: actions/setup-python@v7
24
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
25
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
26
26
  with:
27
27
  python-version: "3.12"
28
28
  cache: pip
@@ -41,8 +41,8 @@ jobs:
41
41
  matrix:
42
42
  os: [ubuntu-latest, windows-latest]
43
43
  steps:
44
- - uses: actions/checkout@v7
45
- - uses: actions/setup-python@v7
44
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
45
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
46
46
  with:
47
47
  python-version: "3.12"
48
48
  cache: pip
@@ -62,8 +62,8 @@ jobs:
62
62
  matrix:
63
63
  python-version: ["3.10", "3.11", "3.12", "3.13"]
64
64
  steps:
65
- - uses: actions/checkout@v7
66
- - uses: actions/setup-python@v7
65
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
66
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
67
67
  with:
68
68
  python-version: ${{ matrix.python-version }}
69
69
  cache: pip
@@ -20,8 +20,18 @@ permissions:
20
20
  contents: read
21
21
 
22
22
  jobs:
23
+ # CodeQL, Semgrep and pip-audit (security.yml). Any finding fails this job,
24
+ # and publishing waits on it.
25
+ security:
26
+ name: Security analysis
27
+ uses: ./.github/workflows/security.yml
28
+ permissions:
29
+ contents: read
30
+ security-events: write
31
+
23
32
  publish:
24
33
  name: Build and publish to PyPI
34
+ needs: security
25
35
  runs-on: ubuntu-latest
26
36
  environment:
27
37
  name: pypi
@@ -29,8 +39,8 @@ jobs:
29
39
  permissions:
30
40
  id-token: write # OIDC token for PyPI Trusted Publishing
31
41
  steps:
32
- - uses: actions/checkout@v7
33
- - uses: actions/setup-python@v7
42
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
43
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
34
44
  with:
35
45
  python-version: "3.12"
36
46
  cache: pip
@@ -45,9 +55,29 @@ jobs:
45
55
  - name: Build sdist + wheel
46
56
  run: python -m build
47
57
  - name: Upload build artifacts
48
- uses: actions/upload-artifact@v7
58
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
49
59
  with:
50
60
  name: dist
51
61
  path: dist/*
52
62
  - name: Publish to PyPI
53
- uses: pypa/gh-action-pypi-publish@release/v1
63
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
64
+
65
+ attach-security-report:
66
+ name: Attach the security report to the release
67
+ needs: [security, publish]
68
+ runs-on: ubuntu-latest
69
+ permissions:
70
+ contents: write
71
+ steps:
72
+ - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
73
+ with:
74
+ name: security-report
75
+ path: report
76
+ - name: Upload to the release
77
+ env:
78
+ GH_TOKEN: ${{ github.token }}
79
+ TAG: ${{ github.event.release.tag_name }}
80
+ run: |
81
+ cd report
82
+ tar -czf security-sarif.tar.gz *.sarif *.json
83
+ gh release upload "$TAG" security-report.md security-sarif.tar.gz --clobber --repo "$GITHUB_REPOSITORY"
@@ -0,0 +1,141 @@
1
+ name: Security
2
+
3
+ # Static security analysis: CodeQL (Python and the workflows themselves),
4
+ # Semgrep, and pip-audit over the runtime dependency tree. Any finding fails
5
+ # the run. Results go to the repository's Security tab as SARIF and to a
6
+ # `security-report` artifact, which publish.yml attaches to every release.
7
+
8
+ on:
9
+ push:
10
+ branches: [main]
11
+ pull_request:
12
+ schedule:
13
+ - cron: "17 6 * * 1" # weekly, so new advisories surface between pushes
14
+ workflow_call:
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ jobs:
20
+ codeql:
21
+ name: CodeQL (${{ matrix.language }})
22
+ runs-on: ubuntu-latest
23
+ permissions:
24
+ contents: read
25
+ security-events: write
26
+ strategy:
27
+ fail-fast: false
28
+ matrix:
29
+ language: [python, actions]
30
+ steps:
31
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
32
+ - uses: github/codeql-action/init@1190a975f95ce23525efb6a3fc21ea29567c1b52 # v3
33
+ with:
34
+ languages: ${{ matrix.language }}
35
+ queries: security-extended
36
+ - uses: github/codeql-action/analyze@1190a975f95ce23525efb6a3fc21ea29567c1b52 # v3
37
+ with:
38
+ category: codeql-${{ matrix.language }}
39
+ output: sarif
40
+ - name: Fail on any finding
41
+ run: |
42
+ count=$(jq '[.runs[].results[]] | length' sarif/*.sarif)
43
+ echo "CodeQL ${{ matrix.language }}: $count finding(s)"
44
+ jq -r '.runs[].results[] | "\(.ruleId): \(.locations[0].physicalLocation.artifactLocation.uri):\(.locations[0].physicalLocation.region.startLine) \(.message.text)"' sarif/*.sarif
45
+ test "$count" -eq 0
46
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
47
+ if: always()
48
+ with:
49
+ name: sarif-codeql-${{ matrix.language }}
50
+ path: sarif/*.sarif
51
+
52
+ semgrep:
53
+ name: Semgrep
54
+ runs-on: ubuntu-latest
55
+ permissions:
56
+ contents: read
57
+ security-events: write
58
+ steps:
59
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
60
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
61
+ with:
62
+ python-version: "3.12"
63
+ - run: python -m pip install "semgrep>=1,<2"
64
+ - name: Scan (fails on any finding)
65
+ run: >
66
+ semgrep scan --metrics off --error
67
+ --config p/python --config p/security-audit
68
+ --config p/secrets --config p/github-actions
69
+ --sarif-output semgrep.sarif --text
70
+ - uses: github/codeql-action/upload-sarif@1190a975f95ce23525efb6a3fc21ea29567c1b52 # v3
71
+ if: always() && hashFiles('semgrep.sarif') != ''
72
+ with:
73
+ sarif_file: semgrep.sarif
74
+ category: semgrep
75
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
76
+ if: always()
77
+ with:
78
+ name: sarif-semgrep
79
+ path: semgrep.sarif
80
+
81
+ dependencies:
82
+ name: Dependency audit
83
+ runs-on: ubuntu-latest
84
+ steps:
85
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
86
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
87
+ with:
88
+ python-version: "3.12"
89
+ # The runtime tree without pyvbaanalysis itself, whose version is not on
90
+ # PyPI until the release that ships it; frozen before pip-audit is added.
91
+ - run: |
92
+ python -m pip install .
93
+ python -m pip freeze --exclude pyvbaanalysis > runtime.txt
94
+ cat runtime.txt
95
+ python -m pip install pip-audit
96
+ - name: Audit the runtime dependencies (fails on any known vulnerability)
97
+ run: pip-audit --strict --no-deps -r runtime.txt --format json --output pip-audit.json --progress-spinner off
98
+ - if: always()
99
+ run: pip-audit --strict --no-deps -r runtime.txt --progress-spinner off || true
100
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
101
+ if: always()
102
+ with:
103
+ name: pip-audit
104
+ path: pip-audit.json
105
+
106
+ report:
107
+ name: Security report
108
+ needs: [codeql, semgrep, dependencies]
109
+ if: always()
110
+ runs-on: ubuntu-latest
111
+ steps:
112
+ - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
113
+ with:
114
+ path: results
115
+ merge-multiple: true
116
+ - name: Write the report
117
+ env:
118
+ CODEQL: ${{ needs.codeql.result }}
119
+ SEMGREP: ${{ needs.semgrep.result }}
120
+ DEPS: ${{ needs.dependencies.result }}
121
+ run: |
122
+ count() { if [ -f "$1" ]; then jq '[.runs[].results[]] | length' "$1"; else echo "not run"; fi; }
123
+ vulns=$(if [ -f results/pip-audit.json ]; then jq '[.dependencies[].vulns[]] | length' results/pip-audit.json; else echo "not run"; fi)
124
+ {
125
+ echo "# Security report"
126
+ echo
127
+ echo "Commit \`${GITHUB_SHA}\`, run ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
128
+ echo
129
+ echo "| Check | Result | Findings |"
130
+ echo "| --- | --- | --- |"
131
+ echo "| CodeQL (Python, security-extended) | $CODEQL | $(count results/python.sarif) |"
132
+ echo "| CodeQL (GitHub Actions) | $CODEQL | $(count results/actions.sarif) |"
133
+ echo "| Semgrep (python, security-audit, secrets, github-actions) | $SEMGREP | $(count results/semgrep.sarif) |"
134
+ echo "| pip-audit (runtime dependencies) | $DEPS | $vulns |"
135
+ } > security-report.md
136
+ mkdir -p report && cp security-report.md report/ && cp results/*.sarif results/*.json report/ 2>/dev/null || true
137
+ cat security-report.md >> "$GITHUB_STEP_SUMMARY"
138
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
139
+ with:
140
+ name: security-report
141
+ path: report/
@@ -5,6 +5,164 @@ All notable changes to pyVBAanalysis are recorded here. The format follows
5
5
  follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html): a minor version
6
6
  per milestone.
7
7
 
8
+ ## 2.3.1 - 2026-09-28
9
+
10
+ Sync to XLIDE 10.14.1 (commit 67b844d), from 10.14.0, and a command-line flag
11
+ for projects that ship as one file.
12
+
13
+ ### Added
14
+
15
+ * `--whole-project` on the command line runs the whole-project checks
16
+ (`undeclared-variable`, `unknown-call`, `member-not-found`) on any input,
17
+ a single file included, such as a single-module distribution. It cannot be
18
+ combined with `--partial-project`, and the default is unchanged (#15).
19
+ * Security checks. CodeQL, Semgrep and pip-audit run on every push and pull
20
+ request and weekly, and any finding fails the run. A release reaches PyPI
21
+ only when all three pass, and it carries `security-report.md` and the raw
22
+ results as assets. `SECURITY.md` describes private vulnerability reporting.
23
+
24
+ ### Fixed
25
+
26
+ * `property-accessor-signature-mismatch` on a Property Set beside a Get of
27
+ another type, such as a Variant Get with an Object Set. Excel compiles it:
28
+ a Set's value is never compared with the Get. A Let must still match its Get
29
+ (XLIDE issue #152).
30
+
31
+ ### Verified
32
+
33
+ * The oracle corpus (2251 diagnostics in 1289 modules), 16 real workbooks, 195
34
+ Office files, 693 further projects and 7 VB6 projects give identical findings
35
+ from both analyzers at 10.14.1. The recorded replay of upstream's test suite
36
+ did not run for this release.
37
+
38
+ ## 2.3.0 - 2026-09-26
39
+
40
+ Sync to XLIDE 10.14.0 (commit 110c76e), from 10.7.1. Upstream measured the
41
+ analyzer against Excel, Word and PowerPoint 16.0 (build 20326) through
42
+ pyVBAharness and answered each finding (XLIDE issues #96 to #148): 34 new
43
+ diagnostics, 19 of them runtime errors in code the VBE compiles, and false
44
+ positives removed on code that compiles and runs. XLIDE 10.7.2, 10.8.0, 10.11.0
45
+ and 10.12.0 changed nothing the port reads.
46
+
47
+ The port now returns what XLIDE shows, not its raw rule list, and it analyzes
48
+ procedures nested past Python's recursion limit and long With blocks and member
49
+ chains in linear time.
50
+
51
+ ### Added
52
+
53
+ * Nineteen runtime errors in code the VBE compiles, each reported as "This will
54
+ raise Run-time error ...":
55
+ * Overflow (#116): `arithmetic-overflow` for Integer arithmetic such as
56
+ `60 * 60 * 24`, an assignment that rounds past its target, and conversions
57
+ out of range; `for-counter-overflow` for `For i = 1 To 32767` on an Integer.
58
+ * Control flow (#117): `handler-fall-through` into an error handler that
59
+ re-raises, `resume-without-error`, `return-without-gosub`, and
60
+ `recursive-property-accessor`.
61
+ * Collections and Variants (#121): `collection-index-out-of-range`,
62
+ `collection-key-not-found`, `collection-key-in-use`, `variant-value-misuse`
63
+ and `runtime-member-not-found` (438 on a late-bound object).
64
+ * Host arguments (#122): `host-argument-out-of-range` for index 0 into a
65
+ 1-based Office collection, `Cells(0, 1)` or an Offset off the sheet;
66
+ `multi-cell-range-as-scalar`; `sheet-name-invalid`.
67
+ * File statements (#123): `file-number-zero`, `file-used-after-close`,
68
+ `file-mode-mismatch`, `file-already-open` and `file-record-zero`.
69
+ * Fifteen compile errors: `const-overflow` (#116); `array-parameter-form`,
70
+ `bracketed-variable-name` and `duplicate-deftype` (#124);
71
+ `collection-operand`, `sub-used-as-value`, `implements-member-missing`,
72
+ `implements-member-signature` and `rem-after-then` (#125);
73
+ `directive-trailing-statement` and `duplicate-const-directive` (#130);
74
+ `stray-character` for characters VBA does not use and a no-break space
75
+ (#132); `line-too-long`, `date-literal-invalid` and `float-literal-overflow`
76
+ (#133).
77
+ * Existing rules report more of what the code states (#118 to #120, #124 to
78
+ #126): `Asc("")`, `Sqr(-1)`, `Log(0)`, `CLng("abc")`, `"abc" + 1` into a
79
+ Variant, a divisor local that holds 0, array bounds known from `Split`,
80
+ `Array` or a Range literal's `Value`, `ReDim a(-1)`, `Next i, j` out of
81
+ order, and the line continuations the VBE refuses.
82
+ * `AnalyzeModuleOptions.raw_rule_output`: the rules' own list, as upstream's
83
+ `analyzeModule` returns it, without the two steps below.
84
+ * `resolve_host_member` in `pyvbaanalysis.host`, and `declaredType` on a host
85
+ model member: the type its library declares, where the model's `returns`
86
+ is repaired from the reference documentation.
87
+
88
+ ### Changed
89
+
90
+ * `analyze_module`, and everything built on it, returns what XLIDE shows. A
91
+ runtime-error finding under `On Error Resume Next`, from that statement to the
92
+ next `On Error` or the end of the procedure, is dropped, since the error is
93
+ raised and handled there (`n = UBound(a)` is the usual allocated-array
94
+ test, XLIDE issue #106). Findings with one code and span are merged, the later
95
+ one kept. `diagnostics/module_analysis.py` ports both from XLIDE's
96
+ `analyzeVbaModuleSource`.
97
+ * `member-not-found` works in Word, PowerPoint and Access: their models carry
98
+ the type libraries' hidden members and prove a member absent where the
99
+ library marks the interface NONEXTENSIBLE (#127). Document, Form, Report and
100
+ Control stay open. The data file `excel_closed_types.json` is replaced by
101
+ `host_closed_types.json`, which covers all four hosts.
102
+ * A host member the type library declares `As Object`, such as `ActiveSheet`
103
+ or a `Worksheets(1)` item, is late bound (#114).
104
+ * A hex or octal literal is the signed value of its bits: `&H8000` is -32768
105
+ and `&H80000000` is -2147483648 (#141). `parse_vba_integer_literal` returns
106
+ that value.
107
+ * The parser opens and closes a block written in a one-line If's tail (#128),
108
+ reads `Else:` as the If's Else (#129), counts a block keyword restated in both
109
+ arms of an `#If` once (#130), and reads a numbered one-line If with an `=`
110
+ condition as an If (#131).
111
+ * An Enum value or Optional default keeps its leading number, so `= 300 - 100`
112
+ is not the literal -100, and a module's Consts fold once with a procedure's
113
+ own Consts layered on top (XLIDE 10.13.0).
114
+
115
+ ### Fixed
116
+
117
+ * False positives on code the VBE compiles and runs (#96 to #115): `Choose` and
118
+ `Switch` arity, `Open path` without `For`, `On Local Error`, a ReDim that
119
+ declares its array, `total&+1`, a library qualifier such as `Excel.`, a
120
+ `#Const` never defined, DAO constants in Access, `Left(Null, 1)`, a string
121
+ into a Byte array, a division the code guards, the Let and Set pairings of a
122
+ property, Nothing tracking past a GoSub or an early `Exit For`, two project
123
+ types sharing an instance, a Public Enum in a class, a Const or parenthesized
124
+ ByRef argument, `Len` in an Enum value, Option placement after a Deftype, and
125
+ a Function's return assigned by For, ReDim, `Line Input #` or `Get #`.
126
+ * False positives found by this port's own hunt and fixed upstream in 10.14.0
127
+ (#140 to #147): `If c Is Nothing Then Set c = New Collection`, `Set a(i) = c`
128
+ and `AddressOf` a Sub reported as compile errors; Win32 flag Enums such as
129
+ `GENERIC_READ = &H80000000` as Overflow; `Err.Raise vbObjectError + 513` as
130
+ error 5; the `;` of `If x Then Debug.Print a; b`; a string default holding a
131
+ comma in an Implements signature; `32000 \ 2 * 4` folded at the wrong
132
+ precedence; a For counter in a loop that leaves through `Exit For`; a file
133
+ reopened after `Reset` or a closing helper, an error handler's `Print #`,
134
+ and hex file numbers; and an item added through `Set o = c`.
135
+ * Misses from the same issues: `1 Mod 200 * 200` (error 6), `Resume Next`
136
+ after `On Error GoTo -1` (20), a `Print #` after `Reset` (52), a duplicate
137
+ key added through an alias (457), and a read-write interface property
138
+ implemented with its Get alone.
139
+ * `analyze_project` raised RecursionError on a procedure nested about 490 blocks
140
+ deep, where the VBE compiles a thousand. Every walk over a procedure body now
141
+ runs on an explicit stack, and `tests/test_deep_nesting.py` fails on one that
142
+ recurses per block.
143
+
144
+ ### Performance
145
+
146
+ * A long With block and a long member chain are analyzed in linear time: the
147
+ pass keeps upstream's With-scan index (XLIDE issue #134) and receiver-chain
148
+ results (#135). A 500-line With block took 14.2 seconds in 2.2.1 and takes
149
+ 0.19; a 3,000-member chain took 16 seconds and takes 0.56.
150
+ * Expression strings the parser carried on their own are lexed without
151
+ evicting the module from the token cache, and a test fails if one pass lexes
152
+ a module twice (#139). On two parts of the differential corpus's Office files
153
+ (66 modules), 2.3.0 is 12% faster than 2.2.1, new rules included.
154
+
155
+ ### Verified
156
+
157
+ * Upstream's own 10.14.0 test suite, recorded and replayed through the port:
158
+ 1419 standalone and 992 project calls, identical in code, span and message.
159
+ * The oracle corpus (2155 diagnostics in 1229 modules), 16 real workbooks, 195
160
+ Office files of every host, 693 further projects (948 modules) and 7 VB6
161
+ projects: identical findings from both analyzers, compared at what XLIDE
162
+ shows.
163
+ * Every expectation in the new sync tests was also run through the pinned
164
+ upstream analyzer.
165
+
8
166
  ## 2.2.1 - 2026-09-23
9
167
 
10
168
  Sync to XLIDE 10.7.1 (commit 6ead73d), from 10.6.0. Upstream fixed how its
@@ -80,7 +80,8 @@ python tools/differential/harness.py projects artifacts/differential/cases/mine.
80
80
  the port, rebuilding the project index behind a call made with project context,
81
81
  and compares the diagnostics by code, span and message. It finds the gaps
82
82
  nothing else exercises: whole checks never ported, fixes older than the last
83
- sync point.
83
+ sync point. The recorded calls are the rules alone, so the port is asked for its
84
+ `raw_rule_output`.
84
85
  * `corpus` runs the oracle corpus through both analyzers, each module standalone
85
86
  and with its case's modules as a project.
86
87
  * `cases` turns Office files, and folders searched for them and for exported
@@ -88,6 +89,16 @@ python tools/differential/harness.py projects artifacts/differential/cases/mine.
88
89
  block of upstream's syntax corpus, and `--host` names a host for the cases no
89
90
  file implies one for. `projects` runs a cases file through both analyzers.
90
91
 
92
+ `corpus` and `projects` compare what XLIDE shows. Upstream runs its rules
93
+ through `analyzeVbaModuleSource`, which drops a runtime-error finding under
94
+ `On Error Resume Next` and merges findings with one code and span, as
95
+ `analyze_module` does (`pyvbaanalysis/diagnostics/module_analysis.py`). Its own
96
+ additions the port leaves out, the structural block-balance pass and XLIDE's test
97
+ and suppression directives, are cut from its list by keeping only what its rules
98
+ produced (`tools/differential/upstream/shown.mjs`). One step the port lacks does
99
+ remove findings: a procedure marked `'@xlide-test expected-error=N` hides a runtime
100
+ finding for error N. No corpus has one.
101
+
91
102
  `replay`, `corpus` and `projects` exit 1 when anything differs and print what only
92
103
  one side reports. Where the port reports more, the port is wrong. Where upstream
93
104
  reports more it may be an upstream false positive, so check before porting it.
@@ -104,6 +115,11 @@ run ends. `harness.py unpatch` restores a pin a run left patched, and
104
115
  ## Adding or changing a rule
105
116
 
106
117
  * Port the rule from its XLIDE source; match the behavior, not just the shape.
118
+ * Walk a procedure body with `iter_body_nodes` or `iter_body_nodes_in_context`
119
+ (`pyvbaanalysis/parser/nodes.py`), not with a function that calls itself for
120
+ each nested block. XLIDE's walks recurse, which JavaScript's stack absorbs;
121
+ Python stops at 1,000 frames, and the VBE compiles blocks nested a thousand
122
+ deep. `tests/test_deep_nesting.py` fails on a walk that recurses per block.
107
123
  * A rule ships only with oracle backing. Validate it against the vendored corpus
108
124
  and add direct tests for the positive and the no-false-positive control cases.
109
125
  * The diagnostic rule registry order is a contract: it is the diagnostic
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pyvbaanalysis
3
- Version: 2.2.1
3
+ Version: 2.3.1
4
4
  Summary: Pure-Python static analysis for Excel VBA
5
5
  Project-URL: Homepage, https://github.com/WilliamSmithEdward/pyVBAanalysis
6
6
  Project-URL: Repository, https://github.com/WilliamSmithEdward/pyVBAanalysis
@@ -29,6 +29,12 @@ Description-Content-Type: text/markdown
29
29
 
30
30
  # pyVBAanalysis
31
31
 
32
+ [![CI](https://github.com/WilliamSmithEdward/pyVBAanalysis/actions/workflows/ci.yml/badge.svg)](https://github.com/WilliamSmithEdward/pyVBAanalysis/actions/workflows/ci.yml)
33
+ [![Security](https://github.com/WilliamSmithEdward/pyVBAanalysis/actions/workflows/security.yml/badge.svg)](https://github.com/WilliamSmithEdward/pyVBAanalysis/actions/workflows/security.yml)
34
+ [![PyPI](https://img.shields.io/pypi/v/pyvbaanalysis)](https://pypi.org/project/pyvbaanalysis/)
35
+ [![Python](https://img.shields.io/pypi/pyversions/pyvbaanalysis)](https://pypi.org/project/pyvbaanalysis/)
36
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
37
+
32
38
  Static analysis for Office VBA. It reads your macros and reports likely bugs and the
33
39
  errors the VBA compiler would catch, without opening Office or running any code.
34
40
 
@@ -135,6 +141,14 @@ an agent that changes a macro runs them afterwards and treats an error
135
141
  as a failure rather than a suggestion, which is most of what stops a
136
142
  model shipping VBA that does not compile.
137
143
 
144
+ ## Security
145
+
146
+ Report a vulnerability privately through
147
+ [GitHub's advisory form](https://github.com/WilliamSmithEdward/pyVBAanalysis/security/advisories/new),
148
+ not a public issue. CodeQL, Semgrep and pip-audit run on every push and gate
149
+ every release, and each release carries its security report. See
150
+ [SECURITY.md](SECURITY.md).
151
+
138
152
  ## License
139
153
 
140
154
  MIT. See [LICENSE](LICENSE).
@@ -1,5 +1,11 @@
1
1
  # pyVBAanalysis
2
2
 
3
+ [![CI](https://github.com/WilliamSmithEdward/pyVBAanalysis/actions/workflows/ci.yml/badge.svg)](https://github.com/WilliamSmithEdward/pyVBAanalysis/actions/workflows/ci.yml)
4
+ [![Security](https://github.com/WilliamSmithEdward/pyVBAanalysis/actions/workflows/security.yml/badge.svg)](https://github.com/WilliamSmithEdward/pyVBAanalysis/actions/workflows/security.yml)
5
+ [![PyPI](https://img.shields.io/pypi/v/pyvbaanalysis)](https://pypi.org/project/pyvbaanalysis/)
6
+ [![Python](https://img.shields.io/pypi/pyversions/pyvbaanalysis)](https://pypi.org/project/pyvbaanalysis/)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
8
+
3
9
  Static analysis for Office VBA. It reads your macros and reports likely bugs and the
4
10
  errors the VBA compiler would catch, without opening Office or running any code.
5
11
 
@@ -106,6 +112,14 @@ an agent that changes a macro runs them afterwards and treats an error
106
112
  as a failure rather than a suggestion, which is most of what stops a
107
113
  model shipping VBA that does not compile.
108
114
 
115
+ ## Security
116
+
117
+ Report a vulnerability privately through
118
+ [GitHub's advisory form](https://github.com/WilliamSmithEdward/pyVBAanalysis/security/advisories/new),
119
+ not a public issue. CodeQL, Semgrep and pip-audit run on every push and gate
120
+ every release, and each release carries its security report. See
121
+ [SECURITY.md](SECURITY.md).
122
+
109
123
  ## License
110
124
 
111
125
  MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,39 @@
1
+ # Security
2
+
3
+ ## Supported versions
4
+
5
+ Security fixes go into the latest release on PyPI. Upgrade to it before
6
+ reporting a problem.
7
+
8
+ ## Reporting a vulnerability
9
+
10
+ Report privately through GitHub:
11
+ [Security > Report a vulnerability](https://github.com/WilliamSmithEdward/pyVBAanalysis/security/advisories/new).
12
+ Please do not open a public issue for a vulnerability.
13
+
14
+ Include the version, what you ran, the input that triggers the problem (a
15
+ minimal module or file if you can share one), and what happened. You will get a
16
+ reply within a week.
17
+
18
+ ## What counts
19
+
20
+ pyVBAanalysis reads Office files and VBA source and never runs them. A file
21
+ that makes the reader or the analyzer crash, hang, use unbounded memory, write
22
+ outside where it was asked to, or run code is a vulnerability. A wrong or
23
+ missing diagnostic is an ordinary bug; open an issue for it.
24
+
25
+ ## How the code is checked
26
+
27
+ Every push, pull request and release runs [security.yml](.github/workflows/security.yml):
28
+
29
+ - CodeQL with the `security-extended` queries, over the Python package and the
30
+ GitHub Actions workflows.
31
+ - Semgrep with the `python`, `security-audit`, `secrets` and `github-actions`
32
+ rule sets.
33
+ - pip-audit over the runtime dependencies.
34
+
35
+ Any finding fails the run, and a release is not published to PyPI until all
36
+ three pass. Each release carries the resulting `security-report.md` and the raw
37
+ SARIF and pip-audit output as assets. Dependabot keeps the dependencies and the
38
+ workflow actions current, and the run repeats weekly so new advisories surface
39
+ between releases.