csvpath 0.0.481__tar.gz → 0.0.483__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 (222) hide show
  1. {csvpath-0.0.481 → csvpath-0.0.483}/PKG-INFO +2 -3
  2. {csvpath-0.0.481 → csvpath-0.0.483}/README.md +1 -2
  3. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/csvpath.py +11 -7
  4. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/managers/results_manager.py +5 -8
  5. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/args.py +16 -9
  6. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/boolean/all.py +3 -1
  7. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/boolean/andf.py +3 -7
  8. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/boolean/any.py +3 -3
  9. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/boolean/empty.py +2 -26
  10. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/boolean/inf.py +2 -2
  11. csvpath-0.0.483/csvpath/matching/functions/boolean/orf.py +57 -0
  12. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/counting/count.py +2 -5
  13. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/counting/counter.py +5 -0
  14. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/counting/every.py +2 -2
  15. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/counting/increment.py +3 -3
  16. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/counting/tally.py +1 -7
  17. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/dates/now.py +2 -4
  18. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/function.py +5 -3
  19. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/function_factory.py +11 -10
  20. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/headers/collect.py +1 -1
  21. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/headers/end.py +1 -5
  22. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/headers/reset_headers.py +4 -2
  23. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/lines/advance.py +3 -2
  24. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/math/intf.py +62 -5
  25. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/strings/length.py +4 -1
  26. csvpath-0.0.483/csvpath/matching/functions/types/__init__.py +7 -0
  27. csvpath-0.0.483/csvpath/matching/functions/types/boolean.py +49 -0
  28. csvpath-0.0.483/csvpath/matching/functions/types/datef.py +138 -0
  29. csvpath-0.0.483/csvpath/matching/functions/types/decimal.py +92 -0
  30. {csvpath-0.0.481/csvpath/matching/functions/misc → csvpath-0.0.483/csvpath/matching/functions/types}/nonef.py +5 -3
  31. {csvpath-0.0.481/csvpath/matching/functions/strings → csvpath-0.0.483/csvpath/matching/functions/types}/string.py +6 -6
  32. csvpath-0.0.483/csvpath/matching/functions/validity/line.py +109 -0
  33. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/variables/pushpop.py +2 -2
  34. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/matcher.py +15 -0
  35. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/productions/matchable.py +43 -2
  36. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/util/expression_utility.py +20 -4
  37. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/util/error.py +5 -30
  38. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/util/line_counter.py +3 -2
  39. {csvpath-0.0.481 → csvpath-0.0.483}/docs/comments.md +2 -2
  40. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/header_names_mismatch.md +2 -0
  41. csvpath-0.0.483/docs/functions/intf.md +51 -0
  42. csvpath-0.0.483/docs/functions/line.md +74 -0
  43. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/now.md +5 -0
  44. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/subtract.md +1 -10
  45. csvpath-0.0.483/docs/functions/types.md +48 -0
  46. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions.md +18 -6
  47. {csvpath-0.0.481 → csvpath-0.0.483}/docs/variables.md +70 -2
  48. {csvpath-0.0.481 → csvpath-0.0.483}/pyproject.toml +1 -1
  49. csvpath-0.0.481/csvpath/matching/functions/boolean/boolean.py +0 -31
  50. csvpath-0.0.481/csvpath/matching/functions/boolean/orf.py +0 -34
  51. csvpath-0.0.481/csvpath/matching/functions/dates/datef.py +0 -40
  52. csvpath-0.0.481/csvpath/matching/functions/validity/line.py +0 -88
  53. {csvpath-0.0.481 → csvpath-0.0.483}/LICENSE +0 -0
  54. {csvpath-0.0.481 → csvpath-0.0.483}/config/config.ini +0 -0
  55. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/__init__.py +0 -0
  56. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/csvpaths.py +0 -0
  57. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/managers/__init__.py +0 -0
  58. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/managers/csvpaths_manager.py +0 -0
  59. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/managers/file_manager.py +0 -0
  60. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/managers/result.py +0 -0
  61. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/__init__.py +0 -0
  62. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/__init__.py +0 -0
  63. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/boolean/between.py +0 -0
  64. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/boolean/exists.py +0 -0
  65. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/boolean/no.py +0 -0
  66. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/boolean/notf.py +0 -0
  67. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/boolean/yes.py +0 -0
  68. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/counting/count_headers.py +0 -0
  69. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/counting/count_lines.py +0 -0
  70. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/counting/count_scans.py +0 -0
  71. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/counting/has_matches.py +0 -0
  72. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/counting/total_lines.py +0 -0
  73. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/function_finder.py +0 -0
  74. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/function_focus.py +0 -0
  75. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/headers/append.py +0 -0
  76. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/headers/empty_stack.py +0 -0
  77. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/headers/header_name.py +0 -0
  78. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
  79. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/headers/headers.py +0 -0
  80. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/headers/mismatch.py +0 -0
  81. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/headers/replace.py +0 -0
  82. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/lines/after_blank.py +0 -0
  83. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/lines/dups.py +0 -0
  84. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/lines/first.py +0 -0
  85. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/lines/first_line.py +0 -0
  86. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/lines/last.py +0 -0
  87. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/lines/stop.py +0 -0
  88. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/math/above.py +0 -0
  89. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/math/add.py +0 -0
  90. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/math/divide.py +0 -0
  91. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/math/equals.py +0 -0
  92. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/math/mod.py +0 -0
  93. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/math/multiply.py +0 -0
  94. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/math/round.py +0 -0
  95. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/math/subtotal.py +0 -0
  96. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/math/subtract.py +0 -0
  97. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/math/sum.py +0 -0
  98. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/misc/importf.py +0 -0
  99. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/misc/random.py +0 -0
  100. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/print/jinjaf.py +0 -0
  101. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/print/print_line.py +0 -0
  102. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/print/print_queue.py +0 -0
  103. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/print/printf.py +0 -0
  104. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/print/table.py +0 -0
  105. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/stats/minf.py +0 -0
  106. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/stats/percent.py +0 -0
  107. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  108. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/stats/stdev.py +0 -0
  109. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/strings/concat.py +0 -0
  110. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/strings/lower.py +0 -0
  111. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/strings/metaphone.py +0 -0
  112. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/strings/regex.py +0 -0
  113. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/strings/starts_with.py +0 -0
  114. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/strings/strip.py +0 -0
  115. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/strings/substring.py +0 -0
  116. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/strings/upper.py +0 -0
  117. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/testing/debug.py +0 -0
  118. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/validity/fail.py +0 -0
  119. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/validity/failed.py +0 -0
  120. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/variables/get.py +0 -0
  121. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/variables/put.py +0 -0
  122. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/variables/track.py +0 -0
  123. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/functions/variables/variables.py +0 -0
  124. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/lark_parser.py +0 -0
  125. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/lark_transformer.py +0 -0
  126. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/productions/__init__.py +0 -0
  127. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/productions/equality.py +0 -0
  128. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/productions/expression.py +0 -0
  129. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/productions/header.py +0 -0
  130. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/productions/qualified.py +0 -0
  131. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/productions/reference.py +0 -0
  132. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/productions/term.py +0 -0
  133. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/productions/variable.py +0 -0
  134. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/util/exceptions.py +0 -0
  135. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/util/expression_encoder.py +0 -0
  136. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/util/lark_print_parser.py +0 -0
  137. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/matching/util/print_parser.py +0 -0
  138. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/scanning/__init__.py +0 -0
  139. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/scanning/exceptions.py +0 -0
  140. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/scanning/parser.out +0 -0
  141. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/scanning/parsetab.py +0 -0
  142. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/scanning/scanner.py +0 -0
  143. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/scanning/scanning_lexer.py +0 -0
  144. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/util/cache.py +0 -0
  145. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/util/config.py +0 -0
  146. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/util/config_exception.py +0 -0
  147. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/util/exceptions.py +0 -0
  148. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/util/last_line_stats.py +0 -0
  149. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/util/line_monitor.py +0 -0
  150. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/util/log_utility.py +0 -0
  151. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/util/metadata_parser.py +0 -0
  152. {csvpath-0.0.481 → csvpath-0.0.483}/csvpath/util/printer.py +0 -0
  153. {csvpath-0.0.481 → csvpath-0.0.483}/docs/asbool.md +0 -0
  154. {csvpath-0.0.481 → csvpath-0.0.483}/docs/assignment.md +0 -0
  155. {csvpath-0.0.481 → csvpath-0.0.483}/docs/config.md +0 -0
  156. {csvpath-0.0.481 → csvpath-0.0.483}/docs/examples.md +0 -0
  157. {csvpath-0.0.481 → csvpath-0.0.483}/docs/files.md +0 -0
  158. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/above.md +0 -0
  159. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/advance.md +0 -0
  160. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/after_blank.md +0 -0
  161. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/all.md +0 -0
  162. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/andor.md +0 -0
  163. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/any.md +0 -0
  164. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/average.md +0 -0
  165. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/between.md +0 -0
  166. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/collect.md +0 -0
  167. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/correlate.md +0 -0
  168. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/count.md +0 -0
  169. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/count_headers.md +0 -0
  170. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/counter.md +0 -0
  171. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/date.md +0 -0
  172. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/empty.md +0 -0
  173. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/empty_stack.md +0 -0
  174. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/end.md +0 -0
  175. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/every.md +0 -0
  176. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/fail.md +0 -0
  177. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/first.md +0 -0
  178. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/get.md +0 -0
  179. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/has_dups.md +0 -0
  180. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/has_matches.md +0 -0
  181. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/header.md +0 -0
  182. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/header_name.md +0 -0
  183. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/implementing_functions.md +0 -0
  184. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/import.md +0 -0
  185. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/in.md +0 -0
  186. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/increment.md +0 -0
  187. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/jinja.md +0 -0
  188. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/last.md +0 -0
  189. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/line_number.md +0 -0
  190. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/max.md +0 -0
  191. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/metaphone.md +0 -0
  192. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/mismatch.md +0 -0
  193. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/no.md +0 -0
  194. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/not.md +0 -0
  195. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/percent_unique.md +0 -0
  196. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/pop.md +0 -0
  197. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/print.md +0 -0
  198. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/print_line.md +0 -0
  199. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/print_queue.md +0 -0
  200. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/random.md +0 -0
  201. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/regex.md +0 -0
  202. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/replace.md +0 -0
  203. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/reset_headers.md +0 -0
  204. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/stdev.md +0 -0
  205. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/stop.md +0 -0
  206. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/string_functions.md +0 -0
  207. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/subtotal.md +0 -0
  208. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/sum.md +0 -0
  209. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/tally.md +0 -0
  210. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/total_lines.md +0 -0
  211. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/track.md +0 -0
  212. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/variables.md +0 -0
  213. {csvpath-0.0.481 → csvpath-0.0.483}/docs/functions/variables_and_headers.md +0 -0
  214. {csvpath-0.0.481 → csvpath-0.0.483}/docs/grammar.md +0 -0
  215. {csvpath-0.0.481 → csvpath-0.0.483}/docs/headers.md +0 -0
  216. {csvpath-0.0.481 → csvpath-0.0.483}/docs/images/logo-wordmark-white-on-black-trimmed-padded.png +0 -0
  217. {csvpath-0.0.481 → csvpath-0.0.483}/docs/images/logo-wordmark-white-trimmed.png +0 -0
  218. {csvpath-0.0.481 → csvpath-0.0.483}/docs/paths.md +0 -0
  219. {csvpath-0.0.481 → csvpath-0.0.483}/docs/printing.md +0 -0
  220. {csvpath-0.0.481 → csvpath-0.0.483}/docs/qualifiers.md +0 -0
  221. {csvpath-0.0.481 → csvpath-0.0.483}/docs/references.md +0 -0
  222. {csvpath-0.0.481 → csvpath-0.0.483}/docs/terms.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: csvpath
3
- Version: 0.0.481
3
+ Version: 0.0.483
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
@@ -48,7 +48,6 @@ And do it all in an automation-friendly way.
48
48
  Though much simpler, it is inspired by:
49
49
  - XPath. CsvPath is to CSV files like XPath is to XML files.
50
50
  - Validation of XML using <a href='https://schematron.com/'>Schematron rules</a>
51
- - The way CSS selectors pick out HTML structures
52
51
 
53
52
  CsvPath is intended to fit with other DataOps and data quality tools. Files are streamed. The interface is simple. New functions are easy to create.
54
53
 
@@ -81,8 +80,8 @@ Read more about CsvPath and see realistic CSV validation examples at <a href='ht
81
80
  - [More Examples](#examples)
82
81
  - [Grammar](#grammar)
83
82
 
84
- # Motivation
85
83
  <a name="motivation"></a>
84
+ # Motivation
86
85
 
87
86
  CSV files are everywhere!
88
87
 
@@ -14,7 +14,6 @@ And do it all in an automation-friendly way.
14
14
  Though much simpler, it is inspired by:
15
15
  - XPath. CsvPath is to CSV files like XPath is to XML files.
16
16
  - Validation of XML using <a href='https://schematron.com/'>Schematron rules</a>
17
- - The way CSS selectors pick out HTML structures
18
17
 
19
18
  CsvPath is intended to fit with other DataOps and data quality tools. Files are streamed. The interface is simple. New functions are easy to create.
20
19
 
@@ -47,8 +46,8 @@ Read more about CsvPath and see realistic CSV validation examples at <a href='ht
47
46
  - [More Examples](#examples)
48
47
  - [Grammar](#grammar)
49
48
 
50
- # Motivation
51
49
  <a name="motivation"></a>
50
+ # Motivation
52
51
 
53
52
  CSV files are everywhere!
54
53
 
@@ -14,7 +14,7 @@ from csvpath.util.log_utility import LogUtility
14
14
  from .matching.matcher import Matcher
15
15
  from .scanning.scanner import Scanner
16
16
  from .util.metadata_parser import MetadataParser
17
- from .util.error import Error, ErrorCollector
17
+ from .util.error import Error, ErrorCollector, ErrorCommsManager
18
18
  from .util.printer import StdOutPrinter
19
19
  from .util.line_counter import LineCounter
20
20
  from .util.exceptions import VariableException, InputException, ParsingException
@@ -262,6 +262,10 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
262
262
  #
263
263
  self.logger = LogUtility.logger(self)
264
264
  self.logger.info("initialized CsvPath")
265
+ self._ecoms = ErrorCommsManager(csvpath=self)
266
+
267
+ def do_i_raise(self) -> bool:
268
+ return self._ecoms.do_i_raise()
265
269
 
266
270
  @property
267
271
  def advance_count(self) -> int: # pragma: no cover
@@ -569,7 +573,7 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
569
573
  #
570
574
  # settings:
571
575
  # - logic-mode: AND | OR
572
- # - match-mode: matches | no-matches
576
+ # - return-mode: matches | no-matches
573
577
  # - print-mode: default | no-default
574
578
  # - validation-mode: (no-)print | log | (no-)raise | quiet | (no-)match
575
579
  #
@@ -606,15 +610,15 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
606
610
  )
607
611
 
608
612
  def update_match_mode_if(self) -> None:
609
- if "match-mode" in self.metadata:
610
- if f"{self.metadata['match-mode']}".strip() == "matches":
613
+ if "return-mode" in self.metadata:
614
+ if f"{self.metadata['return-mode']}".strip() == "matches":
611
615
  self.collect_when_not_matched = False
612
- elif f"{self.metadata['match-mode']}".strip() == "no-matches":
616
+ elif f"{self.metadata['return-mode']}".strip() == "no-matches":
613
617
  self.collect_when_not_matched = True
614
618
  else:
615
619
  self.logger.warning(
616
- "Incorrect metadata field value 'match-mode': %s",
617
- self.metadata["match-mode"],
620
+ "Incorrect metadata field value 'return-mode': %s",
621
+ self.metadata["return-mode"],
618
622
  )
619
623
 
620
624
  def update_print_mode_if(self) -> None:
@@ -89,7 +89,6 @@ class ResultsManager(CsvPathsResultsManager): # pylint: disable=C0115
89
89
  def __init__(self, *, csvpaths=None):
90
90
  self.named_results = {}
91
91
  self._csvpaths = None
92
- self._variables = None
93
92
 
94
93
  # use property
95
94
  self.csvpaths = csvpaths
@@ -137,13 +136,11 @@ class ResultsManager(CsvPathsResultsManager): # pylint: disable=C0115
137
136
  return True
138
137
 
139
138
  def get_variables(self, name: str) -> bool:
140
- if self._variables is None:
141
- results = self.get_named_results(name)
142
- vs = {}
143
- for r in results:
144
- vs = {**r.csvpath.variables, **vs}
145
- self._variables = vs
146
- return self._variables
139
+ results = self.get_named_results(name)
140
+ vs = {}
141
+ for r in results:
142
+ vs = {**r.csvpath.variables, **vs}
143
+ return vs
147
144
 
148
145
  def has_lines(self, name: str) -> bool:
149
146
  results = self.get_named_results(name)
@@ -16,9 +16,12 @@ from csvpath.util.config_exception import ConfigurationException
16
16
 
17
17
 
18
18
  class Arg:
19
- def __init__(self, *, types: list[Type] = None, actuals: list[Type] = None):
19
+ def __init__(
20
+ self, *, name: str = None, types: list[Type] = None, actuals: list[Type] = None
21
+ ):
20
22
  self.is_noneable = False
21
23
  self._types = None
24
+ self._name = name
22
25
  self._x_actuals = None
23
26
  self.types: list[Type] = types or [None]
24
27
  self.actuals: list[Type] = actuals or []
@@ -100,8 +103,10 @@ class ArgSet:
100
103
  # setup time
101
104
  # ----------------------------
102
105
 
103
- def arg(self, *, types: list[Type] = None, actuals: list[Type] = None) -> Arg:
104
- arg = Arg(types=types, actuals=actuals)
106
+ def arg(
107
+ self, *, name: str = None, types: list[Type] = None, actuals: list[Type] = None
108
+ ) -> Arg:
109
+ arg = Arg(name=name, types=types, actuals=actuals)
105
110
  self._args.append(arg)
106
111
  if len(self._args) > self.max_length and self.max_length != -1:
107
112
  self.max_length = len(self._args)
@@ -194,16 +199,17 @@ class ArgSet:
194
199
  self._args = args
195
200
  self.max_length = len(self._args)
196
201
 
197
- def validate_structure(self, siblings: List[Matchable]) -> None:
202
+ def validate_structure(self, siblings: List[Matchable]) -> None | str:
198
203
  b = self._validate_length(siblings)
199
204
  if b is False:
200
- return False
205
+ return "incorrect number of args"
201
206
  self._pad_or_shrink(siblings)
202
207
  for i, s in enumerate(siblings):
203
208
  t = tuple(self._args[i].types)
204
209
  if not isinstance(s, t):
205
- return False
206
- return True
210
+ ii = i + 1
211
+ return f"type mismatch at arg {ii}"
212
+ return None
207
213
 
208
214
  # ----------------------------
209
215
  # match actuals line-by-line
@@ -390,11 +396,12 @@ class Args:
390
396
  #
391
397
  good = False
392
398
  for aset in self._argsets:
393
- if aset.validate_structure(siblings):
399
+ _m = aset.validate_structure(siblings)
400
+ if _m is None:
394
401
  good = True
395
402
  if not good:
396
403
  _ = f" at {self.matchable.my_chain}" if self.matchable else ""
397
- msg = f"{self._csvpath_id()} Incorrectly written{_}. Wrong type or number of args."
404
+ msg = f"{self._csvpath_id()} Incorrectly written{_}. Wrong type or number of args: {_m}."
398
405
  raise ChildrenException(msg)
399
406
  self.validated = True
400
407
 
@@ -19,7 +19,9 @@ class All(MatchDecider):
19
19
  self.args = Args(matchable=self)
20
20
  self.args.argset(0)
21
21
  self.args.argset(1).arg(types=[None, Variables, Headers], actuals=[])
22
- self.args.argset().arg(types=[None, Function, Variable, Header], actuals=[])
22
+ self.args.argset().arg(
23
+ types=[None, Function, Variable, Header], actuals=[None, Any]
24
+ )
23
25
  self.args.validate(self.siblings())
24
26
  super().check_valid()
25
27
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  from typing import Any
4
4
  from ..function_focus import MatchDecider
5
- from csvpath.matching.productions import Term, Variable, Header, Reference, Equality
5
+ from csvpath.matching.productions import Matchable
6
6
  from ..function import Function
7
7
  from ..args import Args
8
8
 
@@ -15,12 +15,8 @@ class And(MatchDecider):
15
15
  def check_valid(self) -> None: # pragma: no cover
16
16
  self.args = Args(matchable=self)
17
17
  a = self.args.argset()
18
- a.arg(
19
- types=[Term, Variable, Header, Function, Reference, Equality], actuals=[Any]
20
- )
21
- a.arg(
22
- types=[Term, Variable, Header, Function, Reference, Equality], actuals=[Any]
23
- )
18
+ a.arg(types=[Matchable], actuals=[None, Any])
19
+ a.arg(types=[Matchable], actuals=[None, Any])
24
20
  self.args.validate(self.siblings_or_equality())
25
21
  super().check_valid()
26
22
 
@@ -24,11 +24,11 @@ class Any(MatchDecider):
24
24
  a = self.args.argset(0)
25
25
 
26
26
  a = self.args.argset(2)
27
- a.arg(types=[Variables, Headers], actuals=[Any])
28
- a.arg(types=[typing.Any], actuals=[typing.Any])
27
+ a.arg(types=[Variables, Headers], actuals=[None, typing.Any])
28
+ a.arg(types=[typing.Any], actuals=[None, typing.Any])
29
29
 
30
30
  a = self.args.argset(1)
31
- a.arg(types=[typing.Any, Variables, Headers], actuals=[typing.Any])
31
+ a.arg(types=[typing.Any, Variables, Headers], actuals=[None, typing.Any])
32
32
 
33
33
  self.args.validate(self.siblings())
34
34
  super().check_valid()
@@ -33,7 +33,7 @@ class Empty(MatchDecider):
33
33
  def _validate(self):
34
34
  sibs = self.siblings()
35
35
  for s in sibs:
36
- # both definitely structure / children exceptions
36
+ # both structure / children exceptions
37
37
  if isinstance(s, Headers) and len(sibs) > 1:
38
38
  raise ChildrenException(
39
39
  "If empty() has a headers() argument it can only have 1 argument"
@@ -73,12 +73,7 @@ class Empty(MatchDecider):
73
73
  self.match = ret
74
74
 
75
75
  def _do_many(self, skip=None):
76
- siblings = None
77
- if isinstance(self.children[0], Equality):
78
- siblings = self.children[0].commas_to_list()
79
- else:
80
- siblings = self.children[0]
81
-
76
+ siblings = self.siblings()
82
77
  for s in siblings:
83
78
  self._do_one(s)
84
79
  if self.match is False:
@@ -87,22 +82,3 @@ class Empty(MatchDecider):
87
82
  def _do_one(self, child, skip=None):
88
83
  v = child.to_value(skip=skip)
89
84
  self.match = ExpressionUtility.is_empty(v)
90
-
91
- """
92
- def _is_empty(self, v):
93
- ret = True
94
- if v is None:
95
- ret = True
96
- elif f"{v}".strip() == "":
97
- ret = True
98
- elif isinstance(v, list) or isinstance(v, tuple):
99
- for item in v:
100
- ret = self._is_empty(item)
101
- if not ret:
102
- break
103
- elif isinstance(v, dict):
104
- ret = len(v) > 0
105
- else:
106
- ret = False
107
- return ret
108
- """
@@ -13,8 +13,8 @@ class In(MatchDecider):
13
13
  def check_valid(self) -> None:
14
14
  self.args = Args(matchable=self)
15
15
  a = self.args.argset()
16
- a.arg(types=[Term, Variable, Header, Function, Reference], actuals=[Any])
17
- a.arg(types=[Term, Variable, Header, Function, Reference], actuals=[Any])
16
+ a.arg(types=[Term, Variable, Header, Function, Reference], actuals=[None, Any])
17
+ a.arg(types=[Term, Variable, Header, Function, Reference], actuals=[None, Any])
18
18
  self.args.validate(self.siblings())
19
19
  super().check_valid()
20
20
 
@@ -0,0 +1,57 @@
1
+ # pylint: disable=C0114
2
+ from typing import Any
3
+ from ..function_focus import MatchDecider
4
+ from csvpath.matching.productions import (
5
+ Term,
6
+ Variable,
7
+ Header,
8
+ Reference,
9
+ Equality,
10
+ Matchable,
11
+ )
12
+ from ..function import Function
13
+ from ..args import Args
14
+
15
+
16
+ class Or(MatchDecider):
17
+ """does a logical OR of match components"""
18
+
19
+ def __init__(self, matcher: Any, name: str, child: Matchable = None) -> None:
20
+ super().__init__(matcher, name=name, child=child)
21
+ self.hold = []
22
+
23
+ def reset(self) -> None:
24
+ self.hold = []
25
+ super().reset()
26
+
27
+ def check_valid(self) -> None:
28
+ self.args = Args(matchable=self)
29
+ a = self.args.argset()
30
+ a.arg(types=[Matchable], actuals=[None, Any])
31
+ a.arg(types=[Matchable], actuals=[None, Any])
32
+ self.args.validate(self.siblings_or_equality())
33
+ super().check_valid()
34
+
35
+ def raise_if(self, e, *, cause=None) -> None:
36
+ # not bubbling up until we know we don't have a
37
+ # match on all options
38
+ self.hold.append((e, cause))
39
+
40
+ def _produce_value(self, skip=None) -> None:
41
+ self.value = self.matches(skip=skip)
42
+
43
+ def _decide_match(self, skip=None) -> None:
44
+ child = self.children[0]
45
+ siblings = child.commas_to_list()
46
+ for sib in siblings:
47
+ b = sib.matches(skip=skip)
48
+ if b:
49
+ self.match = True
50
+ # if we find a True we succeed and dump any errors
51
+ self.hold = []
52
+ return
53
+ self.match = False
54
+ # if we fail we progress any errors up the stack
55
+ for err in self.hold:
56
+ super().raise_if(err[0], cause=err[1])
57
+ self.hold = []
@@ -3,7 +3,7 @@ from typing import Any
3
3
  from ..function_focus import ValueProducer
4
4
  from ..function import Function
5
5
  from ..args import Args
6
- from csvpath.matching.productions import Equality, Variable, Header, Term
6
+ from csvpath.matching.productions import Matchable
7
7
 
8
8
 
9
9
  class Count(ValueProducer):
@@ -16,10 +16,7 @@ class Count(ValueProducer):
16
16
  self.args = Args(matchable=self)
17
17
  a = self.args.argset(0)
18
18
  a = self.args.argset()
19
- a.arg(
20
- types=[None, Variable, Function, Header, Term, Equality],
21
- actuals=[None, Any],
22
- )
19
+ a.arg(types=[None, Matchable], actuals=[None, Any])
23
20
  self.args.validate(self.siblings())
24
21
  #
25
22
  super().check_valid() # pylint: disable=W0246
@@ -16,6 +16,11 @@ class Counter(ValueProducer):
16
16
  self.args = Args(matchable=self)
17
17
  self.args.argset(1).arg(types=[None, Any], actuals=[int])
18
18
  self.args.validate(self.siblings())
19
+ name = self.first_non_term_qualifier(self.get_id())
20
+ # initializing the counter to 0. if we don't do this and the counter is
21
+ # never hit (e.g. it is behind a ->) a print returns the counter's name
22
+ # which is confusing.
23
+ self.matcher.get_variable(name, set_if_none=0)
19
24
  super().check_valid() # pylint: disable=W0246
20
25
 
21
26
  def _produce_value(self, skip=None) -> None:
@@ -3,7 +3,7 @@ from typing import Any
3
3
  from csvpath.matching.util.exceptions import ChildrenException
4
4
  from csvpath.matching.util.expression_utility import ExpressionUtility
5
5
  from ..function_focus import ValueProducer
6
- from csvpath.matching.productions import Term, Header, Variable, Equality
6
+ from csvpath.matching.productions import Term, Matchable
7
7
  from ..function import Function
8
8
  from ..args import Args
9
9
 
@@ -19,7 +19,7 @@ class Every(ValueProducer):
19
19
  def check_valid(self) -> None:
20
20
  self.args = Args(matchable=self)
21
21
  a = self.args.argset(2)
22
- a.arg(types=[Term, Variable, Header, Function, Equality], actuals=[Any])
22
+ a.arg(types=[Matchable], actuals=[None, Any])
23
23
  a.arg(types=[Term], actuals=[int])
24
24
  self.args.validate(self.siblings())
25
25
  super().check_valid()
@@ -2,18 +2,18 @@
2
2
  from typing import Any
3
3
  from csvpath.matching.util.exceptions import DataException
4
4
  from ..function_focus import ValueProducer
5
- from csvpath.matching.productions import Term, Header, Variable, Equality
5
+ from csvpath.matching.productions import Term, Matchable
6
6
  from ..function import Function
7
7
  from ..args import Args
8
8
 
9
9
 
10
10
  class Increment(ValueProducer):
11
- """increments a var every n-times a each different value is seen"""
11
+ """increments a var every n-times each different value is seen"""
12
12
 
13
13
  def check_valid(self) -> None:
14
14
  self.args = Args(matchable=self)
15
15
  a = self.args.argset(2)
16
- a.arg(types=[Term, Variable, Header, Function, Equality], actuals=[str])
16
+ a.arg(types=[Matchable], actuals=[Any])
17
17
  a.arg(types=[Term], actuals=[int])
18
18
  self.args.validate(self.siblings())
19
19
  super().check_valid()
@@ -18,14 +18,8 @@ class Tally(ValueProducer):
18
18
  super().check_valid()
19
19
 
20
20
  def _produce_value(self, skip=None) -> None:
21
- child = self.children[0]
22
- siblings = None
23
- if isinstance(child, Equality):
24
- siblings = child.commas_to_list()
25
- else:
26
- siblings = [child]
21
+ siblings = self.siblings()
27
22
  tally = ""
28
-
29
23
  for _ in siblings:
30
24
  tally += f"{_.to_value(skip=skip)}|"
31
25
  value = f"{_.to_value(skip=skip)}"
@@ -1,9 +1,7 @@
1
1
  # pylint: disable=C0114
2
2
  import datetime
3
3
  from ..function_focus import ValueProducer
4
- from csvpath.matching.productions.term import Term
5
- from csvpath.matching.productions.variable import Variable
6
- from csvpath.matching.productions.header import Header
4
+ from csvpath.matching.productions import Term, Variable, Header
7
5
  from csvpath.matching.functions.function import Function
8
6
  from csvpath.matching.util.exceptions import ChildrenException
9
7
  from ..args import Args
@@ -19,7 +17,7 @@ class Now(ValueProducer):
19
17
  self.args.validate(self.siblings())
20
18
  else:
21
19
  self.args.argset(1).arg(
22
- types=[None, Term, Function, Header, Variable], actuals=[str]
20
+ types=[None, Term, Function, Header, Variable], actuals=[None, str]
23
21
  )
24
22
  self.args.validate(self.siblings())
25
23
  super().check_valid()
@@ -138,7 +138,7 @@ class Function(Matchable):
138
138
  if Matchable.FAILED_VALUE in sibs:
139
139
  pln = self.matcher.csvpath.line_monitor.physical_line_number
140
140
  raise ChildrenException(
141
- f"Cannot continue with {self.my_chain} on line {pln} due to an invalid child"
141
+ f"Line {pln}: Cannot continue with {self.my_chain} due to an invalid child"
142
142
  )
143
143
  #
144
144
  # ready to run the match!
@@ -162,12 +162,14 @@ class Function(Matchable):
162
162
  ):
163
163
  self.matcher.csvpath.stop()
164
164
  if (
165
- self.args.args_match is False
165
+ self.args
166
+ and self.args.args_match is False
166
167
  and self.matcher.csvpath.fail_on_validation_errors
167
168
  ):
168
169
  self.matcher.csvpath.is_valid = False
169
170
  if (
170
- self.args.args_match is False
171
+ self.args
172
+ and self.args.args_match is False
171
173
  and self.matcher.csvpath._match_validation_errors is not None
172
174
  ):
173
175
  self.match = self.matcher.csvpath._match_validation_errors
@@ -3,11 +3,9 @@ from csvpath.matching.productions.expression import Matchable
3
3
  from .function import Function
4
4
  from .function_finder import FunctionFinder
5
5
  from .dates.now import Now
6
- from .dates.datef import Date
7
6
  from .strings.lower import Lower
8
7
  from .strings.upper import Upper
9
8
  from .strings.substring import Substring
10
- from .strings.string import String
11
9
  from .strings.starts_with import StartsWith
12
10
  from .strings.strip import Strip
13
11
  from .strings.length import Length, MinMaxLength
@@ -35,11 +33,11 @@ from .headers.empty_stack import EmptyStack
35
33
  from .headers.mismatch import Mismatch
36
34
  from .headers.end import End
37
35
  from .math.above import AboveBelow
38
- from .math.intf import Int, Num, Float
39
36
  from .math.add import Add
40
37
  from .math.subtract import Subtract
41
38
  from .math.multiply import Multiply
42
39
  from .math.divide import Divide
40
+ from .math.intf import Int, Float # , Num
43
41
  from .math.sum import Sum
44
42
  from .math.subtotal import Subtotal
45
43
  from .math.equals import Equals
@@ -47,7 +45,6 @@ from .math.round import Round
47
45
  from .math.mod import Mod
48
46
  from .boolean.notf import Not
49
47
  from .boolean.inf import In
50
- from .boolean.boolean import Boolean
51
48
  from .boolean.orf import Or
52
49
  from .boolean.empty import Empty
53
50
  from .boolean.no import No
@@ -61,8 +58,6 @@ from .stats.percent import Percent
61
58
  from .stats.minf import Min, Max, Average
62
59
  from .stats.percent_unique import PercentUnique
63
60
  from .stats.stdev import Stdev
64
-
65
- # from .stats.correlate import Correlate
66
61
  from .print.printf import Print
67
62
  from .print.table import HeaderTable, RowTable, VarTable, RunTable
68
63
  from .print.print_line import PrintLine
@@ -81,12 +76,16 @@ from .variables.get import Get
81
76
  from .variables.put import Put
82
77
  from .variables.track import Track
83
78
  from .misc.random import Random, Shuffle
84
- from .misc.nonef import Nonef, Blank
85
79
  from .misc.importf import Import
86
80
  from .testing.debug import Debug, BriefStackTrace, VoteStack, DoWhenStack, Log
87
81
  from .validity.line import Line
88
82
  from .validity.failed import Failed
89
83
  from .validity.fail import Fail, FailAll
84
+ from .types.nonef import Nonef, Blank
85
+ from .types.decimal import Decimal
86
+ from .types.boolean import Boolean
87
+ from .types.datef import Date
88
+ from .types.string import String
90
89
 
91
90
 
92
91
  class UnknownFunctionException(Exception):
@@ -218,6 +217,8 @@ class FunctionFactory:
218
217
  f = Random(matcher, name, child)
219
218
  elif name == "shuffle":
220
219
  f = Shuffle(matcher, name, child)
220
+ elif name in ["decimal", "integer"]:
221
+ f = Decimal(matcher, name, child)
221
222
  elif name == "end":
222
223
  f = End(matcher, name, child)
223
224
  elif name == "length":
@@ -260,7 +261,7 @@ class FunctionFactory:
260
261
  f = Any(matcher, name, child)
261
262
  elif name == "none":
262
263
  f = Nonef(matcher, name, child)
263
- elif name in ["blank", "unspecific"]:
264
+ elif name in ["blank", "nonspecific"]:
264
265
  f = Blank(matcher, name, child)
265
266
  elif name == "line":
266
267
  f = Line(matcher, name, child)
@@ -390,8 +391,8 @@ class FunctionFactory:
390
391
  f = RunTable(matcher, name, child)
391
392
  elif name == "empty_stack":
392
393
  f = EmptyStack(matcher, name, child)
393
- elif name == "num":
394
- f = Num(matcher, name, child)
394
+ # elif name == "num":
395
+ # f = Num(matcher, name, child)
395
396
  elif name == "counter":
396
397
  f = Counter(matcher, name, child)
397
398
  else:
@@ -12,7 +12,7 @@ class Collect(SideEffect):
12
12
  def check_valid(self) -> None:
13
13
  self.args = Args(matchable=self)
14
14
  a = self.args.argset()
15
- a.arg(types=[Term], actuals=[Any])
15
+ a.arg(types=[Term], actuals=[int, str])
16
16
  self.args.validate(self.siblings())
17
17
  super().check_valid()
18
18
 
@@ -24,11 +24,7 @@ class End(ValueProducer):
24
24
  else:
25
25
  if len(self.children) > 0:
26
26
  v = self.children[0].to_value()
27
- if isinstance(v, int) or v.isdigit():
28
- i = i - int(v)
29
- else:
30
- # this is an Args-style / data exception
31
- raise DataException("end()'s term must be a positive int")
27
+ i = i - abs(int(v))
32
28
  if 0 <= i < len(self.matcher.line):
33
29
  self.value = self.matcher.line[i]
34
30
 
@@ -1,6 +1,7 @@
1
1
  # pylint: disable=C0114
2
2
  from ..function_focus import SideEffect
3
3
  from csvpath.matching.functions.function import Function
4
+ from csvpath.util.line_counter import LineCounter
4
5
  from ..args import Args
5
6
 
6
7
 
@@ -9,7 +10,7 @@ class ResetHeaders(SideEffect):
9
10
 
10
11
  def check_valid(self) -> None:
11
12
  self.args = Args(matchable=self)
12
- self.args.argset(1).arg(types=[None, Function], actuals=[None])
13
+ self.args.argset(1).arg(types=[None, Function], actuals=[])
13
14
  self.args.validate(self.siblings())
14
15
  super().check_valid()
15
16
 
@@ -17,7 +18,8 @@ class ResetHeaders(SideEffect):
17
18
  self._apply_default_value()
18
19
 
19
20
  def _decide_match(self, skip=None) -> None:
20
- self.matcher.csvpath.headers = self.matcher.line[:]
21
+ hs = LineCounter.clean_headers(self.matcher.line[:])
22
+ self.matcher.csvpath.headers = hs
21
23
  self.matcher.header_dict = None
22
24
  for key in self.matcher.csvpath.variables.keys():
23
25
  #
@@ -1,7 +1,8 @@
1
1
  # pylint: disable=C0114
2
2
  from csvpath.matching.util.exceptions import ChildrenException
3
3
  from ..function_focus import SideEffect
4
- from csvpath.matching.productions.term import Term
4
+ from csvpath.matching.productions import Term, Variable
5
+ from csvpath.matching.functions.function import Function
5
6
  from ..args import Args
6
7
 
7
8
 
@@ -11,7 +12,7 @@ class Advance(SideEffect):
11
12
  def check_valid(self) -> None:
12
13
  self.args = Args(matchable=self)
13
14
  a = self.args.argset(1)
14
- a.arg(types=[Term], actuals=[int])
15
+ a.arg(types=[Term, Variable, Function], actuals=[int])
15
16
  self.args.validate(self.siblings())
16
17
  super().check_valid()
17
18