csvpath 0.0.495__tar.gz → 0.0.496__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 (249) hide show
  1. {csvpath-0.0.495 → csvpath-0.0.496}/PKG-INFO +1 -1
  2. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/csvpath.py +57 -274
  3. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/csvpaths.py +0 -1
  4. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/args.py +13 -1
  5. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/function.py +2 -2
  6. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/productions/expression.py +7 -2
  7. csvpath-0.0.496/csvpath/modes/explain_mode.py +41 -0
  8. csvpath-0.0.496/csvpath/modes/files_mode.py +61 -0
  9. csvpath-0.0.496/csvpath/modes/logic_mode.py +66 -0
  10. csvpath-0.0.496/csvpath/modes/mode_controller.py +70 -0
  11. csvpath-0.0.496/csvpath/modes/print_mode.py +57 -0
  12. csvpath-0.0.496/csvpath/modes/return_mode.py +46 -0
  13. csvpath-0.0.496/csvpath/modes/run_mode.py +43 -0
  14. csvpath-0.0.496/csvpath/modes/source_mode.py +25 -0
  15. csvpath-0.0.496/csvpath/modes/transfer_mode.py +46 -0
  16. csvpath-0.0.496/csvpath/modes/unmatched_mode.py +30 -0
  17. csvpath-0.0.496/csvpath/modes/validation_mode.py +165 -0
  18. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/config.py +2 -1
  19. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/error.py +4 -4
  20. {csvpath-0.0.495 → csvpath-0.0.496}/pyproject.toml +1 -1
  21. {csvpath-0.0.495 → csvpath-0.0.496}/LICENSE +0 -0
  22. {csvpath-0.0.495 → csvpath-0.0.496}/README.md +0 -0
  23. {csvpath-0.0.495 → csvpath-0.0.496}/config/config.ini +0 -0
  24. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/__init__.py +0 -0
  25. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/cli/__init__.py +0 -0
  26. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/cli/cli.py +0 -0
  27. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/cli/drill_down.py +0 -0
  28. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/managers/__init__.py +0 -0
  29. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/managers/file_manager.py +0 -0
  30. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/managers/file_registrar.py +0 -0
  31. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/managers/line_spooler.py +0 -0
  32. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/managers/paths_manager.py +0 -0
  33. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/managers/paths_registrar.py +0 -0
  34. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/managers/result.py +0 -0
  35. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/managers/result_registrar.py +0 -0
  36. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/managers/result_serializer.py +0 -0
  37. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/managers/results_manager.py +0 -0
  38. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/managers/results_registrar.py +0 -0
  39. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/__init__.py +0 -0
  40. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/__init__.py +0 -0
  41. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/boolean/all.py +0 -0
  42. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/boolean/andf.py +0 -0
  43. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/boolean/any.py +0 -0
  44. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/boolean/between.py +0 -0
  45. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/boolean/empty.py +0 -0
  46. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/boolean/exists.py +0 -0
  47. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/boolean/inf.py +0 -0
  48. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/boolean/no.py +0 -0
  49. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/boolean/notf.py +0 -0
  50. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/boolean/orf.py +0 -0
  51. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/boolean/yes.py +0 -0
  52. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/counting/count.py +0 -0
  53. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/counting/count_bytes.py +0 -0
  54. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/counting/count_headers.py +0 -0
  55. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/counting/count_lines.py +0 -0
  56. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/counting/count_scans.py +0 -0
  57. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/counting/counter.py +0 -0
  58. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/counting/every.py +0 -0
  59. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/counting/has_matches.py +0 -0
  60. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/counting/increment.py +0 -0
  61. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/counting/tally.py +0 -0
  62. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/counting/total_lines.py +0 -0
  63. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/dates/now.py +0 -0
  64. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/function_factory.py +0 -0
  65. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/function_finder.py +0 -0
  66. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/function_focus.py +0 -0
  67. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/headers/append.py +0 -0
  68. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/headers/collect.py +0 -0
  69. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/headers/empty_stack.py +0 -0
  70. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/headers/end.py +0 -0
  71. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/headers/header_name.py +0 -0
  72. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
  73. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/headers/headers.py +0 -0
  74. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/headers/mismatch.py +0 -0
  75. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/headers/replace.py +0 -0
  76. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/headers/reset_headers.py +0 -0
  77. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/lines/advance.py +0 -0
  78. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/lines/after_blank.py +0 -0
  79. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/lines/dups.py +0 -0
  80. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/lines/first.py +0 -0
  81. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/lines/first_line.py +0 -0
  82. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/lines/last.py +0 -0
  83. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/lines/stop.py +0 -0
  84. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/math/above.py +0 -0
  85. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/math/add.py +0 -0
  86. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/math/divide.py +0 -0
  87. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/math/equals.py +0 -0
  88. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/math/intf.py +0 -0
  89. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/math/mod.py +0 -0
  90. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/math/multiply.py +0 -0
  91. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/math/round.py +0 -0
  92. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/math/subtotal.py +0 -0
  93. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/math/subtract.py +0 -0
  94. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/math/sum.py +0 -0
  95. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/misc/fingerprint.py +0 -0
  96. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/misc/importf.py +0 -0
  97. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/misc/random.py +0 -0
  98. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/print/jinjaf.py +0 -0
  99. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/print/print_line.py +0 -0
  100. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/print/print_queue.py +0 -0
  101. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/print/printf.py +0 -0
  102. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/print/table.py +0 -0
  103. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/stats/minf.py +0 -0
  104. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/stats/percent.py +0 -0
  105. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  106. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/stats/stdev.py +0 -0
  107. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/strings/concat.py +0 -0
  108. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/strings/length.py +0 -0
  109. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/strings/lower.py +0 -0
  110. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/strings/metaphone.py +0 -0
  111. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/strings/regex.py +0 -0
  112. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/strings/starts_with.py +0 -0
  113. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/strings/strip.py +0 -0
  114. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/strings/substring.py +0 -0
  115. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/strings/upper.py +0 -0
  116. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/testing/debug.py +0 -0
  117. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/types/__init__.py +0 -0
  118. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/types/boolean.py +0 -0
  119. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/types/datef.py +0 -0
  120. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/types/decimal.py +0 -0
  121. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/types/nonef.py +0 -0
  122. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/types/string.py +0 -0
  123. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/types/type.py +0 -0
  124. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/validity/fail.py +0 -0
  125. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/validity/failed.py +0 -0
  126. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/validity/line.py +0 -0
  127. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/variables/get.py +0 -0
  128. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/variables/pushpop.py +0 -0
  129. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/variables/put.py +0 -0
  130. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/variables/track.py +0 -0
  131. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/functions/variables/variables.py +0 -0
  132. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/lark_parser.py +0 -0
  133. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/lark_transformer.py +0 -0
  134. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/matcher.py +0 -0
  135. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/productions/__init__.py +0 -0
  136. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/productions/equality.py +0 -0
  137. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/productions/header.py +0 -0
  138. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/productions/matchable.py +0 -0
  139. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/productions/qualified.py +0 -0
  140. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/productions/reference.py +0 -0
  141. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/productions/term.py +0 -0
  142. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/productions/variable.py +0 -0
  143. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/util/exceptions.py +0 -0
  144. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/util/expression_encoder.py +0 -0
  145. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/util/expression_utility.py +0 -0
  146. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/util/lark_print_parser.py +0 -0
  147. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/util/print_parser.py +0 -0
  148. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/matching/util/runtime_data_collector.py +0 -0
  149. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/scanning/__init__.py +0 -0
  150. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/scanning/exceptions.py +0 -0
  151. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/scanning/parser.out +0 -0
  152. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/scanning/parsetab.py +0 -0
  153. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/scanning/scanner.py +0 -0
  154. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/scanning/scanning_lexer.py +0 -0
  155. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/cache.py +0 -0
  156. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/config_exception.py +0 -0
  157. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/csvpaths_registrar.py +0 -0
  158. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/exceptions.py +0 -0
  159. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/file_readers.py +0 -0
  160. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/last_line_stats.py +0 -0
  161. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/line_counter.py +0 -0
  162. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/line_monitor.py +0 -0
  163. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/log_utility.py +0 -0
  164. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/metadata_parser.py +0 -0
  165. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/pandas_data_reader.py +0 -0
  166. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/printer.py +0 -0
  167. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/reference_parser.py +0 -0
  168. {csvpath-0.0.495 → csvpath-0.0.496}/csvpath/util/s3_data_reader.py +0 -0
  169. {csvpath-0.0.495 → csvpath-0.0.496}/docs/asbool.md +0 -0
  170. {csvpath-0.0.495 → csvpath-0.0.496}/docs/assignment.md +0 -0
  171. {csvpath-0.0.495 → csvpath-0.0.496}/docs/comments.md +0 -0
  172. {csvpath-0.0.495 → csvpath-0.0.496}/docs/config.md +0 -0
  173. {csvpath-0.0.495 → csvpath-0.0.496}/docs/examples.md +0 -0
  174. {csvpath-0.0.495 → csvpath-0.0.496}/docs/files.md +0 -0
  175. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/above.md +0 -0
  176. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/advance.md +0 -0
  177. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/after_blank.md +0 -0
  178. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/all.md +0 -0
  179. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/andor.md +0 -0
  180. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/any.md +0 -0
  181. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/average.md +0 -0
  182. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/between.md +0 -0
  183. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/collect.md +0 -0
  184. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/correlate.md +0 -0
  185. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/count.md +0 -0
  186. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/count_bytes.md +0 -0
  187. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/count_headers.md +0 -0
  188. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/counter.md +0 -0
  189. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/date.md +0 -0
  190. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/empty.md +0 -0
  191. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/empty_stack.md +0 -0
  192. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/end.md +0 -0
  193. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/every.md +0 -0
  194. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/fail.md +0 -0
  195. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/fingerprint.md +0 -0
  196. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/first.md +0 -0
  197. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/get.md +0 -0
  198. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/has_dups.md +0 -0
  199. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/has_matches.md +0 -0
  200. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/header.md +0 -0
  201. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/header_name.md +0 -0
  202. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/header_names_mismatch.md +0 -0
  203. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/implementing_functions.md +0 -0
  204. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/import.md +0 -0
  205. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/in.md +0 -0
  206. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/increment.md +0 -0
  207. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/intf.md +0 -0
  208. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/jinja.md +0 -0
  209. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/last.md +0 -0
  210. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/line.md +0 -0
  211. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/line_number.md +0 -0
  212. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/max.md +0 -0
  213. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/metaphone.md +0 -0
  214. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/mismatch.md +0 -0
  215. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/no.md +0 -0
  216. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/not.md +0 -0
  217. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/now.md +0 -0
  218. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/percent_unique.md +0 -0
  219. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/pop.md +0 -0
  220. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/print.md +0 -0
  221. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/print_line.md +0 -0
  222. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/print_queue.md +0 -0
  223. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/random.md +0 -0
  224. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/regex.md +0 -0
  225. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/replace.md +0 -0
  226. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/reset_headers.md +0 -0
  227. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/stdev.md +0 -0
  228. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/stop.md +0 -0
  229. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/string_functions.md +0 -0
  230. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/subtotal.md +0 -0
  231. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/subtract.md +0 -0
  232. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/sum.md +0 -0
  233. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/tally.md +0 -0
  234. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/total_lines.md +0 -0
  235. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/track.md +0 -0
  236. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/types.md +0 -0
  237. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/variables.md +0 -0
  238. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions/variables_and_headers.md +0 -0
  239. {csvpath-0.0.495 → csvpath-0.0.496}/docs/functions.md +0 -0
  240. {csvpath-0.0.495 → csvpath-0.0.496}/docs/grammar.md +0 -0
  241. {csvpath-0.0.495 → csvpath-0.0.496}/docs/headers.md +0 -0
  242. {csvpath-0.0.495 → csvpath-0.0.496}/docs/images/logo-wordmark-white-on-black-trimmed-padded.png +0 -0
  243. {csvpath-0.0.495 → csvpath-0.0.496}/docs/images/logo-wordmark-white-trimmed.png +0 -0
  244. {csvpath-0.0.495 → csvpath-0.0.496}/docs/paths.md +0 -0
  245. {csvpath-0.0.495 → csvpath-0.0.496}/docs/printing.md +0 -0
  246. {csvpath-0.0.495 → csvpath-0.0.496}/docs/qualifiers.md +0 -0
  247. {csvpath-0.0.495 → csvpath-0.0.496}/docs/references.md +0 -0
  248. {csvpath-0.0.495 → csvpath-0.0.496}/docs/terms.md +0 -0
  249. {csvpath-0.0.495 → csvpath-0.0.496}/docs/variables.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: csvpath
3
- Version: 0.0.495
3
+ Version: 0.0.496
4
4
  Summary: A declarative language for validating CSV, Excel, and other tabular data files
5
5
  Author: David Kershaw
6
6
  Author-email: dk107dk@hotmail.com
@@ -29,6 +29,7 @@ from .matching.util.exceptions import MatchException
29
29
  from csvpath.util.printer import Printer
30
30
  from csvpath.util.file_readers import DataFileReader
31
31
  from csvpath.managers.line_spooler import LineSpooler, ListLineSpooler
32
+ from csvpath.modes.mode_controller import ModeController
32
33
 
33
34
 
34
35
  class CsvPathPublic(ABC):
@@ -110,12 +111,17 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
110
111
  # a parent CsvPaths may manage a CsvPath instance. if so, it will enable
111
112
  # the use of named files and named paths, print capture, error handling,
112
113
  # results collection, reference handling, etc. if a CsvPaths is not present
113
- # the CsvPath instance is responsible for all its own upkeep and does not have
114
- # some of those capabilities.
114
+ # the CsvPath instance is responsible for all its own upkeep and does not
115
+ # have some of those capabilities.
115
116
  #
116
117
  self.csvpaths = csvpaths
117
118
  #
119
+ # modes are set in external comments
118
120
  #
121
+ self.modes = ModeController(self)
122
+ #
123
+ # captures the number of lines up front and tracks line stats as the
124
+ # run progresses
119
125
  #
120
126
  self._line_monitor = None
121
127
  #
@@ -127,27 +133,14 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
127
133
  #
128
134
  self.match = None
129
135
  #
130
- # when AND is True we do a logical AND of the match components
131
- # to see if there is a match. this is the default. when AND is
132
- # False (or set OR to True) the match components are ORed to
133
- # determine if a line matches. in the former case all the match
134
- # components must agree for a line to match. in the latter case,
135
- # if any one match component votes True the line is matched.
136
- # technically you can switch from AND to OR, or vice versa, in
137
- # the middle of iterating a file using next(). probably not a
138
- # good idea, tho.
139
- #
140
- self._AND = True # pylint: disable=C0103
141
- #
142
136
  # when True the lines that do not match are returned from next()
143
137
  # and collect(). this effectively switches CsvPath from being an
144
- # AND machine to being a NOT AND machine. we do not actually
145
138
  # create an OR expression in this case. in the default, we say:
146
139
  # are all of these things true?
147
140
  # but when collect_when_not_matched is True we ask:
148
141
  # are any of these things not true?
149
142
  #
150
- self._when_not_matched = False
143
+ # self._when_not_matched = False
151
144
  self._headers = None
152
145
  self.variables: Dict[str, Any] = {}
153
146
  self.delimiter = delimiter
@@ -169,16 +162,6 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
169
162
  #
170
163
  self._freeze_path = False
171
164
  #
172
- # explain-mode: explain
173
- # turns on capturing match reasoning and dumps the captured decisions to INFO
174
- # at the end of a match. the reasoning is already present in the DEBUG but it
175
- # is harder to see amid all the noise. we don't want to dump explainations
176
- # all the time tho because it is very expensive -- potentially 25% worse
177
- # performance. the explainations could be improved. atm this is an experimental
178
- # feature.
179
- #
180
- self._explain = False
181
- #
182
165
  # counts are 1-based
183
166
  #
184
167
  self.scan_count = 0
@@ -233,14 +216,6 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
233
216
  self._errors: List[Error] = None
234
217
  self._error_collector = None
235
218
  #
236
- # transfers from transfer-mode: ((data | unmatched):var-name)(,*)
237
- # this setting tells CsvPaths to copy resulting data.csv and/or
238
- # unmatched.csv to one or more target locations below the config.ini's
239
- # transfer directory. the name "data" or "unmatched" is paired with
240
- # a var name that indicates the path to write the indicated file.
241
- #
242
- self._transfers = None
243
- #
244
219
  # saves the scan and match parts of paths for reference. mainly helpful
245
220
  # for testing the CsvPath library itself; not used end users. the run
246
221
  # name becomes the file name of the saved path parts.
@@ -280,30 +255,6 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
280
255
  # way.
281
256
  self._config = config
282
257
  #
283
- # these settings determine how we report function args validation
284
- # errors. e.g. if print(True) the validation check fails because
285
- # print() expects a string. the more recent trend is to get all
286
- # the errors and print statements in the same place controlled by
287
- # the same properties. for now this stays because there is a minor
288
- # benefit to being able to suppress runtime arg validation and only
289
- # use match component rules and exceptions to generate validation
290
- # info. but long term this capability may go away.
291
- #
292
- self._log_validation_errors = True
293
- self._print_validation_errors = True
294
- self._raise_validation_errors = None
295
- self._match_validation_errors = None
296
- self._stop_on_validation_errors = None
297
- self._fail_on_validation_errors = None
298
- #
299
- # run mode determines if a csvpath gets run or if it is skipped. the
300
- # main reasons to set run-mode: no-run vs. run are: you want to import
301
- # it into other csvpaths that are in the same named-paths group, or
302
- # you want to switch off a csvpath in a named-paths group for testing
303
- # a similar reason.
304
- #
305
- self._run_mode = True
306
- #
307
258
  # there are two logger components one for CsvPath and one for CsvPaths.
308
259
  # the default levels are set in config.ini. to change the levels pass LogUtility
309
260
  # your component instance and the logging level. e.g.:
@@ -312,23 +263,31 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
312
263
  self.logger = LogUtility.logger(self)
313
264
  self.logger.info("initialized CsvPath")
314
265
  self._ecoms = ErrorCommsManager(csvpath=self)
266
+ #
267
+ # _function_times_match collects the time a function spends doing its matches()
268
+ #
315
269
  self._function_times_match = {}
270
+ #
271
+ # _function_times_value collects the time a function spends doing its to_value()
272
+ #
316
273
  self._function_times_value = {}
317
274
  self._created_at = datetime.now()
318
275
  self._run_started_at = None
319
- self._all_expected_files = []
320
276
  self._collecting = False
277
+ #
278
+ # holds the unmatched lines when lines are being collected and
279
+ # _unmatched_available is True. it is analogous to the lines returned
280
+ # by collect(), but is the lines not returned by collect().
281
+ #
321
282
  self._unmatched = None
322
- self._unmatched_available = False
323
- self._data_from_preceding = False
324
283
 
325
284
  @property
326
285
  def data_from_preceding(self) -> bool:
327
- return self._data_from_preceding
286
+ return self.modes.source_mode.value
328
287
 
329
288
  @data_from_preceding.setter
330
289
  def data_from_preceding(self, dfp: bool) -> None:
331
- self._data_from_preceding = dfp
290
+ self.modes.source_mode.value = dfp
332
291
 
333
292
  @property
334
293
  def unmatched(self) -> list[list[Any]]:
@@ -346,22 +305,13 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
346
305
  def collecting(self, c: bool) -> None:
347
306
  self._collecting = c
348
307
 
349
- def set_unmatched_availability(self) -> None:
350
- um = self.metadata.get("unmatched-mode")
351
- if um is not None and um.find("no-keep") > -1:
352
- self.unmatched_available = False
353
- elif um is not None and um.find("keep") > -1:
354
- self.unmatched_available = True
355
- else:
356
- self.unmatched_available = False
357
-
358
308
  @property
359
309
  def unmatched_available(self) -> bool:
360
- return self._unmatched_available
310
+ return self.modes.unmatched_mode.value
361
311
 
362
312
  @unmatched_available.setter
363
313
  def unmatched_available(self, ua: bool) -> None:
364
- self._unmatched_available = ua
314
+ self.modes.unmatched_mode.value = ua
365
315
 
366
316
  @property
367
317
  def created_at(self) -> datetime:
@@ -373,12 +323,15 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
373
323
 
374
324
  @property
375
325
  def will_run(self) -> bool:
376
- return self._run_mode
326
+ return self.modes.run_mode.value
377
327
 
378
328
  @will_run.setter
379
329
  def will_run(self, mode) -> None:
380
- self._run_mode = mode
330
+ self.self.modes.run_mode.value = mode
381
331
 
332
+ #
333
+ # increases the total accumulated time spent doing c.matches() by t
334
+ #
382
335
  def _up_function_time_match(self, c, t) -> None:
383
336
  if c not in self.function_times_match:
384
337
  self.function_times_match[c] = 0
@@ -390,6 +343,9 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
390
343
  def function_times_match(self) -> int:
391
344
  return self._function_times_match
392
345
 
346
+ #
347
+ # increases the total accumulated time spent doing c.to_value() by t
348
+ #
393
349
  def _up_function_time_value(self, c, t) -> None:
394
350
  if c not in self.function_times_value:
395
351
  self.function_times_value[c] = 0
@@ -434,19 +390,19 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
434
390
 
435
391
  @property
436
392
  def AND(self) -> bool: # pylint: disable=C0103
437
- return self._AND
393
+ return self.modes.logic_mode.value
438
394
 
439
395
  @AND.setter
440
396
  def AND(self, a: bool) -> bool: # pylint: disable=C0103
441
- self._AND = a
397
+ self.modes.logic_mode.value = a
442
398
 
443
399
  @property
444
400
  def OR(self) -> bool: # pylint: disable=C0103
445
- return not self._AND
401
+ return not self.modes.logic_mode.value
446
402
 
447
403
  @OR.setter
448
404
  def OR(self, a: bool) -> bool: # pylint: disable=C0103
449
- self._AND = not a
405
+ self.modes.logic_mode.value = not a
450
406
 
451
407
  @property
452
408
  def identity(self) -> str:
@@ -516,86 +472,29 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
516
472
  self._errors = []
517
473
  self._errors.append(error)
518
474
 
519
- #
520
- # validation error handling overrides the error policy in config. this
521
- # is because the validation handling is:
522
- # - different. it is built-in. it deals with programmatic decisions
523
- # about how functions work and is the basis for structural (schema)
524
- # validation.
525
- # - set on a per csvpath basis in comments
526
- #
527
- # by default, validation errors do not impact matching. they are print
528
- # and raise only. however, you can set them to raise or match/not-match
529
- # and/or suppress printing.
530
- #
531
- def set_validation_error_handling(self, veh) -> None:
532
- # print prints to the Printer(s), not std.out. atm, no
533
- # customization of messages is possible, so there is likely
534
- # to be stylistic mismatch with other output.
535
- if veh and veh.find("no-print") > -1:
536
- self._print_validation_errors = False
537
- elif veh and veh.find("print") > -1:
538
- self._print_validation_errors = True
539
- else:
540
- self._print_validation_errors = None
541
- #
542
- if veh and veh.find("no-raise") > -1:
543
- self._raise_validation_errors = False
544
- elif veh and veh.find("raise") > -1:
545
- self._raise_validation_errors = True
546
- else:
547
- self._raise_validation_errors = None
548
- #
549
- # match, no-match, and None do:
550
- # match: return True on error
551
- # no-match: return False on error
552
- # None: default behavior: default_match() or result of matches()
553
- if veh and veh.find("no-match") > -1:
554
- self._match_validation_errors = False
555
- elif veh and veh.find("match") > -1:
556
- self._match_validation_errors = True
557
- else:
558
- self._match_validation_errors = None
559
- #
560
- # also stop and fail to match the config
561
- #
562
- if veh and veh.find("no-stop") > -1:
563
- self._stop_on_validation_errors = False
564
- elif veh and veh.find("stop") > -1:
565
- self._stop_on_validation_errors = True
566
- else:
567
- self._stop_on_validation_errors = None
568
- #
569
- if veh and veh.find("no-fail") > -1:
570
- self._fail_on_validation_errors = False
571
- elif veh and veh.find("fail") > -1:
572
- self._fail_on_validation_errors = True
573
- else:
574
- self._fail_on_validation_errors = None
575
-
576
475
  @property
577
476
  def stop_on_validation_errors(self) -> bool:
578
- return self._stop_on_validation_errors
477
+ return self.modes.validation_mode.stop_on_validation_errors
579
478
 
580
479
  @property
581
480
  def fail_on_validation_errors(self) -> bool:
582
- return self._fail_on_validation_errors
481
+ return self.modes.validation_mode.fail_on_validation_errors
583
482
 
584
483
  @property
585
484
  def print_validation_errors(self) -> bool:
586
- return self._print_validation_errors
485
+ return self.modes.validation_mode.print_validation_errors
587
486
 
588
487
  @property
589
488
  def log_validation_errors(self) -> bool:
590
- return self._log_validation_errors
489
+ return self.modes.validation_mode.log_validation_errors
591
490
 
592
491
  @property
593
492
  def raise_validation_errors(self) -> bool:
594
- return self._raise_validation_errors
493
+ return self.modes.validation_mode.raise_validation_errors
595
494
 
596
495
  @property
597
496
  def match_validation_errors(self) -> bool:
598
- return self._match_validation_errors
497
+ return self.modes.validation_mode.match_validation_errors
599
498
 
600
499
  def add_printer(self, printer) -> None: # pylint: disable=C0116
601
500
  if printer not in self.printers:
@@ -650,24 +549,24 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
650
549
  to INFO. this can be expensive. a 25% performance hit wouldn't
651
550
  be unexpected.
652
551
  """
653
- return self._explain
552
+ return self.modes.explain_mode.value
654
553
 
655
554
  @explain.setter
656
555
  def explain(self, yesno: bool) -> None:
657
- self._explain = yesno
556
+ self.modes.explain_mode.value = yesno
658
557
 
659
558
  @property
660
559
  def collect_when_not_matched(self) -> bool:
661
560
  """when this property is True CsvPath returns the lines that do not
662
561
  match the matchers match components"""
663
- return self._when_not_matched
562
+ return self.modes.return_mode.collect_when_not_matched
664
563
 
665
564
  @collect_when_not_matched.setter
666
565
  def collect_when_not_matched(self, yesno: bool) -> None:
667
- """when collect_when_not_matched is True we return the lines that failed
566
+ """when c ollect_when_not_matched is True we return the lines that failed
668
567
  to match, rather than the default behavior of returning the matches.
669
568
  """
670
- self._when_not_matched = yesno
569
+ self.modes.return_mode.collect_when_not_matched = yesno
671
570
 
672
571
  def parse(self, csvpath, disposably=False):
673
572
  """displosably is True when a Matcher is needed for some purpose other than
@@ -731,16 +630,8 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
731
630
  # - source-mode: preceding | origin
732
631
  # - files-mode: all | no-data | no-unmatched | no-printouts | data | unmatched | errors | meta | vars | printouts
733
632
  #
734
- self.update_logic_mode_if()
735
- self.update_run_mode_if()
736
- self.update_match_mode_if()
737
- self.update_print_mode_if()
738
- self.update_explain_mode_if()
739
- self.update_arg_validation_mode_if()
740
- self.update_unmatched_mode_if()
741
- self.update_data_from_preceding_if()
742
- self.update_expected_files_if()
743
- self.update_transfer_mode_if()
633
+ self.modes.update()
634
+ # self.update_arg_validation_mode_if()
744
635
 
745
636
  # =====================
746
637
 
@@ -766,11 +657,11 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
766
657
 
767
658
  @property
768
659
  def logic_mode(self) -> str:
769
- return "AND" if self.AND else "OR"
660
+ return self.metadata.get("logic-mode")
770
661
 
771
662
  @property
772
663
  def return_mode(self) -> str:
773
- return self.metadata.get("return-mode")
664
+ return self.modes.get("return-mode")
774
665
 
775
666
  @property
776
667
  def explain_mode(self) -> str:
@@ -788,49 +679,9 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
788
679
 
789
680
  @property
790
681
  def transfers(self) -> list[tuple[str, str]]:
791
- return self._transfers
792
-
793
- def update_transfer_mode_if(self) -> None:
794
- m = self.transfer_mode
795
- if m is not None:
796
- self._transfers = []
797
- for t in m.split(","):
798
- i = t.find(">")
799
- if i == -1:
800
- raise InputException(
801
- "Transfer mode directive must be in the form file > location"
802
- )
803
- file = t[0:i].strip()
804
- location = t[i + 1 :].strip()
805
- self._transfers.append((file, location))
806
-
807
- def update_expected_files_if(self) -> None:
808
- fm = self.files_mode
809
- if fm is None:
810
- return []
811
- fs = [s for s in fm.split(",")]
812
- _ = []
813
- for s in fs:
814
- s = s.strip()
815
- if s not in ["data", "unmatched", "vars", "errors", "meta", "printouts"]:
816
- self.logger.warning(
817
- "Unknown file-mode token %s. Mode tokens may be separated by , and will be trimmed.",
818
- s,
819
- )
820
- continue
821
- _.append(s)
822
- self.all_expected_files = _
823
-
824
- def update_data_from_preceding_if(self) -> None:
825
- if self.metadata and "source-mode" in self.metadata:
826
- dfp = self.metadata["source-mode"]
827
- self.data_from_preceding = dfp == "preceding"
828
- else:
829
- self.data_from_preceding = False
830
-
831
- def update_unmatched_mode_if(self) -> None:
832
- self.set_unmatched_availability()
682
+ return self.modes.transfer_mode.transfers
833
683
 
684
+ """
834
685
  def update_arg_validation_mode_if(self) -> None:
835
686
  if self.metadata and "validation-mode" in self.metadata:
836
687
  # sets arg validation reporting. one or more or none of:
@@ -845,83 +696,15 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
845
696
  "Setting 'validation-mode': %s",
846
697
  self.metadata["validation-mode"],
847
698
  )
848
-
849
- def update_run_mode_if(self) -> None:
850
- if self.metadata and "run-mode" in self.metadata:
851
- if f"{self.metadata['run-mode']}".strip() == "no-run":
852
- self.will_run = False
853
- elif f"{self.metadata['run-mode']}".strip() == "run":
854
- self.will_run = True
855
- else:
856
- self.logger.warning(
857
- "Incorrect metadata field value 'run-mode': %s",
858
- self.metadata["run-mode"],
859
- )
860
-
861
- def update_logic_mode_if(self) -> None:
862
- if self.metadata and "logic-mode" in self.metadata:
863
- if f"{self.metadata['logic-mode']}".strip() == "AND":
864
- self.AND = True
865
- elif f"{self.metadata['logic-mode']}".strip() == "OR":
866
- self.AND = False
867
- else:
868
- self.logger.warning(
869
- "Incorrect metadata field value 'logic-mode': %s",
870
- self.metadata["logic-mode"],
871
- )
872
-
873
- def update_match_mode_if(self) -> None:
874
- if "return-mode" in self.metadata:
875
- if f"{self.metadata['return-mode']}".strip() == "matches":
876
- self.collect_when_not_matched = False
877
- elif f"{self.metadata['return-mode']}".strip() == "no-matches":
878
- self.collect_when_not_matched = True
879
- else:
880
- self.logger.warning(
881
- "Incorrect metadata field value 'return-mode': %s",
882
- self.metadata["return-mode"],
883
- )
884
-
885
- def update_explain_mode_if(self) -> None:
886
- if "explain-mode" in self.metadata:
887
- if f"{self.metadata['explain-mode']}".strip() == "no-explain":
888
- self._explain = False
889
- elif f"{self.metadata['explain-mode']}".strip() == "explain":
890
- self._explain = True
891
- else:
892
- self._explain = False
893
-
894
- def update_print_mode_if(self) -> None:
895
- if "print-mode" in self.metadata:
896
- if f"{self.metadata['print-mode']}".strip() == "no-default":
897
- remove = -1
898
- for i, p in enumerate(self.printers):
899
- if isinstance(p, StdOutPrinter):
900
- remove = i
901
- break
902
- if remove >= 0:
903
- del self.printers[remove]
904
- elif f"{self.metadata['print-mode']}".strip() == "default":
905
- done = False
906
- for i, p in enumerate(self.printers):
907
- if isinstance(p, StdOutPrinter):
908
- done = True
909
- break
910
- if not done:
911
- self.printers.append(StdOutPrinter())
912
- else:
913
- self.logger.warning(
914
- "Incorrect metadata field value 'print-mode': %s",
915
- self.metadata["print-mode"],
916
- )
699
+ """
917
700
 
918
701
  @property
919
702
  def all_expected_files(self) -> list[str]:
920
- return self._all_expected_files
703
+ return self.modes.files_mode.all_expected_files
921
704
 
922
705
  @all_expected_files.setter
923
706
  def all_expected_files(self, efs: list[str]) -> None:
924
- self._all_expected_files = efs
707
+ self.modes.files_mode.all_expected_files = efs
925
708
 
926
709
  def _pick_named_path(self, name, *, specific=None) -> str:
927
710
  if not self.csvpaths:
@@ -1494,7 +1277,7 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
1494
1277
  self.matcher = Matcher(
1495
1278
  csvpath=self, data=self.match, line=line, headers=self.headers, myid=h
1496
1279
  )
1497
- self.matcher.AND = self._AND
1280
+ self.matcher.AND = self.AND
1498
1281
  else:
1499
1282
  self.logger.debug("Resetting and reloading matcher")
1500
1283
  self.matcher.reset()
@@ -583,7 +583,6 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
583
583
  raise InputException(
584
584
  f"Pathsname '{pathsname}' must name a list of csvpaths"
585
585
  )
586
-
587
586
  csvpath_objects = self._load_csvpath_objects(
588
587
  paths=paths,
589
588
  named_file=fn,
@@ -10,6 +10,7 @@ from csvpath.matching.productions.equality import Equality
10
10
  from csvpath.matching.util.expression_utility import ExpressionUtility
11
11
  from ..util.exceptions import ChildrenException, ChildrenValidationException
12
12
  from csvpath.util.config_exception import ConfigurationException
13
+ from csvpath.util.error import ErrorCommsManager
13
14
 
14
15
  # from csvpath.util.log_utility import LogUtility
15
16
  # LogUtility.log_brief_trace()
@@ -461,4 +462,15 @@ class Args:
461
462
  pm = f"Wrong value in match component {ei}: {pm}"
462
463
  lpm = f"{pm}: {mismatches}"
463
464
  self._matchable.matcher.csvpath.logger.error(lpm)
464
- self._matchable.raiseChildrenException(pm)
465
+ if (
466
+ not ErrorCommsManager(
467
+ csvpath=self._matchable.matcher.csvpath
468
+ ).do_i_raise()
469
+ and self._matchable.matcher.csvpath.match_validation_errors
470
+ ):
471
+ # we match on errors so we have to handle and keep going as best we can.
472
+ pm = self._matchable.decorate_error_message(pm)
473
+ e = ChildrenException(pm)
474
+ self._matchable.handle_error(e)
475
+ else:
476
+ self._matchable.raiseChildrenException(pm)
@@ -200,9 +200,9 @@ class Function(Matchable):
200
200
  if (
201
201
  self.args
202
202
  and self.args.args_match is False
203
- and self.matcher.csvpath._match_validation_errors is not None
203
+ and self.matcher.csvpath.match_validation_errors is not None
204
204
  ):
205
- self.match = self.matcher.csvpath._match_validation_errors
205
+ self.match = self.matcher.csvpath.match_validation_errors
206
206
  else:
207
207
  self._decide_match(skip=skip)
208
208
  self.matcher.csvpath.logger.debug(
@@ -72,9 +72,14 @@ class Expression(Matchable):
72
72
  # if we don't raise the exception we decline the match and
73
73
  # continue
74
74
  #
75
- self.match = False
75
+ # is this False needed?
76
+ # self.match = False
76
77
  if len(self.errors) > 0:
77
- self.match = False
78
+ #
79
+ # if we are matching on errors we want to not just fail lines
80
+ #
81
+ if not self.matcher.csvpath.match_validation_errors:
82
+ self.match = False
78
83
  return self.match
79
84
 
80
85
  def reset(self) -> None:
@@ -0,0 +1,41 @@
1
+ class ExplainMode:
2
+ EXPLAIN = "explain"
3
+ NO_EXPLAIN = "no-explain"
4
+ MODE = "explain-mode"
5
+
6
+ def __init__(self, controller):
7
+ self.controller = controller
8
+ #
9
+ # explain-mode: explain
10
+ # turns on capturing match reasoning and dumps the captured decisions to INFO
11
+ # at the end of a match. the reasoning is already present in the DEBUG but it
12
+ # is harder to see amid all the noise. we don't want to dump explainations
13
+ # all the time tho because it is very expensive -- potentially 25% worse
14
+ # performance. the explainations could be improved. atm this is an experimental
15
+ # feature.
16
+ #
17
+ self._explain: bool = None
18
+
19
+ def update(self) -> None:
20
+ self._explain = None
21
+ self.value
22
+
23
+ @property
24
+ def value(self) -> bool:
25
+ if self._explain is None:
26
+ em = self.controller.get(ExplainMode.MODE)
27
+ if em is None:
28
+ self._explain = False
29
+ else:
30
+ self._explain = em.strip() == ExplainMode.EXPLAIN
31
+ return self._explain
32
+
33
+ @value.setter
34
+ def value(self, em: bool) -> None:
35
+ self.controller.set(
36
+ ExplainMode.MODE,
37
+ ExplainMode.NO_EXPLAIN
38
+ if em is False or em is None
39
+ else ExplainMode.EXPLAIN,
40
+ )
41
+ self._explain = em