csvpath 0.0.482__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.482 → csvpath-0.0.483}/PKG-INFO +1 -2
  2. {csvpath-0.0.482 → csvpath-0.0.483}/README.md +0 -1
  3. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/csvpath.py +11 -7
  4. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/args.py +16 -9
  5. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/boolean/all.py +3 -1
  6. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/boolean/andf.py +3 -7
  7. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/boolean/any.py +3 -3
  8. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/boolean/empty.py +2 -26
  9. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/boolean/inf.py +2 -2
  10. csvpath-0.0.483/csvpath/matching/functions/boolean/orf.py +57 -0
  11. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/counting/count.py +2 -5
  12. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/counting/every.py +2 -2
  13. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/counting/increment.py +3 -3
  14. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/counting/tally.py +1 -7
  15. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/dates/now.py +2 -4
  16. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/function.py +5 -3
  17. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/function_factory.py +8 -7
  18. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/headers/collect.py +1 -1
  19. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/headers/end.py +1 -5
  20. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/headers/reset_headers.py +4 -2
  21. {csvpath-0.0.482/csvpath/matching/functions/types → csvpath-0.0.483/csvpath/matching/functions/math}/intf.py +6 -4
  22. csvpath-0.0.483/csvpath/matching/functions/types/__init__.py +7 -0
  23. csvpath-0.0.483/csvpath/matching/functions/types/boolean.py +49 -0
  24. csvpath-0.0.483/csvpath/matching/functions/types/datef.py +138 -0
  25. csvpath-0.0.483/csvpath/matching/functions/types/decimal.py +92 -0
  26. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/types/nonef.py +5 -3
  27. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/types/string.py +6 -6
  28. csvpath-0.0.483/csvpath/matching/functions/validity/line.py +109 -0
  29. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/variables/pushpop.py +1 -1
  30. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/matcher.py +15 -0
  31. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/productions/matchable.py +14 -1
  32. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/util/expression_utility.py +20 -4
  33. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/util/error.py +5 -30
  34. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/util/line_counter.py +3 -2
  35. {csvpath-0.0.482 → csvpath-0.0.483}/docs/comments.md +2 -2
  36. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/header_names_mismatch.md +2 -0
  37. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/line.md +2 -2
  38. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/now.md +5 -0
  39. csvpath-0.0.483/docs/functions/types.md +48 -0
  40. {csvpath-0.0.482 → csvpath-0.0.483}/pyproject.toml +1 -1
  41. csvpath-0.0.482/csvpath/matching/functions/boolean/orf.py +0 -37
  42. csvpath-0.0.482/csvpath/matching/functions/types/boolean.py +0 -31
  43. csvpath-0.0.482/csvpath/matching/functions/types/datef.py +0 -40
  44. csvpath-0.0.482/csvpath/matching/functions/validity/line.py +0 -92
  45. {csvpath-0.0.482 → csvpath-0.0.483}/LICENSE +0 -0
  46. {csvpath-0.0.482 → csvpath-0.0.483}/config/config.ini +0 -0
  47. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/__init__.py +0 -0
  48. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/csvpaths.py +0 -0
  49. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/managers/__init__.py +0 -0
  50. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/managers/csvpaths_manager.py +0 -0
  51. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/managers/file_manager.py +0 -0
  52. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/managers/result.py +0 -0
  53. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/managers/results_manager.py +0 -0
  54. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/__init__.py +0 -0
  55. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/__init__.py +0 -0
  56. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/boolean/between.py +0 -0
  57. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/boolean/exists.py +0 -0
  58. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/boolean/no.py +0 -0
  59. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/boolean/notf.py +0 -0
  60. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/boolean/yes.py +0 -0
  61. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/counting/count_headers.py +0 -0
  62. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/counting/count_lines.py +0 -0
  63. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/counting/count_scans.py +0 -0
  64. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/counting/counter.py +0 -0
  65. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/counting/has_matches.py +0 -0
  66. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/counting/total_lines.py +0 -0
  67. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/function_finder.py +0 -0
  68. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/function_focus.py +0 -0
  69. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/headers/append.py +0 -0
  70. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/headers/empty_stack.py +0 -0
  71. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/headers/header_name.py +0 -0
  72. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
  73. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/headers/headers.py +0 -0
  74. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/headers/mismatch.py +0 -0
  75. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/headers/replace.py +0 -0
  76. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/lines/advance.py +0 -0
  77. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/lines/after_blank.py +0 -0
  78. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/lines/dups.py +0 -0
  79. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/lines/first.py +0 -0
  80. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/lines/first_line.py +0 -0
  81. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/lines/last.py +0 -0
  82. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/lines/stop.py +0 -0
  83. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/math/above.py +0 -0
  84. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/math/add.py +0 -0
  85. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/math/divide.py +0 -0
  86. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/math/equals.py +0 -0
  87. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/math/mod.py +0 -0
  88. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/math/multiply.py +0 -0
  89. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/math/round.py +0 -0
  90. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/math/subtotal.py +0 -0
  91. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/math/subtract.py +0 -0
  92. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/math/sum.py +0 -0
  93. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/misc/importf.py +0 -0
  94. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/misc/random.py +0 -0
  95. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/print/jinjaf.py +0 -0
  96. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/print/print_line.py +0 -0
  97. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/print/print_queue.py +0 -0
  98. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/print/printf.py +0 -0
  99. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/print/table.py +0 -0
  100. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/stats/minf.py +0 -0
  101. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/stats/percent.py +0 -0
  102. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  103. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/stats/stdev.py +0 -0
  104. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/strings/concat.py +0 -0
  105. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/strings/length.py +0 -0
  106. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/strings/lower.py +0 -0
  107. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/strings/metaphone.py +0 -0
  108. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/strings/regex.py +0 -0
  109. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/strings/starts_with.py +0 -0
  110. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/strings/strip.py +0 -0
  111. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/strings/substring.py +0 -0
  112. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/strings/upper.py +0 -0
  113. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/testing/debug.py +0 -0
  114. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/validity/fail.py +0 -0
  115. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/validity/failed.py +0 -0
  116. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/variables/get.py +0 -0
  117. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/variables/put.py +0 -0
  118. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/variables/track.py +0 -0
  119. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/functions/variables/variables.py +0 -0
  120. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/lark_parser.py +0 -0
  121. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/lark_transformer.py +0 -0
  122. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/productions/__init__.py +0 -0
  123. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/productions/equality.py +0 -0
  124. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/productions/expression.py +0 -0
  125. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/productions/header.py +0 -0
  126. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/productions/qualified.py +0 -0
  127. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/productions/reference.py +0 -0
  128. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/productions/term.py +0 -0
  129. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/productions/variable.py +0 -0
  130. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/util/exceptions.py +0 -0
  131. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/util/expression_encoder.py +0 -0
  132. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/util/lark_print_parser.py +0 -0
  133. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/matching/util/print_parser.py +0 -0
  134. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/scanning/__init__.py +0 -0
  135. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/scanning/exceptions.py +0 -0
  136. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/scanning/parser.out +0 -0
  137. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/scanning/parsetab.py +0 -0
  138. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/scanning/scanner.py +0 -0
  139. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/scanning/scanning_lexer.py +0 -0
  140. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/util/cache.py +0 -0
  141. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/util/config.py +0 -0
  142. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/util/config_exception.py +0 -0
  143. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/util/exceptions.py +0 -0
  144. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/util/last_line_stats.py +0 -0
  145. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/util/line_monitor.py +0 -0
  146. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/util/log_utility.py +0 -0
  147. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/util/metadata_parser.py +0 -0
  148. {csvpath-0.0.482 → csvpath-0.0.483}/csvpath/util/printer.py +0 -0
  149. {csvpath-0.0.482 → csvpath-0.0.483}/docs/asbool.md +0 -0
  150. {csvpath-0.0.482 → csvpath-0.0.483}/docs/assignment.md +0 -0
  151. {csvpath-0.0.482 → csvpath-0.0.483}/docs/config.md +0 -0
  152. {csvpath-0.0.482 → csvpath-0.0.483}/docs/examples.md +0 -0
  153. {csvpath-0.0.482 → csvpath-0.0.483}/docs/files.md +0 -0
  154. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/above.md +0 -0
  155. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/advance.md +0 -0
  156. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/after_blank.md +0 -0
  157. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/all.md +0 -0
  158. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/andor.md +0 -0
  159. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/any.md +0 -0
  160. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/average.md +0 -0
  161. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/between.md +0 -0
  162. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/collect.md +0 -0
  163. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/correlate.md +0 -0
  164. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/count.md +0 -0
  165. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/count_headers.md +0 -0
  166. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/counter.md +0 -0
  167. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/date.md +0 -0
  168. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/empty.md +0 -0
  169. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/empty_stack.md +0 -0
  170. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/end.md +0 -0
  171. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/every.md +0 -0
  172. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/fail.md +0 -0
  173. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/first.md +0 -0
  174. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/get.md +0 -0
  175. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/has_dups.md +0 -0
  176. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/has_matches.md +0 -0
  177. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/header.md +0 -0
  178. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/header_name.md +0 -0
  179. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/implementing_functions.md +0 -0
  180. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/import.md +0 -0
  181. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/in.md +0 -0
  182. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/increment.md +0 -0
  183. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/intf.md +0 -0
  184. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/jinja.md +0 -0
  185. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/last.md +0 -0
  186. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/line_number.md +0 -0
  187. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/max.md +0 -0
  188. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/metaphone.md +0 -0
  189. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/mismatch.md +0 -0
  190. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/no.md +0 -0
  191. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/not.md +0 -0
  192. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/percent_unique.md +0 -0
  193. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/pop.md +0 -0
  194. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/print.md +0 -0
  195. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/print_line.md +0 -0
  196. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/print_queue.md +0 -0
  197. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/random.md +0 -0
  198. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/regex.md +0 -0
  199. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/replace.md +0 -0
  200. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/reset_headers.md +0 -0
  201. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/stdev.md +0 -0
  202. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/stop.md +0 -0
  203. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/string_functions.md +0 -0
  204. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/subtotal.md +0 -0
  205. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/subtract.md +0 -0
  206. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/sum.md +0 -0
  207. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/tally.md +0 -0
  208. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/total_lines.md +0 -0
  209. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/track.md +0 -0
  210. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/variables.md +0 -0
  211. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions/variables_and_headers.md +0 -0
  212. {csvpath-0.0.482 → csvpath-0.0.483}/docs/functions.md +0 -0
  213. {csvpath-0.0.482 → csvpath-0.0.483}/docs/grammar.md +0 -0
  214. {csvpath-0.0.482 → csvpath-0.0.483}/docs/headers.md +0 -0
  215. {csvpath-0.0.482 → csvpath-0.0.483}/docs/images/logo-wordmark-white-on-black-trimmed-padded.png +0 -0
  216. {csvpath-0.0.482 → csvpath-0.0.483}/docs/images/logo-wordmark-white-trimmed.png +0 -0
  217. {csvpath-0.0.482 → csvpath-0.0.483}/docs/paths.md +0 -0
  218. {csvpath-0.0.482 → csvpath-0.0.483}/docs/printing.md +0 -0
  219. {csvpath-0.0.482 → csvpath-0.0.483}/docs/qualifiers.md +0 -0
  220. {csvpath-0.0.482 → csvpath-0.0.483}/docs/references.md +0 -0
  221. {csvpath-0.0.482 → csvpath-0.0.483}/docs/terms.md +0 -0
  222. {csvpath-0.0.482 → csvpath-0.0.483}/docs/variables.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: csvpath
