csvpath 0.0.471__tar.gz → 0.0.472__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 (204) hide show
  1. {csvpath-0.0.471 → csvpath-0.0.472}/PKG-INFO +1 -1
  2. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/matchable.py +10 -0
  3. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/config.py +15 -14
  4. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/advance.md +1 -1
  5. csvpath-0.0.472/docs/functions/has_matches.md +17 -0
  6. csvpath-0.0.472/docs/functions/implementing_functions.md +107 -0
  7. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/import.md +1 -1
  8. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/metaphone.md +1 -1
  9. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions.md +1 -0
  10. {csvpath-0.0.471 → csvpath-0.0.472}/docs/paths.md +2 -2
  11. {csvpath-0.0.471 → csvpath-0.0.472}/docs/references.md +1 -1
  12. {csvpath-0.0.471 → csvpath-0.0.472}/pyproject.toml +1 -1
  13. csvpath-0.0.471/docs/functions/implementing_functions.md +0 -85
  14. {csvpath-0.0.471 → csvpath-0.0.472}/LICENSE +0 -0
  15. {csvpath-0.0.471 → csvpath-0.0.472}/README.md +0 -0
  16. {csvpath-0.0.471 → csvpath-0.0.472}/config/config.ini +0 -0
  17. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/__init__.py +0 -0
  18. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/csvpath.py +0 -0
  19. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/csvpaths.py +0 -0
  20. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/managers/__init__.py +0 -0
  21. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/managers/csvpaths_manager.py +0 -0
  22. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/managers/file_manager.py +0 -0
  23. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/managers/result.py +0 -0
  24. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/managers/results_manager.py +0 -0
  25. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/__init__.py +0 -0
  26. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/__init__.py +0 -0
  27. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/all.py +0 -0
  28. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/andf.py +0 -0
  29. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/any.py +0 -0
  30. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/between.py +0 -0
  31. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/empty.py +0 -0
  32. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/exists.py +0 -0
  33. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/inf.py +0 -0
  34. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/no.py +0 -0
  35. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/notf.py +0 -0
  36. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/orf.py +0 -0
  37. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/yes.py +0 -0
  38. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/count.py +0 -0
  39. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/count_headers.py +0 -0
  40. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/count_lines.py +0 -0
  41. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/count_scans.py +0 -0
  42. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/every.py +0 -0
  43. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/has_matches.py +0 -0
  44. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/increment.py +0 -0
  45. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/tally.py +0 -0
  46. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/total_lines.py +0 -0
  47. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/dates/datef.py +0 -0
  48. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/dates/now.py +0 -0
  49. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/function.py +0 -0
  50. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/function_factory.py +0 -0
  51. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/function_focus.py +0 -0
  52. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/collect.py +0 -0
  53. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/empty_stack.py +0 -0
  54. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/end.py +0 -0
  55. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/header_name.py +0 -0
  56. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
  57. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/headers.py +0 -0
  58. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/mismatch.py +0 -0
  59. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/replace.py +0 -0
  60. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/reset_headers.py +0 -0
  61. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/advance.py +0 -0
  62. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/after_blank.py +0 -0
  63. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/dups.py +0 -0
  64. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/first.py +0 -0
  65. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/first_line.py +0 -0
  66. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/last.py +0 -0
  67. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/stop.py +0 -0
  68. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/above.py +0 -0
  69. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/add.py +0 -0
  70. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/divide.py +0 -0
  71. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/equals.py +0 -0
  72. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/mod.py +0 -0
  73. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/multiply.py +0 -0
  74. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/round.py +0 -0
  75. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/subtract.py +0 -0
  76. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/sum.py +0 -0
  77. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/misc/importf.py +0 -0
  78. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/misc/intf.py +0 -0
  79. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/misc/nonef.py +0 -0
  80. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/misc/random.py +0 -0
  81. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/print/jinjaf.py +0 -0
  82. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/print/print_line.py +0 -0
  83. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/print/print_queue.py +0 -0
  84. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/print/printf.py +0 -0
  85. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/print/table.py +0 -0
  86. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/stats/correlate.py +0 -0
  87. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/stats/minf.py +0 -0
  88. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/stats/percent.py +0 -0
  89. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  90. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/stats/stdev.py +0 -0
  91. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/concat.py +0 -0
  92. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/length.py +0 -0
  93. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/lower.py +0 -0
  94. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/metaphone.py +0 -0
  95. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/num.py +0 -0
  96. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/regex.py +0 -0
  97. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/starts_with.py +0 -0
  98. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/strip.py +0 -0
  99. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/substring.py +0 -0
  100. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/upper.py +0 -0
  101. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/testing/debug.py +0 -0
  102. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/validation.py +0 -0
  103. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/validity/fail.py +0 -0
  104. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/validity/failed.py +0 -0
  105. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/variables/get.py +0 -0
  106. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/variables/pushpop.py +0 -0
  107. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/variables/put.py +0 -0
  108. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/variables/track.py +0 -0
  109. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/variables/variables.py +0 -0
  110. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/lark_parser.py +0 -0
  111. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/lark_transformer.py +0 -0
  112. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/matcher.py +0 -0
  113. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/__init__.py +0 -0
  114. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/equality.py +0 -0
  115. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/expression.py +0 -0
  116. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/header.py +0 -0
  117. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/qualified.py +0 -0
  118. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/reference.py +0 -0
  119. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/term.py +0 -0
  120. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/variable.py +0 -0
  121. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/util/exceptions.py +0 -0
  122. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/util/expression_encoder.py +0 -0
  123. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/util/expression_utility.py +0 -0
  124. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/util/lark_print_parser.py +0 -0
  125. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/util/print_parser.py +0 -0
  126. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/scanning/__init__.py +0 -0
  127. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/scanning/exceptions.py +0 -0
  128. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/scanning/parser.out +0 -0
  129. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/scanning/parsetab.py +0 -0
  130. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/scanning/scanner.py +0 -0
  131. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/scanning/scanning_lexer.py +0 -0
  132. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/cache.py +0 -0
  133. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/config_exception.py +0 -0
  134. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/error.py +0 -0
  135. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/exceptions.py +0 -0
  136. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/last_line_stats.py +0 -0
  137. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/line_counter.py +0 -0
  138. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/line_monitor.py +0 -0
  139. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/log_utility.py +0 -0
  140. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/metadata_parser.py +0 -0
  141. {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/printer.py +0 -0
  142. {csvpath-0.0.471 → csvpath-0.0.472}/docs/asbool.md +0 -0
  143. {csvpath-0.0.471 → csvpath-0.0.472}/docs/assignment.md +0 -0
  144. {csvpath-0.0.471 → csvpath-0.0.472}/docs/config.md +0 -0
  145. {csvpath-0.0.471 → csvpath-0.0.472}/docs/examples.md +0 -0
  146. {csvpath-0.0.471 → csvpath-0.0.472}/docs/files.md +0 -0
  147. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/above.md +0 -0
  148. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/after_blank.md +0 -0
  149. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/all.md +0 -0
  150. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/andor.md +0 -0
  151. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/any.md +0 -0
  152. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/average.md +0 -0
  153. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/between.md +0 -0
  154. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/collect.md +0 -0
  155. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/correlate.md +0 -0
  156. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/count.md +0 -0
  157. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/count_headers.md +0 -0
  158. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/date.md +0 -0
  159. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/empty.md +0 -0
  160. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/empty_stack.md +0 -0
  161. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/end.md +0 -0
  162. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/every.md +0 -0
  163. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/fail.md +0 -0
  164. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/first.md +0 -0
  165. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/get.md +0 -0
  166. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/has_dups.md +0 -0
  167. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/header.md +0 -0
  168. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/header_name.md +0 -0
  169. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/header_names_mismatch.md +0 -0
  170. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/in.md +0 -0
  171. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/increment.md +0 -0
  172. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/jinja.md +0 -0
  173. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/last.md +0 -0
  174. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/line_number.md +0 -0
  175. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/max.md +0 -0
  176. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/mismatch.md +0 -0
  177. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/no.md +0 -0
  178. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/not.md +0 -0
  179. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/now.md +0 -0
  180. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/percent_unique.md +0 -0
  181. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/pop.md +0 -0
  182. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/print.md +0 -0
  183. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/print_line.md +0 -0
  184. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/print_queue.md +0 -0
  185. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/regex.md +0 -0
  186. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/replace.md +0 -0
  187. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/reset_headers.md +0 -0
  188. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/stdev.md +0 -0
  189. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/stop.md +0 -0
  190. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/string_functions.md +0 -0
  191. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/subtract.md +0 -0
  192. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/sum.md +0 -0
  193. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/tally.md +0 -0
  194. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/total_lines.md +0 -0
  195. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/track.md +0 -0
  196. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/variables.md +0 -0
  197. {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/variables_and_headers.md +0 -0
  198. {csvpath-0.0.471 → csvpath-0.0.472}/docs/grammar.md +0 -0
  199. {csvpath-0.0.471 → csvpath-0.0.472}/docs/headers.md +0 -0
  200. {csvpath-0.0.471 → csvpath-0.0.472}/docs/images/logo-wordmark-white-on-black-trimmed-padded.png +0 -0
  201. {csvpath-0.0.471 → csvpath-0.0.472}/docs/images/logo-wordmark-white-trimmed.png +0 -0
  202. {csvpath-0.0.471 → csvpath-0.0.472}/docs/qualifiers.md +0 -0
  203. {csvpath-0.0.471 → csvpath-0.0.472}/docs/terms.md +0 -0
  204. {csvpath-0.0.471 → csvpath-0.0.472}/docs/variables.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: csvpath
3
- Version: 0.0.471
3
+ Version: 0.0.472
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
@@ -38,6 +38,7 @@ class Matchable(Qualified):
38
38
  return name
39
39
 
40
40
  def _noop_match(self) -> bool:
41
+ """deprecated. use self.default_match()"""
41
42
  return self.match if self.match is not None else True
42
43
 
43
44
  def _noop_value(self) -> bool:
@@ -122,5 +123,14 @@ class Matchable(Qualified):
122
123
  # with the current parse tree this shouldn't happen
123
124
  return None
124
125
 
126
+ def _siblings(self) -> list:
127
+ if len(self.children) and hasattr(self.children[0], "op"):
128
+ return self.children[0].commas_to_list()
129
+ else:
130
+ self.matcher.csvpath.error(
131
+ "Cannot get siblings. children[0] is not an Equality"
132
+ )
133
+ return None
134
+
125
135
  def default_match(self) -> bool:
126
136
  return self.matcher._AND
@@ -76,7 +76,7 @@ class Config:
76
76
  def config_path(self) -> str:
77
77
  return self._configpath
78
78
 
79
- def _get(self, section: str, name: str, quiet: bool = True):
79
+ def _get(self, section: str, name: str):
80
80
  if self._config is None:
81
81
  raise ConfigurationException("No config object available")
82
82
  try:
@@ -89,10 +89,9 @@ class Config:
89
89
  ret = s
90
90
  return ret
91
91
  except KeyError:
92
- if not quiet:
93
- raise ConfigurationException(
94
- f"Check config at {self.config_path} for [{section}][{name}]"
95
- )
92
+ raise ConfigurationException(
93
+ f"Check config at {self.config_path} for [{section}][{name}]"
94
+ )
96
95
 
97
96
  def _create_default_config(self) -> None:
98
97
  if not path.exists("config"):
@@ -137,12 +136,12 @@ path =
137
136
 
138
137
  def _assure_cache_path(self) -> None:
139
138
  dirpath = self.cache_dir_path
140
- if dirpath is None:
141
- dirpath == "cache"
142
- self._config.add_section("cache")
143
- self._config.set("cache", "path", dirpath)
144
139
  if dirpath and not path.exists(dirpath):
145
140
  os.makedirs(dirpath)
141
+ elif not dirpath:
142
+ raise ConfigurationException(
143
+ "No cache path available. Check config.ini [cache][path]."
144
+ )
146
145
 
147
146
  def _assure_config_file_path(self) -> None:
148
147
  if not self._configpath or not os.path.isfile(self._configpath):
@@ -265,11 +264,13 @@ path =
265
264
 
266
265
  @property
267
266
  def cache_dir_path(self) -> str:
268
- path = self._get("cache", "path", quiet=True)
269
- #
270
- # for now we can let this fail silently. if there is no
271
- # cache dir we just don't cache.
272
- #
267
+ try:
268
+ path = self._get("cache", "path")
269
+ except Exception:
270
+ print("No cache path in config.ini at [cache][path]. Using 'cache'.")
271
+ path = "config"
272
+ self._config.add_section("cache")
273
+ self._config.set("cache", "path", path)
273
274
  return path
274
275
 
275
276
  @property
@@ -20,7 +20,7 @@ One way to run it looks like this, using dict objects to identify the csvpaths a
20
20
 
21
21
  ```python
22
22
  paths = CsvPaths()
23
- paths.files_manager.set_named_files(nf)
23
+ paths.file_manager.set_named_files(nf)
24
24
  paths.paths_manager.set_named_paths(np)
25
25
  lines = paths.collect_paths(pathsname="sample", filename="survey")
26
26
  ```
@@ -0,0 +1,17 @@
1
+
2
+ # Has matches
3
+
4
+ `has_matches()` returns `True` when there have been previous matches. It is a convenience function, since you can achieve the same result with `count()` and other functions; although not quite as simply.
5
+
6
+ ## Examples
7
+
8
+ $people.csv[*][
9
+ ~ Apply three rules to check if a CSV file is invalid ~
10
+ missing(headers())
11
+ too_long(#lastname, 30)
12
+ not.nocontrib( header_name(0, "firstname") ) -> fail()
13
+ has_matches.nocontrib() -> fail()
14
+ ]
15
+
16
+ This csvpath fails a file if any of the other match components match on any line.
17
+
@@ -0,0 +1,107 @@
1
+
2
+ # How to create a function
3
+
4
+ You can easily create your own function, register it for use, and use it in your csvpaths.
5
+
6
+ Functions are descendants of the Function class. Most of the built-ins extend one of:
7
+ - ValueProducer - for functions that mainly generate information
8
+ - MatchDecider - for functions that mainly do a true/false response to information
9
+ - SideEffect - for functions that don't add or consider information in the current line, but rather have some side effect such as printing, setting validity, advancing lines, etc.
10
+
11
+ These three classes are only indicators. You can extend Function directly.
12
+
13
+ from csvpath.matching.functions.function import Function
14
+ class MyFunction(Function):
15
+ ...
16
+
17
+ Function implementations override three methods:
18
+
19
+ - `_produce_value(self, skip=[])` - produces the value of the function
20
+ - `_decide_match(self, skip=[])` - determines if the function contributes to a row matching the csvpath
21
+ - `check_valid(self)` - raises an exception if the function is configured incorrectly
22
+
23
+ The first two methods may be called multiple times per row due to checking qualifier constraints, principally `onmatch`, or for other reasons. When a function checks to see if the other csvpath components all match it passes itself in the skip list. The skip list is a list of match components that should not perform their usual calculations if they find themselves in the list. If your function finds itself in the skip list it should immediately return. The return value should be:
24
+
25
+ - `self.value` for `_produce_value`
26
+ - `self.default_match()` for `matches`
27
+
28
+ Usually you want to cache the result of calculating `to_value` and `matches`. Two variables are provided for caching. It is important to set them to a non-None value in order to prevent your function running multiple times.
29
+
30
+ - self.value
31
+ - self.match
32
+
33
+ ## Qualifiers
34
+
35
+ Qualifiers are available to your function. They are accessed using the methods in the Qualified class. Qualified is an ancestor of Function. The most relevant capabilities are:
36
+
37
+ - first_non_term_qualifier()
38
+ - qualifiers
39
+
40
+ The former will get you a non-built-in qualifier. The `qualifiers` property gives you access to all qualifiers.
41
+
42
+ All match components support the `onmatch` qualifier. All components support the `nocontrib` when they are on the left-hand side of a when/do (`->`) operation.
43
+
44
+ ## Arguments Validation
45
+
46
+ Validation is an important step that happens before any rows are considered. It allows for structural csvpath problems to be discovered before you start processing files. The validity checks only address the number of children and the type of children. You cannot check types or values ofdata provided by child match components because the match components are not setup yet and there is no data at the time validation happens.
47
+
48
+ The most common validations are methods available on the `Validation` class. `Validation` is an ancestor class of Function.
49
+
50
+
51
+ ## Example
52
+
53
+ A very simple function might look like:
54
+
55
+ ```python
56
+ class MyFunction(Function):
57
+ def _produce_value(self, skip=[]) -> None:
58
+ v = self.calculate_stuff()
59
+ self.value = v
60
+
61
+ def _decide_match(self, skip=[]) -> None:
62
+ m = self.calculate_stuff()
63
+ self.match = result
64
+
65
+ def check_valid(self) -> None:
66
+ self.validate_zero_args()
67
+ # you must call check_valid so that your
68
+ # function's children are validated.
69
+ super().check_valid()
70
+ ```
71
+
72
+ When your function's match depends on its value, or its value depends on its match, it needs to call the appropriate method:
73
+ - To get the value, call self.to_value(skip=skip)
74
+ - To check the match, call self.matches(skip=skip)
75
+
76
+ When your function needs its arguments you can call:
77
+ - self._child_one()
78
+ - self._value_one(skip=skip)
79
+ - self._child_two()
80
+ - self._value_two(skip=skip)
81
+ - self._siblings()
82
+
83
+ When you need to get a value or a match from a child object you use `to_value()` or `matches()`. Remember to pass the skip list as a named argument "skip".
84
+
85
+ ## Registering
86
+
87
+ To register your function for use, add it to the FunctionFactory like this:
88
+
89
+ ```python
90
+ from csvpath.matching.functions.function_factory import FunctionFactory
91
+ FunctionFactory.add_function(name='iamafunction', function=my_function_instance)
92
+ ```
93
+
94
+ To use your function do something like:
95
+
96
+ ```bash
97
+ "$test[*][ @t = iamafunction() ]"
98
+ ```
99
+
100
+ Behind the scenes an instance of your function will be retrieved with:
101
+
102
+ ```python
103
+ f = FunctionFactory.get_function(matcher=None, name="iamafunction")
104
+ ```
105
+
106
+ The name you set on FunctionFactory must match the name passed in when a function is requested.
107
+
@@ -17,7 +17,7 @@ Let's set up the Python to run the simplest import test:
17
17
 
18
18
  ```python
19
19
  cs = CsvPaths()
20
- cs.files_manager.add_named_files_from_dir("./csvs")
20
+ cs.file_manager.add_named_files_from_dir("./csvs")
21
21
  cs.paths_manager.add_named_paths_from_dir("./csvpaths")
22
22
  cs.fast_forward_by_line(filename="food", pathsname="import")
23
23
  vars = cs.results_manager.get_variables("import")
@@ -25,7 +25,7 @@ To set up a canonicalization match component takes a bit more effort, but not to
25
25
 
26
26
  ```python
27
27
  paths = CsvPaths()
28
- paths.files_manager.add_named_file(
28
+ paths.file_manager.add_named_file(
29
29
  name="lookups", path="tests/test_resources/named_files/lookup_names.csv"
30
30
  )
31
31
  paths.paths_manager.add_named_paths_from_file(
@@ -85,6 +85,7 @@ There are lots more simple examples on the individual function pages.
85
85
  <tr><td> count_lines() </td><td> count the lines of data to this point in the file. </td></tr>
86
86
  <tr><td> count_scans() </td><td> count lines we checked for match </td></tr>
87
87
  <tr><td> <a href='https://github.com/dk107dk/csvpath/blob/main/docs/functions/has_dups.md'>count_dups(header, ...)</a> </td><td> Returns the number of duplicate lines. </td></tr>
88
+ <tr><td> <a href='https://github.com/dk107dk/csvpath/blob/main/docs/functions/has_matches.md'>has_matches(header, ...)</a> </td><td> Matches when any other match component matched anywhere in the file. </td></tr>
88
89
  <tr><td> <a href='https://github.com/dk107dk/csvpath/blob/main/docs/functions/line_number.md'>line_number()</a> </td><td> Gives the physical line number. </td></tr>
89
90
  <tr><td> <a href='https://github.com/dk107dk/csvpath/blob/main/docs/functions/increment.md'>increment(value, n)</a> </td><td> Increments a variable by n each time seen. </td></tr>
90
91
  <tr><td> <a href='https://github.com/dk107dk/csvpath/blob/main/docs/functions/every.md'>every(value, number)</a> </td><td> Matches every Nth time a value is seen. </td></tr>
@@ -60,7 +60,7 @@ A named path can reference a named file. To extend our example with named files:
60
60
  }
61
61
 
62
62
  paths = CsvPaths()
63
- paths.files_manager.set_named_files(nf)
63
+ paths.file_manager.set_named_files(nf)
64
64
  paths.paths_manager.set_named_paths(np)
65
65
 
66
66
  path = paths.csvpath()
@@ -105,7 +105,7 @@ We can apply them breadth-first using this code:
105
105
 
106
106
  ```python
107
107
  cs = CsvPaths()
108
- cs.files_manager.set_named_files(FILES)
108
+ cs.file_manager.set_named_files(FILES)
109
109
  cs.paths_manager.add_named_paths_from_dir(NAMED_PATHS_DIR)
110
110
  for line in cs.next_by_line(filename="food", pathsname="many"):
111
111
  valid = cs.results_manager.is_valid("many")
@@ -40,7 +40,7 @@ This reference points to the `total` variable resulting from the most recent Csv
40
40
 
41
41
  ```python
42
42
  cs = CsvPaths()
43
- cs.files_manager.add_named_files_from_dir(NAMED_FILES_DIR)
43
+ cs.file_manager.add_named_files_from_dir(NAMED_FILES_DIR)
44
44
  cs.paths_manager.add_named_paths_from_dir(NAMED_PATHS_DIR)
45
45
  cs.fast_forward_paths(filename="orders", pathsname="shipping-validations")
46
46
  #
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "csvpath"
3
- version = "0.0.471"
3
+ version = "0.0.472"
4
4
  description = "A declarative language for data extraction and validation of CSV files"
5
5
  authors = ["David Kershaw <dk107dk@hotmail.com>"]
6
6
  readme = "README.md"
@@ -1,85 +0,0 @@
1
-
2
- # How to create a function
3
-
4
- You can easily create your own function, register it for use, and use it in your csvpaths.
5
-
6
- Functions extend the Function class using:
7
-
8
- from csvpath.matching.functions.function import Function
9
- class MyFunction(Function):
10
- ...
11
-
12
- Function implementations override three methods:
13
-
14
- - `to_value(self, skip=[])` - produces the value of the function
15
- - `matches(self, skip=[])` - determines if the function contributes to a row matching the csvpath
16
- - `check_valid(self)` - raises an exception if the function is configured incorrectly
17
-
18
- The first two methods may be called multiple times per row due to checking qualifier constraints, principally `onmatch`, or for other reasons. When a function checks to see if the other csvpath components all match it passes itself in the skip list. The skip list is a list of match components that should not perform their usual calculations if they find themselves in the list. If your function finds itself in the skip list it should return:
19
-
20
- - `self.value` for `to_value`
21
- - `True` for `matches` - this makes sure your function isn't asking itself if it matches
22
-
23
- Usually you want to cache the result of calculating `to_value` and `matches`. Two variables are provided for caching:
24
-
25
- - self.value
26
- - self.match
27
-
28
- Validation is an important step that happens before any rows are considered. It allows for structural csvpath problems to be discovered before you start processing files. The most common validations are available on the Validation class within Function's class hierarchy.
29
-
30
- Your function must inherit from Function. It may implement `__init__` and take a `Matcher` object and a string name.
31
-
32
- ## Example
33
-
34
- A very simple function might look like:
35
-
36
- ```python
37
- class MyFunction(Function):
38
- def to_value(self, skip=[]):
39
- if self in skip:
40
- return self._noop_value()
41
-
42
- if self.value is None:
43
- #
44
- self.calculate_stuff()
45
- #
46
- return self.value
47
-
48
- def matches(self, skip=[]):
49
- if self in skip:
50
- return self._noop_match()
51
- if self.match is None:
52
- #
53
- self.calculate_stuff()
54
- #
55
- return self.match
56
-
57
- def check_valid(self) -> None:
58
- self.validate_zero_args()
59
- super().check_valid()
60
- ```
61
-
62
- In the common case the match depends on the value. In some cases, however, the value depends on the match. When the value is dependent and your function finds itself in the skip list return a call to `self.match()`; otherwise, call `self._noop_value()`. In either case when the match finds `self` in the skip list it should return `self._noop_match()`.
63
-
64
- ## Registering
65
-
66
- To register your function for use, add it to the FunctionFactory like this:
67
-
68
- ```python
69
- FunctionFactory.add_function(name='iamafunction', function=my_function_instance)
70
- ```
71
-
72
- To use your function do something like:
73
-
74
- ```bash
75
- "$test[*][ @t = iamafunction() ]"
76
- ```
77
-
78
- Behind the scenes an instance of your function will be retrieved with:
79
-
80
- ```python
81
- f = FunctionFactory.get_function(matcher=None, name="iamafunction")
82
- ```
83
-
84
- The name you set on FunctionFactory must match the name passed in when a function is requested.
85
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes