csvpath 0.0.455__tar.gz → 0.0.457__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 (193) hide show
  1. {csvpath-0.0.455 → csvpath-0.0.457}/PKG-INFO +1 -1
  2. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/csvpath.py +31 -13
  3. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/strings/length.py +2 -1
  4. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/validation.py +0 -1
  5. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/lark_transformer.py +8 -1
  6. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/matcher.py +25 -33
  7. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/util/config.py +15 -15
  8. {csvpath-0.0.455 → csvpath-0.0.457}/pyproject.toml +1 -1
  9. {csvpath-0.0.455 → csvpath-0.0.457}/LICENSE +0 -0
  10. {csvpath-0.0.455 → csvpath-0.0.457}/README.md +0 -0
  11. {csvpath-0.0.455 → csvpath-0.0.457}/config/config.ini +0 -0
  12. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/__init__.py +0 -0
  13. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/csvpaths.py +0 -0
  14. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/managers/__init__.py +0 -0
  15. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/managers/csvpath_result.py +0 -0
  16. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/managers/csvpaths_manager.py +0 -0
  17. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/managers/files_manager.py +0 -0
  18. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/managers/results_manager.py +0 -0
  19. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/__init__.py +0 -0
  20. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/__init__.py +0 -0
  21. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/boolean/all.py +0 -0
  22. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/boolean/andf.py +0 -0
  23. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/boolean/any.py +0 -0
  24. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/boolean/between.py +0 -0
  25. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/boolean/empty.py +0 -0
  26. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/boolean/exists.py +0 -0
  27. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/boolean/inf.py +0 -0
  28. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/boolean/no.py +0 -0
  29. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/boolean/notf.py +0 -0
  30. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/boolean/orf.py +0 -0
  31. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/boolean/yes.py +0 -0
  32. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/counting/count.py +0 -0
  33. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/counting/count_headers.py +0 -0
  34. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/counting/count_lines.py +0 -0
  35. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/counting/count_scans.py +0 -0
  36. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/counting/every.py +0 -0
  37. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/counting/increment.py +0 -0
  38. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/counting/tally.py +0 -0
  39. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/counting/total_lines.py +0 -0
  40. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/function.py +0 -0
  41. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/function_factory.py +0 -0
  42. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/function_focus.py +0 -0
  43. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/headers/end.py +0 -0
  44. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/headers/header_name.py +0 -0
  45. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
  46. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/headers/headers.py +0 -0
  47. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/headers/mismatch.py +0 -0
  48. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/headers/reset_headers.py +0 -0
  49. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/lines/advance.py +0 -0
  50. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/lines/after_blank.py +0 -0
  51. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/lines/dups.py +0 -0
  52. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/lines/first.py +0 -0
  53. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/lines/first_line.py +0 -0
  54. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/lines/last.py +0 -0
  55. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/lines/stop.py +0 -0
  56. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/math/above.py +0 -0
  57. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/math/add.py +0 -0
  58. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/math/divide.py +0 -0
  59. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/math/equals.py +0 -0
  60. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/math/mod.py +0 -0
  61. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/math/multiply.py +0 -0
  62. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/math/round.py +0 -0
  63. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/math/subtract.py +0 -0
  64. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/math/sum.py +0 -0
  65. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/collect.py +0 -0
  66. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/datef.py +0 -0
  67. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/get.py +0 -0
  68. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/importf.py +0 -0
  69. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/intf.py +0 -0
  70. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/nonef.py +0 -0
  71. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/now.py +0 -0
  72. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/pushpop.py +0 -0
  73. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/random.py +0 -0
  74. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/regex.py +0 -0
  75. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/replace.py +0 -0
  76. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/track.py +0 -0
  77. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/misc/variables.py +0 -0
  78. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/print/jinjaf.py +0 -0
  79. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/print/print_line.py +0 -0
  80. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/print/print_queue.py +0 -0
  81. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/print/printf.py +0 -0
  82. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/stats/correlate.py +0 -0
  83. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/stats/minf.py +0 -0
  84. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/stats/percent.py +0 -0
  85. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  86. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/stats/stdev.py +0 -0
  87. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/strings/concat.py +0 -0
  88. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/strings/lower.py +0 -0
  89. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/strings/metaphone.py +0 -0
  90. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/strings/starts_with.py +0 -0
  91. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/strings/strip.py +0 -0
  92. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/strings/substring.py +0 -0
  93. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/strings/upper.py +0 -0
  94. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/validity/fail.py +0 -0
  95. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/functions/validity/failed.py +0 -0
  96. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/lark_parser.py +0 -0
  97. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/productions/__init__.py +0 -0
  98. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/productions/equality.py +0 -0
  99. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/productions/expression.py +0 -0
  100. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/productions/header.py +0 -0
  101. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/productions/matchable.py +0 -0
  102. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/productions/qualified.py +0 -0
  103. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/productions/reference.py +0 -0
  104. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/productions/term.py +0 -0
  105. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/productions/variable.py +0 -0
  106. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/util/exceptions.py +0 -0
  107. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/util/expression_encoder.py +0 -0
  108. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/util/expression_utility.py +0 -0
  109. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/util/lark_print_parser.py +0 -0
  110. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/matching/util/print_parser.py +0 -0
  111. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/scanning/__init__.py +0 -0
  112. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/scanning/exceptions.py +0 -0
  113. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/scanning/parser.out +0 -0
  114. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/scanning/parsetab.py +0 -0
  115. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/scanning/scanner.py +0 -0
  116. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/scanning/scanning_lexer.py +0 -0
  117. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/util/config_exception.py +0 -0
  118. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/util/error.py +0 -0
  119. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/util/exceptions.py +0 -0
  120. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/util/last_line_stats.py +0 -0
  121. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/util/line_monitor.py +0 -0
  122. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/util/log_utility.py +0 -0
  123. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/util/metadata_parser.py +0 -0
  124. {csvpath-0.0.455 → csvpath-0.0.457}/csvpath/util/printer.py +0 -0
  125. {csvpath-0.0.455 → csvpath-0.0.457}/docs/asbool.md +0 -0
  126. {csvpath-0.0.455 → csvpath-0.0.457}/docs/assignment.md +0 -0
  127. {csvpath-0.0.455 → csvpath-0.0.457}/docs/config.md +0 -0
  128. {csvpath-0.0.455 → csvpath-0.0.457}/docs/examples.md +0 -0
  129. {csvpath-0.0.455 → csvpath-0.0.457}/docs/files.md +0 -0
  130. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/above.md +0 -0
  131. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/advance.md +0 -0
  132. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/after_blank.md +0 -0
  133. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/all.md +0 -0
  134. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/andor.md +0 -0
  135. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/any.md +0 -0
  136. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/average.md +0 -0
  137. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/between.md +0 -0
  138. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/collect.md +0 -0
  139. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/correlate.md +0 -0
  140. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/count.md +0 -0
  141. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/count_headers.md +0 -0
  142. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/date.md +0 -0
  143. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/empty.md +0 -0
  144. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/end.md +0 -0
  145. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/every.md +0 -0
  146. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/fail.md +0 -0
  147. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/first.md +0 -0
  148. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/get.md +0 -0
  149. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/has_dups.md +0 -0
  150. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/header.md +0 -0
  151. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/header_name.md +0 -0
  152. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/header_names_mismatch.md +0 -0
  153. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/implementing_functions.md +0 -0
  154. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/import.md +0 -0
  155. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/in.md +0 -0
  156. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/increment.md +0 -0
  157. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/jinja.md +0 -0
  158. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/last.md +0 -0
  159. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/line_number.md +0 -0
  160. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/max.md +0 -0
  161. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/metaphone.md +0 -0
  162. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/mismatch.md +0 -0
  163. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/no.md +0 -0
  164. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/not.md +0 -0
  165. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/now.md +0 -0
  166. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/percent_unique.md +0 -0
  167. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/pop.md +0 -0
  168. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/print.md +0 -0
  169. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/print_line.md +0 -0
  170. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/print_queue.md +0 -0
  171. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/regex.md +0 -0
  172. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/replace.md +0 -0
  173. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/reset_headers.md +0 -0
  174. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/stdev.md +0 -0
  175. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/stop.md +0 -0
  176. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/string_functions.md +0 -0
  177. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/subtract.md +0 -0
  178. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/sum.md +0 -0
  179. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/tally.md +0 -0
  180. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/total_lines.md +0 -0
  181. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/track.md +0 -0
  182. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/variables.md +0 -0
  183. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions/variables_and_headers.md +0 -0
  184. {csvpath-0.0.455 → csvpath-0.0.457}/docs/functions.md +0 -0
  185. {csvpath-0.0.455 → csvpath-0.0.457}/docs/grammar.md +0 -0
  186. {csvpath-0.0.455 → csvpath-0.0.457}/docs/headers.md +0 -0
  187. {csvpath-0.0.455 → csvpath-0.0.457}/docs/images/logo-wordmark-white-on-black-trimmed-padded.png +0 -0
  188. {csvpath-0.0.455 → csvpath-0.0.457}/docs/images/logo-wordmark-white-trimmed.png +0 -0
  189. {csvpath-0.0.455 → csvpath-0.0.457}/docs/paths.md +0 -0
  190. {csvpath-0.0.455 → csvpath-0.0.457}/docs/qualifiers.md +0 -0
  191. {csvpath-0.0.455 → csvpath-0.0.457}/docs/references.md +0 -0
  192. {csvpath-0.0.455 → csvpath-0.0.457}/docs/terms.md +0 -0
  193. {csvpath-0.0.455 → csvpath-0.0.457}/docs/variables.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: csvpath
3
- Version: 0.0.455
3
+ Version: 0.0.457
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
@@ -114,26 +114,27 @@ class CsvPath(CsvPathPublic): # pylint: disable=R0902, R0904
114
114
  #
115
115
  self.match = None
116
116
  #
117
+ # when AND is True we do a logical AND of the match components
118
+ # to see if there is a match. this is the default. when AND is
119
+ # False (or set OR to True) the match components are ORed to
120
+ # determine if a line matches. in the former case all the match
121
+ # components must agree for a line to match. in the latter case,
122
+ # if any one match component votes True the line is matched.
123
+ # technically you can switch from AND to OR, or vice versa, in
124
+ # the middle of iterating a file using next(). probably not a
125
+ # good idea, tho.
126
+ #
127
+ self._AND = True
128
+ #
117
129
  # when True the lines that do not match are returned from next()
118
130
  # and collect(). this effectively switches CsvPath from being an
119
- # AND machine to being an OR machine; though we do not actually
120
- # create an OR expression. in the default, we say:
131
+ # AND machine to being a NOT AND machine. we do not actually
132
+ # create an OR expression in this case. in the default, we say:
121
133
  # are all of these things true?
122
134
  # but when collect_when_not_matched is True we ask:
123
135
  # are any of these things not true?
124
136
  #
125
137
  self._when_not_matched = False
126
- #
127
- # note-to-self: by default CsvPath's matcher does an AND match. if
128
- # we set this property to True we tell the matcher to do an OR.
129
- # i.e. if any of the match components return true there is a match.
130
- # HOWEVER, this would be a big change because default values and
131
- # nocontrib would have to be negative when ORing. we don't have a
132
- # way to do that today -- defaults aren't completely centralized.
133
- # they are, easy.
134
- #
135
- # self._or_match = False
136
- #
137
138
  self.headers = None
138
139
  self.variables: Dict[str, Any] = {}
139
140
  self.delimiter = delimiter
@@ -247,6 +248,22 @@ class CsvPath(CsvPathPublic): # pylint: disable=R0902, R0904
247
248
  self.logger = LogUtility.logger(self)
248
249
  self.logger.info("initialized CsvPath")
249
250
 
251
+ @property
252
+ def AND(self) -> bool:
253
+ return self._AND
254
+
255
+ @AND.setter
256
+ def AND(self, a: bool) -> bool:
257
+ self._AND = a
258
+
259
+ @property
260
+ def OR(self) -> bool:
261
+ return not self._AND
262
+
263
+ @OR.setter
264
+ def OR(self, a: bool) -> bool:
265
+ self._AND = not a
266
+
250
267
  @property
251
268
  def identity(self) -> str:
252
269
  """returns id or name if found in metadata. the id or name gets
@@ -857,6 +874,7 @@ class CsvPath(CsvPathPublic): # pylint: disable=R0902, R0904
857
874
  self.matcher = Matcher(
858
875
  csvpath=self, data=self.match, line=line, headers=self.headers, myid=h
859
876
  )
877
+ self.matcher._AND = self._AND
860
878
  else:
861
879
  self.logger.debug("Resetting and reloading matcher")
862
880
  self.matcher.reset()
@@ -45,4 +45,5 @@ class MinMaxLength(ValueProducer): # pylint: disable=C0115
45
45
  return self.value
46
46
 
47
47
  def _decide_match(self, skip=None) -> None:
48
- self.match = self.to_value(skip=skip) > 0
48
+ v = self.to_value(skip=skip)
49
+ self.match = v
@@ -180,7 +180,6 @@ class Validation(Matchable):
180
180
  if hasattr(self.children[0].right, "op"):
181
181
  raise ChildrenException(f"{self.name}() can only have 2 arguments")
182
182
  if len(left) > 0:
183
- print(f"validate: 183: {self.children[0].left} === {left}")
184
183
  if not self._class_match(self.children[0].left, left):
185
184
  raise ChildrenException(
186
185
  f"{self.name}() must have a first argument of type: {left}"
@@ -24,13 +24,20 @@ class LarkTransformer(Transformer): # pylint: disable=C0115
24
24
  super().__init__()
25
25
 
26
26
  def match(self, *expressions): # pylint: disable=C0116
27
- return list(expressions)
27
+ return [e for e in list(expressions) if e is not None]
28
28
 
29
29
  # left (WHEN action)?
30
30
  # equality (WHEN action)?
31
31
  # assignment
32
32
  # COMMENT
33
33
  def expression(self, acted_on, when=None, action=None): # pylint: disable=C0116
34
+ # print(f"expression: acted_on: {acted_on}, when: {when}, action: {action}")
35
+ if acted_on is None and when is None and action is None:
36
+ # this is a comment
37
+ return None
38
+ #
39
+ #
40
+ #
34
41
  e = Expression(self.matcher)
35
42
  if when is None:
36
43
  e.add_child(acted_on)
@@ -30,6 +30,7 @@ class Matcher: # pylint: disable=R0902
30
30
  self.if_all_match = []
31
31
  self.skip = False
32
32
  self.cachers = []
33
+ self._AND = True
33
34
  if data is not None:
34
35
  self.parser = LarkParser()
35
36
  tree = self.parser.parse(data)
@@ -126,7 +127,7 @@ class Matcher: # pylint: disable=R0902
126
127
  _.clear_caches()
127
128
  self.cachers = []
128
129
 
129
- def matches(self, *, syntax_only=False) -> bool:
130
+ def matches(self) -> bool:
130
131
  """this is the main work of the Matcher. we enumerate the self.expressions.
131
132
  if all evaluate to True in an AND operation we return True."""
132
133
  #
@@ -134,22 +135,25 @@ class Matcher: # pylint: disable=R0902
134
135
  # last() in the csvpath.
135
136
  #
136
137
  if self.csvpath.line_monitor.is_last_line_and_blank(self.line):
137
- # if self.csvpath.line_monitor.is_last_line_and_empty(self.line):
138
138
  self.csvpath.logger.debug(
139
139
  "Is last line and blank. Doing lasts and then returning True"
140
140
  )
141
141
  self._do_lasts()
142
142
  return True
143
143
  ret = True
144
- failed = False
144
+ failed = False if self._AND else True
145
145
  self.csvpath.logger.debug(
146
- "beginning to match against line[%s]: %s",
146
+ "Beginning %s match against line[%s]: %s",
147
+ ("AND" if self._AND else "OR"),
147
148
  self.csvpath.line_monitor.physical_line_number,
148
149
  str(self.line),
149
150
  )
150
151
  for i, et in enumerate(self.expressions):
151
152
  self.csvpath.logger.debug(
152
- "Beginning to consider expression: et[%s]: %s: %s", i, et[0], et[1]
153
+ "Beginning to consider expression: expressions[%s]: %s: %s",
154
+ i,
155
+ et[0],
156
+ et[1],
153
157
  )
154
158
  if self.csvpath and self.csvpath.stopped:
155
159
  #
@@ -172,28 +176,31 @@ class Matcher: # pylint: disable=R0902
172
176
  self.csvpath.logger.debug("Skipping at line %s", pln)
173
177
  self.skip = False
174
178
  return False
179
+ #
180
+ # from here down we care what the expression tells us.
181
+ # we can require concordance or we can allow executive
182
+ # decisons.
183
+ #
175
184
  if et[1] is True:
176
185
  ret = True
177
186
  elif et[1] is False:
178
187
  ret = False
179
- elif not et[0].matches(skip=[]) and not syntax_only:
188
+ elif et[0].matches(skip=[]) is False:
180
189
  et[1] = False
181
190
  ret = False
182
191
  else:
183
192
  et[1] = True
184
193
  ret = True
185
- if not ret:
186
- failed = True
187
194
  #
188
- # if we're failed we need to (re)set ret in case this is the final iteration.
195
+ # now ret holds this expression's vote
189
196
  #
190
- if failed:
191
- ret = False
192
- if ret is True:
193
- self.csvpath.logger.debug("Setting any vars deferred till match")
194
- self.do_set_if_all_match()
195
- else:
196
- pass
197
+ pln = self.csvpath.line_monitor.physical_line_number
198
+ if self._AND:
199
+ if ret is False:
200
+ failed = True
201
+ else:
202
+ if ret is True:
203
+ failed = False
197
204
  #
198
205
  # here we could be set to do an OR, not an AND.
199
206
  # we would do that only in the case that the answer was False. if so, we
@@ -201,28 +208,13 @@ class Matcher: # pylint: disable=R0902
201
208
  # were found, we would respond True; else, False.
202
209
  #
203
210
  pln = self.csvpath.line_monitor.physical_line_number
204
- self.csvpath.logger.debug("Match result for line %s: %s", pln, ret)
205
- return ret
211
+ self.csvpath.logger.debug("Match result for line %s: %s", pln, failed)
212
+ return not failed
206
213
 
207
214
  def check_valid(self) -> None: # pylint: disable=C0116
208
215
  for _ in self.expressions:
209
216
  _[0].check_valid()
210
217
 
211
- def do_set_if_all_match(self) -> None: # pylint: disable=C0116
212
- for _ in self.if_all_match:
213
- name = _[0]
214
- value = _[1]
215
- tracking = _[2]
216
- self.set_variable(name, value=value, tracking=tracking)
217
- self.if_all_match = []
218
-
219
- def set_if_all_match(self, name: str, value: Any, tracking=None) -> None:
220
- """registers a variable set to happen only after the line's consideration
221
- is complete and it is found to match. this is used for setting variables
222
- when they have 'onmatch'; however, more recently we handle onmatch in
223
- another way. you can see that in Matchable."""
224
- self.if_all_match.append((name, value, tracking))
225
-
226
218
  def get_variable(self, name: str, *, tracking=None, set_if_none=None) -> Any:
227
219
  """see CsvPath.get_variable"""
228
220
  if self.csvpath is None:
@@ -98,21 +98,21 @@ class CsvPathConfig:
98
98
  os.makedirs("config")
99
99
  with open(CsvPathConfig.CONFIG, "w") as file:
100
100
  c = """
101
- [csvpath_files]
102
- extensions = txt, csvpath, csvpaths
103
- [csv_files]
104
- extensions = txt, csv, tsv, dat, tab, psv, ssv
105
- [errors]
106
- csvpath = raise, collect, stop, fail
107
- csvpaths = raise, collect
108
- [logging]
109
- csvpath = info
110
- csvpaths = info
111
- log_file = logs/csvpath.log
112
- log_files_to_keep = 100
113
- log_file_size = 52428800
114
- [config]
115
- path =
101
+ [csvpath_files]
102
+ extensions = txt, csvpath, csvpaths
103
+ [csv_files]
104
+ extensions = txt, csv, tsv, dat, tab, psv, ssv
105
+ [errors]
106
+ csvpath = raise, collect, stop, fail
107
+ csvpaths = raise, collect
108
+ [logging]
109
+ csvpath = info
110
+ csvpaths = info
111
+ log_file = logs/csvpath.log
112
+ log_files_to_keep = 100
113
+ log_file_size = 52428800
114
+ [config]
115
+ path =
116
116
  """
117
117
  file.write(c)
118
118
  print(f"Creating a default config file at {CsvPathConfig.CONFIG}.")
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "csvpath"
3
- version = "0.0.455"
3
+ version = "0.0.457"
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"
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
File without changes
File without changes