3
- Version: 0.0.482
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
 
@@ -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
 
@@ -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:
@@ -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
@@ -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
@@ -37,6 +37,7 @@ from .math.add import Add
37
37
  from .math.subtract import Subtract
38
38
  from .math.multiply import Multiply
39
39
  from .math.divide import Divide
40
+ from .math.intf import Int, Float # , Num
40
41
  from .math.sum import Sum
41
42
  from .math.subtotal import Subtotal
42
43
  from .math.equals import Equals
@@ -57,8 +58,6 @@ from .stats.percent import Percent
57
58
  from .stats.minf import Min, Max, Average
58
59
  from .stats.percent_unique import PercentUnique
59
60
  from .stats.stdev import Stdev
60
-
61
- # from .stats.correlate import Correlate
62
61
  from .print.printf import Print
63
62
  from .print.table import HeaderTable, RowTable, VarTable, RunTable
64
63
  from .print.print_line import PrintLine
@@ -83,10 +82,10 @@ from .validity.line import Line
83
82
  from .validity.failed import Failed
84
83
  from .validity.fail import Fail, FailAll
85
84
  from .types.nonef import Nonef, Blank
85
+ from .types.decimal import Decimal
86
86
  from .types.boolean import Boolean
87
- from .types.intf import Int, Num, Float
88
- from .types.string import String
89
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
  #
@@ -54,9 +54,10 @@ class Float(ValueProducer):
54
54
  self.match = self.default_match() # pragma: no cover
55
55
 
56
56
 
57
+ """
57
58
  class Num(ValueProducer):
58
- """parses a string or stringified object to a float, if possible,
59
- ints and bools stay ints"""
59
+ ""parses a string or stringified object to a float, if possible,
60
+ ints and bools stay ints""
60
61
 
61
62
  def check_valid(self) -> None:
62
63
  self.args = Args(matchable=self)
@@ -86,12 +87,12 @@ class Num(ValueProducer):
86
87
  self.my_expression.handle_error(e)
87
88
 
88
89
  def _decide_match(self, skip=None) -> None:
89
- """
90
+ ""
90
91
  (value, max digits before decimal, min digits before decimal, max places, min places)
91
92
  max of -1 means we don't care
92
93
  min of -1 means 0, or use -1, we don't care
93
94
 
94
- """
95
+ ""
95
96
  val = self._value_one()
96
97
  if not ExpressionUtility.is_one_of(val, (int, float)):
97
98
  self.match = False
@@ -137,3 +138,4 @@ class Num(ValueProducer):
137
138
  self.match = 0 <= len(d) <= dplaces_max
138
139
  elif self.match and dplaces_max == -1 and dplaces_min > -1:
139
140
  self.match = len(d) >= dplaces_min
141
+ """
@@ -0,0 +1,7 @@
1
+ """ this module implements the match part of a csvpath string """
2
+
3
+ from csvpath.matching.functions.types.boolean import Boolean
4
+ from csvpath.matching.functions.types.string import String
5
+ from csvpath.matching.functions.types.decimal import Decimal
6
+ from csvpath.matching.functions.types.nonef import Nonef, Blank
7
+ from csvpath.matching.functions.types.datef import Date
@@ -0,0 +1,49 @@
1
+ # pylint: disable=C0114
2
+ from csvpath.matching.util.expression_utility import ExpressionUtility
3
+ from csvpath.matching.util.exceptions import ChildrenException
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, str])
15
+ self.args.validate(self.siblings())
16
+ super().check_valid()
17
+
18
+ def _produce_value(self, skip=None) -> None:
19
+ c = self._child_one()
20
+ v = None
21
+ if isinstance(c, Term):
22
+ v = self.matcher.get_header_value(c.value)
23
+ else:
24
+ v = c.to_value(skip=skip)
25
+ if v is None or f"{v}".strip() == "":
26
+ self.value = None
27
+ if self.notnone is True:
28
+ pln = self.matcher.csvpath.line_monitor.physical_line_number
29
+ self.parent.raise_if(
30
+ ChildrenException(f"Line {pln}: Value cannot be empty")
31
+ )
32
+ else:
33
+ v = ExpressionUtility.to_bool(v)
34
+ if v in [True, False]:
35
+ self.value = v
36
+ else:
37
+ self.value = None
38
+ pln = self.matcher.csvpath.line_monitor.physical_line_number
39
+ self.parent.raise_if(
40
+ ChildrenException(f"Line {pln}: Not a boolean value: '{v}'")
41
+ )
42
+
43
+ def _decide_match(self, skip=None) -> None:
44
+ # we need to make sure a value is produced so that we see
45
+ # any errors. when we stand alone we're just checking our
46
+ # boolean-iness. when we're producing a value we're checking
47
+ # boolean-iness and casting and raising errors.
48
+ v = self.to_value(skip=skip)
49
+ self.match = v in [True, False] # pragma: no cover