csvpath 0.0.480__tar.gz → 0.0.481__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 (214) hide show
  1. {csvpath-0.0.480 → csvpath-0.0.481}/PKG-INFO +1 -1
  2. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/csvpath.py +76 -28
  3. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/args.py +61 -16
  4. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/boolean/all.py +0 -2
  5. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/boolean/any.py +1 -0
  6. csvpath-0.0.481/csvpath/matching/functions/boolean/boolean.py +31 -0
  7. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/boolean/empty.py +21 -14
  8. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/boolean/inf.py +5 -3
  9. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/boolean/yes.py +2 -1
  10. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/counting/count.py +13 -0
  11. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/counting/increment.py +3 -3
  12. csvpath-0.0.481/csvpath/matching/functions/function.py +207 -0
  13. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/function_factory.py +10 -2
  14. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/headers/end.py +3 -2
  15. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/headers/header_name.py +4 -1
  16. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/lines/dups.py +7 -7
  17. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/lines/first_line.py +4 -2
  18. {csvpath-0.0.480/csvpath/matching/functions/misc → csvpath-0.0.481/csvpath/matching/functions/math}/intf.py +17 -8
  19. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/misc/importf.py +2 -0
  20. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/misc/nonef.py +18 -0
  21. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/misc/random.py +5 -3
  22. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/stats/minf.py +2 -2
  23. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/stats/percent.py +2 -0
  24. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/stats/stdev.py +5 -2
  25. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/strings/regex.py +1 -0
  26. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/strings/string.py +2 -2
  27. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/strings/substring.py +5 -3
  28. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/validity/failed.py +1 -0
  29. csvpath-0.0.481/csvpath/matching/functions/validity/line.py +88 -0
  30. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/matcher.py +9 -0
  31. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/productions/expression.py +26 -0
  32. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/productions/header.py +2 -0
  33. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/productions/matchable.py +30 -1
  34. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/productions/qualified.py +1 -1
  35. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/productions/term.py +8 -0
  36. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/util/exceptions.py +8 -0
  37. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/util/expression_utility.py +23 -3
  38. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/util/error.py +97 -9
  39. {csvpath-0.0.480 → csvpath-0.0.481}/docs/comments.md +10 -5
  40. {csvpath-0.0.480 → csvpath-0.0.481}/pyproject.toml +1 -1
  41. csvpath-0.0.480/csvpath/matching/functions/function.py +0 -145
  42. {csvpath-0.0.480 → csvpath-0.0.481}/LICENSE +0 -0
  43. {csvpath-0.0.480 → csvpath-0.0.481}/README.md +0 -0
  44. {csvpath-0.0.480 → csvpath-0.0.481}/config/config.ini +0 -0
  45. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/__init__.py +0 -0
  46. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/csvpaths.py +0 -0
  47. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/managers/__init__.py +0 -0
  48. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/managers/csvpaths_manager.py +0 -0
  49. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/managers/file_manager.py +0 -0
  50. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/managers/result.py +0 -0
  51. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/managers/results_manager.py +0 -0
  52. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/__init__.py +0 -0
  53. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/__init__.py +0 -0
  54. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/boolean/andf.py +0 -0
  55. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/boolean/between.py +0 -0
  56. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/boolean/exists.py +0 -0
  57. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/boolean/no.py +0 -0
  58. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/boolean/notf.py +0 -0
  59. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/boolean/orf.py +0 -0
  60. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/counting/count_headers.py +0 -0
  61. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/counting/count_lines.py +0 -0
  62. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/counting/count_scans.py +0 -0
  63. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/counting/counter.py +0 -0
  64. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/counting/every.py +0 -0
  65. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/counting/has_matches.py +0 -0
  66. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/counting/tally.py +0 -0
  67. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/counting/total_lines.py +0 -0
  68. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/dates/datef.py +0 -0
  69. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/dates/now.py +0 -0
  70. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/function_finder.py +0 -0
  71. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/function_focus.py +0 -0
  72. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/headers/append.py +0 -0
  73. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/headers/collect.py +0 -0
  74. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/headers/empty_stack.py +0 -0
  75. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
  76. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/headers/headers.py +0 -0
  77. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/headers/mismatch.py +0 -0
  78. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/headers/replace.py +0 -0
  79. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/headers/reset_headers.py +0 -0
  80. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/lines/advance.py +0 -0
  81. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/lines/after_blank.py +0 -0
  82. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/lines/first.py +0 -0
  83. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/lines/last.py +0 -0
  84. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/lines/stop.py +0 -0
  85. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/math/above.py +0 -0
  86. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/math/add.py +0 -0
  87. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/math/divide.py +0 -0
  88. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/math/equals.py +0 -0
  89. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/math/mod.py +0 -0
  90. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/math/multiply.py +0 -0
  91. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/math/round.py +0 -0
  92. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/math/subtotal.py +0 -0
  93. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/math/subtract.py +0 -0
  94. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/math/sum.py +0 -0
  95. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/print/jinjaf.py +0 -0
  96. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/print/print_line.py +0 -0
  97. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/print/print_queue.py +0 -0
  98. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/print/printf.py +0 -0
  99. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/print/table.py +0 -0
  100. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  101. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/strings/concat.py +0 -0
  102. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/strings/length.py +0 -0
  103. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/strings/lower.py +0 -0
  104. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/strings/metaphone.py +0 -0
  105. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/strings/starts_with.py +0 -0
  106. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/strings/strip.py +0 -0
  107. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/strings/upper.py +0 -0
  108. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/testing/debug.py +0 -0
  109. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/validity/fail.py +0 -0
  110. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/variables/get.py +0 -0
  111. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/variables/pushpop.py +0 -0
  112. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/variables/put.py +0 -0
  113. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/variables/track.py +0 -0
  114. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/functions/variables/variables.py +0 -0
  115. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/lark_parser.py +0 -0
  116. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/lark_transformer.py +0 -0
  117. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/productions/__init__.py +0 -0
  118. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/productions/equality.py +0 -0
  119. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/productions/reference.py +0 -0
  120. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/productions/variable.py +0 -0
  121. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/util/expression_encoder.py +0 -0
  122. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/util/lark_print_parser.py +0 -0
  123. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/matching/util/print_parser.py +0 -0
  124. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/scanning/__init__.py +0 -0
  125. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/scanning/exceptions.py +0 -0
  126. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/scanning/parser.out +0 -0
  127. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/scanning/parsetab.py +0 -0
  128. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/scanning/scanner.py +0 -0
  129. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/scanning/scanning_lexer.py +0 -0
  130. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/util/cache.py +0 -0
  131. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/util/config.py +0 -0
  132. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/util/config_exception.py +0 -0
  133. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/util/exceptions.py +0 -0
  134. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/util/last_line_stats.py +0 -0
  135. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/util/line_counter.py +0 -0
  136. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/util/line_monitor.py +0 -0
  137. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/util/log_utility.py +0 -0
  138. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/util/metadata_parser.py +0 -0
  139. {csvpath-0.0.480 → csvpath-0.0.481}/csvpath/util/printer.py +0 -0
  140. {csvpath-0.0.480 → csvpath-0.0.481}/docs/asbool.md +0 -0
  141. {csvpath-0.0.480 → csvpath-0.0.481}/docs/assignment.md +0 -0
  142. {csvpath-0.0.480 → csvpath-0.0.481}/docs/config.md +0 -0
  143. {csvpath-0.0.480 → csvpath-0.0.481}/docs/examples.md +0 -0
  144. {csvpath-0.0.480 → csvpath-0.0.481}/docs/files.md +0 -0
  145. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/above.md +0 -0
  146. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/advance.md +0 -0
  147. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/after_blank.md +0 -0
  148. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/all.md +0 -0
  149. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/andor.md +0 -0
  150. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/any.md +0 -0
  151. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/average.md +0 -0
  152. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/between.md +0 -0
  153. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/collect.md +0 -0
  154. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/correlate.md +0 -0
  155. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/count.md +0 -0
  156. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/count_headers.md +0 -0
  157. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/counter.md +0 -0
  158. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/date.md +0 -0
  159. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/empty.md +0 -0
  160. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/empty_stack.md +0 -0
  161. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/end.md +0 -0
  162. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/every.md +0 -0
  163. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/fail.md +0 -0
  164. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/first.md +0 -0
  165. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/get.md +0 -0
  166. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/has_dups.md +0 -0
  167. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/has_matches.md +0 -0
  168. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/header.md +0 -0
  169. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/header_name.md +0 -0
  170. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/header_names_mismatch.md +0 -0
  171. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/implementing_functions.md +0 -0
  172. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/import.md +0 -0
  173. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/in.md +0 -0
  174. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/increment.md +0 -0
  175. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/jinja.md +0 -0
  176. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/last.md +0 -0
  177. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/line_number.md +0 -0
  178. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/max.md +0 -0
  179. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/metaphone.md +0 -0
  180. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/mismatch.md +0 -0
  181. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/no.md +0 -0
  182. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/not.md +0 -0
  183. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/now.md +0 -0
  184. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/percent_unique.md +0 -0
  185. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/pop.md +0 -0
  186. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/print.md +0 -0
  187. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/print_line.md +0 -0
  188. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/print_queue.md +0 -0
  189. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/random.md +0 -0
  190. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/regex.md +0 -0
  191. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/replace.md +0 -0
  192. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/reset_headers.md +0 -0
  193. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/stdev.md +0 -0
  194. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/stop.md +0 -0
  195. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/string_functions.md +0 -0
  196. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/subtotal.md +0 -0
  197. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/subtract.md +0 -0
  198. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/sum.md +0 -0
  199. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/tally.md +0 -0
  200. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/total_lines.md +0 -0
  201. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/track.md +0 -0
  202. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/variables.md +0 -0
  203. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions/variables_and_headers.md +0 -0
  204. {csvpath-0.0.480 → csvpath-0.0.481}/docs/functions.md +0 -0
  205. {csvpath-0.0.480 → csvpath-0.0.481}/docs/grammar.md +0 -0
  206. {csvpath-0.0.480 → csvpath-0.0.481}/docs/headers.md +0 -0
  207. {csvpath-0.0.480 → csvpath-0.0.481}/docs/images/logo-wordmark-white-on-black-trimmed-padded.png +0 -0
  208. {csvpath-0.0.480 → csvpath-0.0.481}/docs/images/logo-wordmark-white-trimmed.png +0 -0
  209. {csvpath-0.0.480 → csvpath-0.0.481}/docs/paths.md +0 -0
  210. {csvpath-0.0.480 → csvpath-0.0.481}/docs/printing.md +0 -0
  211. {csvpath-0.0.480 → csvpath-0.0.481}/docs/qualifiers.md +0 -0
  212. {csvpath-0.0.480 → csvpath-0.0.481}/docs/references.md +0 -0
  213. {csvpath-0.0.480 → csvpath-0.0.481}/docs/terms.md +0 -0
  214. {csvpath-0.0.480 → csvpath-0.0.481}/docs/variables.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: csvpath
3
- Version: 0.0.480
3
+ Version: 0.0.481
4
4
  Summary: A declarative language for data extraction and validation of CSV files
5
5
  Author: David Kershaw
6
6
  Author-email: dk107dk@hotmail.com
@@ -172,7 +172,6 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
172
172
  #
173
173
  self.stopped = False
174
174
  self._advance = 0
175
-
176
175
  #
177
176
  # set by fail()
178
177
  #
@@ -249,9 +248,12 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
249
248
  # use match component rules and exceptions to generate validation
250
249
  # info. but long term this capability may go away.
251
250
  #
252
- self._log_validation_errors = False
251
+ self._log_validation_errors = True
253
252
  self._print_validation_errors = True
254
- self._raise_validation_errors = True
253
+ self._raise_validation_errors = None
254
+ self._match_validation_errors = None
255
+ self._stop_on_validation_errors = None
256
+ self._fail_on_validation_errors = None
255
257
  #
256
258
  # there are two logger components one for CsvPath and one for CsvPaths.
257
259
  # the default levels are set in config.ini. to change the levels pass LogUtility
@@ -372,28 +374,70 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
372
374
  self._errors = []
373
375
  self._errors.append(error)
374
376
 
375
- def report_validation_errors(self, msg: str) -> None:
376
- if self.print_validation_errors:
377
- self.print(msg)
378
- elif self.log_validation_errors:
379
- self.logger.warning(msg)
380
- #
381
- # the args class will do the raise if it is told to by the prop
382
- #
383
-
377
+ #
378
+ # validation error handling overrides the error policy in config. this
379
+ # is because the validation handling is:
380
+ # - different. it is built-in. it deals with programmatic decisions
381
+ # about how functions work and is the basis for structural (schema)
382
+ # validation.
383
+ # - set on a per csvpath basis in comments
384
+ #
385
+ # by default, validation errors do not impact matching. they are print
386
+ # and raise only. however, you can set them to raise or match/not-match
387
+ # and/or suppress printing.
388
+ #
384
389
  def set_validation_error_handling(self, veh) -> None:
385
- if veh and veh.find("print") > -1:
386
- self._print_validation_errors = True
387
- else:
390
+ # print prints to the Printer(s), not std.out. atm, no
391
+ # customization of messages is possible, so there is likely
392
+ # to be stylistic mismatch with other output.
393
+ if veh and veh.find("no-print") > -1:
388
394
  self._print_validation_errors = False
389
- if veh and veh.find("log") > -1:
390
- self._log_validation_errors = True
395
+ elif veh and veh.find("print") > -1:
396
+ self._print_validation_errors = True
391
397
  else:
392
- self._log_validation_errors = False
393
- if veh and veh.find("raise") > -1:
398
+ self._print_validation_errors = None
399
+ #
400
+ if veh and veh.find("no-raise") > -1:
401
+ self._raise_validation_errors = False
402
+ elif veh and veh.find("raise") > -1:
394
403
  self._raise_validation_errors = True
395
404
  else:
396
- self._raise_validation_errors = False
405
+ self._raise_validation_errors = None
406
+ #
407
+ # match, no-match, and None do:
408
+ # match: return True on error
409
+ # no-match: return False on error
410
+ # None: default behavior: default_match() or result of matches()
411
+ if veh and veh.find("no-match") > -1:
412
+ self._match_validation_errors = False
413
+ elif veh and veh.find("match") > -1:
414
+ self._match_validation_errors = True
415
+ else:
416
+ self._match_validation_errors = None
417
+ #
418
+ # also stop and fail to match the config
419
+ #
420
+ if veh and veh.find("no-stop") > -1:
421
+ self._stop_on_validation_errors = False
422
+ elif veh and veh.find("stop") > -1:
423
+ self._stop_on_validation_errors = True
424
+ else:
425
+ self._stop_on_validation_errors = None
426
+ #
427
+ if veh and veh.find("no-fail") > -1:
428
+ self._fail_on_validation_errors = False
429
+ elif veh and veh.find("fail") > -1:
430
+ self._fail_on_validation_errors = True
431
+ else:
432
+ self._fail_on_validation_errors = None
433
+
434
+ @property
435
+ def stop_on_validation_errors(self) -> bool:
436
+ return self._stop_on_validation_errors
437
+
438
+ @property
439
+ def fail_on_validation_errors(self) -> bool:
440
+ return self._fail_on_validation_errors
397
441
 
398
442
  @property
399
443
  def print_validation_errors(self) -> bool:
@@ -407,6 +451,10 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
407
451
  def raise_validation_errors(self) -> bool:
408
452
  return self._raise_validation_errors
409
453
 
454
+ @property
455
+ def match_validation_errors(self) -> bool:
456
+ return self._match_validation_errors
457
+
410
458
  def add_printer(self, printer) -> None: # pylint: disable=C0116
411
459
  if printer not in self.printers:
412
460
  self.printers.append(printer)
@@ -522,8 +570,8 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
522
570
  # settings:
523
571
  # - logic-mode: AND | OR
524
572
  # - match-mode: matches | no-matches
525
- # - print-mode: default-off | default-on
526
- # - arg-validation-mode: print | log | raise | quiet
573
+ # - print-mode: default | no-default
574
+ # - validation-mode: (no-)print | log | (no-)raise | quiet | (no-)match
527
575
  #
528
576
  self.update_logic_mode_if()
529
577
  self.update_match_mode_if()
@@ -531,18 +579,18 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
531
579
  self.update_arg_validation_mode_if()
532
580
 
533
581
  def update_arg_validation_mode_if(self) -> None:
534
- if self.metadata and "arg-validation-mode" in self.metadata:
582
+ if self.metadata and "validation-mode" in self.metadata:
535
583
  # sets arg validation reporting. one or more or none of:
536
584
  # - print
537
585
  # - log
538
586
  # - raise
539
587
  #
540
- validation_mode = f"{self.metadata['arg-validation-mode']}".strip()
588
+ validation_mode = f"{self.metadata['validation-mode']}".strip()
541
589
  if validation_mode:
542
590
  self.set_validation_error_handling(validation_mode)
543
591
  self.logger.info(
544
- "Setting 'arg-validation-mode': %s",
545
- self.metadata["arg-validation-mode"],
592
+ "Setting 'validation-mode': %s",
593
+ self.metadata["validation-mode"],
546
594
  )
547
595
 
548
596
  def update_logic_mode_if(self) -> None:
@@ -571,7 +619,7 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
571
619
 
572
620
  def update_print_mode_if(self) -> None:
573
621
  if "print-mode" in self.metadata:
574
- if f"{self.metadata['print-mode']}".strip() == "default-off":
622
+ if f"{self.metadata['print-mode']}".strip() == "no-default":
575
623
  remove = -1
576
624
  for i, p in enumerate(self.printers):
577
625
  if isinstance(p, StdOutPrinter):
@@ -579,7 +627,7 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
579
627
  break
580
628
  if remove >= 0:
581
629
  del self.printers[remove]
582
- elif f"{self.metadata['print-mode']}".strip() == "default-on":
630
+ elif f"{self.metadata['print-mode']}".strip() == "default":
583
631
  done = False
584
632
  for i, p in enumerate(self.printers):
585
633
  if isinstance(p, StdOutPrinter):
@@ -8,7 +8,7 @@ from csvpath.matching.functions.function import Function
8
8
  from csvpath.matching.productions.reference import Reference
9
9
  from csvpath.matching.productions.equality import Equality
10
10
  from csvpath.matching.util.expression_utility import ExpressionUtility
11
- from ..util.exceptions import ChildrenException
11
+ from ..util.exceptions import ChildrenException, ChildrenValidationException
12
12
  from csvpath.util.config_exception import ConfigurationException
13
13
 
14
14
  # from csvpath.util.log_utility import LogUtility
@@ -194,7 +194,7 @@ class ArgSet:
194
194
  self._args = args
195
195
  self.max_length = len(self._args)
196
196
 
197
- def validate(self, siblings: List[Matchable]) -> None:
197
+ def validate_structure(self, siblings: List[Matchable]) -> None:
198
198
  b = self._validate_length(siblings)
199
199
  if b is False:
200
200
  return False
@@ -235,11 +235,44 @@ class ArgSet:
235
235
  break
236
236
  arg = self._args[i]
237
237
  #
238
+ # in principle we would want to avoid any case where we don't have an arg
239
+ # or the arg's actuals are none
240
+ # -- and ---
241
+ # if the arg exists but has [] elements treat it as a requirement that no
242
+ # optional values should be passed in on that arg in that particular use
243
+ # case.
244
+ #
245
+ # however, that approach a) breaks stuff i'd like to not break atm, and b)
246
+ # the only use case today (in empty()) is obviated by a second arg set
247
+ # that would in essence override the [] actuals in the first argset. so
248
+ # we have no case. given that, letting this idea go until it resurfaces
249
+ # in a more practical way.
250
+ #
251
+ # exp!
252
+ self._parent._csvpath.logger.debug("Checking arg[%i]: %s", i, arg)
253
+ """
254
+ if ( not arg or arg.actuals is None ):
255
+ if self._parent and self._parent._csvpath:
256
+ self._parent._csvpath.logger.debug(
257
+ "No expectations to validate actual values against in argset {self.argset_number}"
258
+ )
259
+ found = True
260
+ break
261
+ if len(arg.actuals) == 0 and len(actuals) > 0:
262
+ if self._parent and self._parent._csvpath:
263
+ self._parent._csvpath.logger.debug(
264
+ "No optional args should be presented in {self.argset_number}"
265
+ )
266
+ found = False
267
+ break
268
+ """
269
+ # end exp
270
+ #
271
+ # start orig w/orig comment:
238
272
  # we can't validate arg if we have no actuals expectations.
239
273
  # this is a way to disable line-by-line validation -- just
240
274
  # remove the expectations from the args
241
275
  #
242
- self._parent._csvpath.logger.debug("Checking arg[%i]: %s", i, arg)
243
276
  if not arg or not arg.actuals or len(arg.actuals) == 0:
244
277
  if self._parent and self._parent._csvpath:
245
278
  self._parent._csvpath.logger.debug(
@@ -247,6 +280,9 @@ class ArgSet:
247
280
  )
248
281
  found = True
249
282
  break
283
+ #
284
+ # end orig
285
+ #
250
286
  if Any in arg.actuals:
251
287
  self._parent._csvpath.logger.debug("Found Any so we're done")
252
288
  found = True
@@ -309,6 +345,21 @@ class Args:
309
345
  # child.to_value(skips=skips) to result in an int, did it?
310
346
  #
311
347
  self.matched = False
348
+ self._args_match = True
349
+
350
+ def reset(self) -> None:
351
+ self._args_match = True
352
+ self.matched = False
353
+
354
+ @property
355
+ def args_match(self) -> bool | None:
356
+ """Only used in the runtime actuals matching. speaks
357
+ to if the line should be considered matched or not.
358
+ None is default
359
+ True means matching succeeded
360
+ False means matching failed
361
+ """
362
+ return self._args_match
312
363
 
313
364
  def argset(self, maxlength: int = -1) -> ArgSet:
314
365
  a = ArgSet(maxlength, parent=self)
@@ -339,10 +390,10 @@ class Args:
339
390
  #
340
391
  good = False
341
392
  for aset in self._argsets:
342
- if aset.validate(siblings):
393
+ if aset.validate_structure(siblings):
343
394
  good = True
344
395
  if not good:
345
- _ = " at {self.matchable.my_chain}" if self.matchable else ""
396
+ _ = f" at {self.matchable.my_chain}" if self.matchable else ""
346
397
  msg = f"{self._csvpath_id()} Incorrectly written{_}. Wrong type or number of args."
347
398
  raise ChildrenException(msg)
348
399
  self.validated = True
@@ -390,19 +441,13 @@ class Args:
390
441
 
391
442
  def handle_errors_if(self, mismatch_count, mismatches):
392
443
  if mismatch_count == len(self._argsets):
444
+ self._args_match = False
393
445
  pm = f"mismatch in {self.matchable.my_chain}: {mismatches}"
394
446
  # when would we not have a csvpath?
395
447
  pln = (
396
448
  self._csvpath.line_monitor.physical_line_number if self._csvpath else 0
397
449
  )
398
- csvpathid = self._csvpath_id()
399
- pm = f"{csvpathid} Wrong value(s) at line {pln}: {pm}"
400
- # self._csvpath.report_validation_errors(pm)
401
- if self._csvpath is None or self._csvpath.raise_validation_errors:
402
- raise ChildrenException(pm)
403
- # we print in-run validation errors as part of the raise handle,
404
- # so this is a bit extra. We can suppress the exceptions completely
405
- # but still print args validation errors. not sure that is anything
406
- # more than a deep corner case. defering removing it.
407
- if self._csvpath and self._csvpath.print_validation_errors:
408
- self._csvpath.report_validation_errors(pm)
450
+ csvpathid = f"{self._csvpath_id()} " if self._csvpath_id() else ""
451
+ ei = ExpressionUtility.get_my_expressions_index(self._matchable)
452
+ pm = f"{csvpathid}Wrong value in match component {ei} at line {pln}: {pm}"
453
+ raise ChildrenValidationException(pm)
@@ -50,8 +50,6 @@ class All(MatchDecider):
50
50
  self.all_exist()
51
51
  elif isinstance(child, Variables):
52
52
  self.all_variables()
53
- else:
54
- raise ChildrenException("Child cannot be {child}")
55
53
 
56
54
  def all_variables(self) -> None: # pylint: disable=C0116
57
55
  # default is True in case no vars
@@ -114,6 +114,7 @@ class Any(MatchDecider):
114
114
  break
115
115
  else:
116
116
  c = self.children[0].left
117
+ # definitely a structure / children exception
117
118
  raise ChildrenException(
118
119
  f"Left child of any() must be header or variable, not {c}"
119
120
  )
@@ -0,0 +1,31 @@
1
+ # pylint: disable=C0114
2
+ from csvpath.matching.util.expression_utility import ExpressionUtility
3
+ from csvpath.matching.util.exceptions import DataException
4
+ from csvpath.matching.productions import Term, Variable, Header
5
+ from ..function import Function
6
+ from ..function_focus import ValueProducer
7
+ from ..args import Args
8
+
9
+
10
+ class Boolean(ValueProducer):
11
+ def check_valid(self) -> None:
12
+ self.args = Args(matchable=self)
13
+ a = self.args.argset(1)
14
+ a.arg(types=[Term, Variable, Header, Function], actuals=[None, bool])
15
+ self.args.validate(self.siblings())
16
+ super().check_valid()
17
+
18
+ def _produce_value(self, skip=None) -> None:
19
+ i = self._value_one(skip=skip)
20
+ if i is None:
21
+ self.value = None
22
+ else:
23
+ self.value = ExpressionUtility.to_bool(i)
24
+
25
+ def _decide_match(self, skip=None) -> None:
26
+ # we need to make sure a value is produced so that we see
27
+ # any errors. when we stand alone we're just checking our
28
+ # boolean-iness. when we're producing a value we're checking
29
+ # boolean-iness and casting and raising errors.
30
+ self.to_value(skip=skip)
31
+ self.match = self.default_match() # pragma: no cover
@@ -1,9 +1,12 @@
1
1
  # pylint: disable=C0114
2
+ from typing import Any
2
3
  from ..function_focus import MatchDecider
3
4
  from csvpath.matching.productions import Header, Variable, Equality, Term
4
5
  from csvpath.matching.util.exceptions import ChildrenException
5
6
  from ..headers.headers import Headers
6
7
  from csvpath.matching.util.expression_utility import ExpressionUtility
8
+ from csvpath.matching.functions.args import Args
9
+ from csvpath.matching.functions.function import Function
7
10
 
8
11
 
9
12
  class Empty(MatchDecider):
@@ -12,22 +15,26 @@ class Empty(MatchDecider):
12
15
  if you pass it headers() it checks for all headers being empty."""
13
16
 
14
17
  def check_valid(self) -> None:
15
- if len(self.children) == 0:
16
- raise ChildrenException("empty() must have at least 1 argument")
17
- elif isinstance(self.children[0], Headers):
18
- if len(self.children) != 1: # pragma: no cover
19
- raise ChildrenException(
20
- "If empty() has a headers() argument it can only have 1 argument"
21
- )
22
- children = self.children
23
- if isinstance(self.children[0], Equality):
24
- children = self.children[0].commas_to_list()
25
- self._validate(children)
18
+ self.args = Args(matchable=self)
19
+ #
20
+ # we'd like to disallow headers from taking a value in this case, but we
21
+ # cannot because headers is a function and will be covered by the second
22
+ # argset, so we handle that in a helper validation function.
23
+ #
24
+ a = self.args.argset(1)
25
+ a.arg(types=[Headers])
26
+ a = self.args.argset()
27
+ a.arg(types=[Variable, Function, Header], actuals=[None, Any])
28
+ self.args.validate(self.siblings())
29
+ #
30
+ self._validate()
26
31
  super().check_valid() # pragma: no cover
27
32
 
28
- def _validate(self, children):
29
- for s in children:
30
- if isinstance(s, Headers) and len(children) > 1:
33
+ def _validate(self):
34
+ sibs = self.siblings()
35
+ for s in sibs:
36
+ # both definitely structure / children exceptions
37
+ if isinstance(s, Headers) and len(sibs) > 1:
31
38
  raise ChildrenException(
32
39
  "If empty() has a headers() argument it can only have 1 argument"
33
40
  )
@@ -28,8 +28,9 @@ class In(MatchDecider):
28
28
  for s in siblings[1:]:
29
29
  v = s.to_value(skip=skip)
30
30
  if isinstance(s, Term):
31
- vs = f"{v}".split("|")
32
- inf += vs
31
+ v = f"{v}".strip()
32
+ nvs = [_.strip() for _ in v.split("|")]
33
+ inf += nvs
33
34
  else:
34
35
  # tuple would mean vars were frozen. this would not be
35
36
  # surprising from a reference
@@ -41,4 +42,5 @@ class In(MatchDecider):
41
42
  inf.append(k)
42
43
  else:
43
44
  inf.append(v)
44
- self.match = t in inf
45
+ ret = t in inf
46
+ self.match = ret
@@ -8,7 +8,8 @@ class Yes(ValueProducer):
8
8
  """returns True"""
9
9
 
10
10
  def check_valid(self) -> None:
11
- Args().validate(self.siblings())
11
+ self.args = Args(matchable=self)
12
+ self.args.validate(self.siblings())
12
13
  super().check_valid()
13
14
 
14
15
  def _produce_value(self, skip=None) -> None:
@@ -1,6 +1,9 @@
1
1
  # pylint: disable=C0114
2
2
  from typing import Any
3
3
  from ..function_focus import ValueProducer
4
+ from ..function import Function
5
+ from ..args import Args
6
+ from csvpath.matching.productions import Equality, Variable, Header, Term
4
7
 
5
8
 
6
9
  class Count(ValueProducer):
@@ -9,6 +12,16 @@ class Count(ValueProducer):
9
12
 
10
13
  def check_valid(self) -> None: # pylint: disable=W0246
11
14
  # note to self: no specific validity checks from way back
15
+ # these args may need work
16
+ self.args = Args(matchable=self)
17
+ a = self.args.argset(0)
18
+ a = self.args.argset()
19
+ a.arg(
20
+ types=[None, Variable, Function, Header, Term, Equality],
21
+ actuals=[None, Any],
22
+ )
23
+ self.args.validate(self.siblings())
24
+ #
12
25
  super().check_valid() # pylint: disable=W0246
13
26
  # re: W0246: Matchable handles this class's children
14
27
 
@@ -1,6 +1,6 @@
1
1
  # pylint: disable=C0114
2
2
  from typing import Any
3
- from csvpath.matching.util.exceptions import ChildrenException
3
+ from csvpath.matching.util.exceptions import DataException
4
4
  from ..function_focus import ValueProducer
5
5
  from csvpath.matching.productions import Term, Header, Variable, Equality
6
6
  from ..function import Function
@@ -26,12 +26,12 @@ class Increment(ValueProducer):
26
26
  return self._noop_value()
27
27
  tv = self.children[0].right.to_value()
28
28
  if not isinstance(tv, int):
29
- raise ChildrenException(
29
+ raise DataException(
30
30
  "increment value must be a positive int"
31
31
  ) # pragma: no cover
32
32
  tv = int(tv)
33
33
  if tv <= 0:
34
- raise ChildrenException(
34
+ raise DataException(
35
35
  "increment value must be a positive int"
36
36
  ) # pragma: no cover
37
37
  if not self.value: