csvpath 0.0.538__tar.gz → 0.0.541__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 (314) hide show
  1. {csvpath-0.0.538 → csvpath-0.0.541}/PKG-INFO +1 -1
  2. {csvpath-0.0.538 → csvpath-0.0.541/assets}/config/config.ini +2 -2
  3. {csvpath-0.0.538/assets → csvpath-0.0.541}/config/config.ini +2 -2
  4. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/cli/function_describer.py +5 -0
  5. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/csvpath.py +19 -8
  6. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/errors/error_comms.py +9 -1
  7. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/files/file_manager.py +11 -6
  8. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ol/file_listener_ol.py +1 -1
  9. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ol/paths_listener_ol.py +2 -2
  10. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ol/result_listener_ol.py +1 -1
  11. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ol/results_listener_ol.py +1 -1
  12. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ol/run_listener_ol.py +1 -1
  13. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/paths/paths_manager.py +91 -8
  14. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/paths/paths_registrar.py +8 -9
  15. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/readers/readers.py +1 -1
  16. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/results_manager.py +16 -2
  17. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/args_helper.py +1 -1
  18. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/boolean/all.py +18 -3
  19. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/boolean/andf.py +15 -0
  20. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/boolean/any.py +28 -2
  21. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/boolean/between.py +35 -3
  22. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/boolean/empty.py +17 -2
  23. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/boolean/exists.py +18 -1
  24. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/boolean/inf.py +23 -2
  25. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/boolean/no.py +9 -0
  26. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/boolean/notf.py +12 -0
  27. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/boolean/orf.py +17 -2
  28. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/boolean/yes.py +9 -0
  29. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/counting/count.py +41 -0
  30. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/counting/count_bytes.py +12 -0
  31. csvpath-0.0.541/csvpath/matching/functions/counting/count_headers.py +44 -0
  32. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/counting/count_lines.py +22 -0
  33. csvpath-0.0.541/csvpath/matching/functions/counting/count_scans.py +32 -0
  34. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/counting/counter.py +7 -1
  35. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/counting/has_matches.py +9 -0
  36. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/counting/increment.py +17 -2
  37. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/counting/tally.py +24 -1
  38. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/counting/total_lines.py +8 -0
  39. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/dates/now.py +23 -1
  40. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/function.py +16 -2
  41. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/headers/append.py +19 -2
  42. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/headers/collect.py +26 -5
  43. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/headers/empty_stack.py +17 -1
  44. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/headers/end.py +15 -1
  45. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/headers/header_name.py +37 -3
  46. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/headers/header_names_mismatch.py +25 -9
  47. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/headers/headers.py +17 -3
  48. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/misc/fingerprint.py +48 -0
  49. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/print/printf.py +46 -8
  50. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/stats/minf.py +33 -4
  51. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/strings/concat.py +10 -0
  52. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/strings/regex.py +30 -1
  53. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/types/nonef.py +4 -3
  54. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/validity/fail.py +8 -0
  55. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/validity/failed.py +3 -0
  56. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/validity/line.py +14 -2
  57. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/variables/variables.py +9 -10
  58. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/matcher.py +6 -6
  59. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/productions/equality.py +10 -2
  60. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/productions/matchable.py +1 -1
  61. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/productions/qualified.py +13 -4
  62. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/modes/explain_mode.py +2 -2
  63. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/config.py +106 -59
  64. csvpath-0.0.541/csvpath/util/date_util.py +35 -0
  65. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/metadata_parser.py +19 -1
  66. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/nos.py +2 -0
  67. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/references/files_reference_finder.py +148 -46
  68. {csvpath-0.0.538 → csvpath-0.0.541}/pyproject.toml +1 -1
  69. csvpath-0.0.538/csvpath/matching/functions/counting/count_headers.py +0 -20
  70. csvpath-0.0.538/csvpath/matching/functions/counting/count_scans.py +0 -15
  71. {csvpath-0.0.538 → csvpath-0.0.541}/LICENSE +0 -0
  72. {csvpath-0.0.538 → csvpath-0.0.541}/README.md +0 -0
  73. {csvpath-0.0.538 → csvpath-0.0.541}/assets/config/function.imports +0 -0
  74. {csvpath-0.0.538 → csvpath-0.0.541}/assets/config/jenkins-local-azure.ini +0 -0
  75. {csvpath-0.0.538 → csvpath-0.0.541}/assets/config/jenkins-local-filesystem-mysql.ini +0 -0
  76. {csvpath-0.0.538 → csvpath-0.0.541}/assets/config/jenkins-local-filesystem.ini +0 -0
  77. {csvpath-0.0.538 → csvpath-0.0.541}/assets/config/jenkins-local-gcs.ini +0 -0
  78. {csvpath-0.0.538 → csvpath-0.0.541}/assets/config/jenkins-local-sftp.ini +0 -0
  79. {csvpath-0.0.538 → csvpath-0.0.541}/assets/config/jenkins-s3.ini +0 -0
  80. {csvpath-0.0.538 → csvpath-0.0.541}/assets/config/jenkins-windows-azure.ini +0 -0
  81. {csvpath-0.0.538 → csvpath-0.0.541}/assets/config/jenkins-windows-local.ini +0 -0
  82. {csvpath-0.0.538 → csvpath-0.0.541}/assets/config/jenkins-windows-sftp.ini +0 -0
  83. {csvpath-0.0.538 → csvpath-0.0.541}/assets/config/local-localhost-sftp.ini +0 -0
  84. {csvpath-0.0.538 → csvpath-0.0.541}/assets/integrations/sftpplus/handle_auto_arrival.bat +0 -0
  85. {csvpath-0.0.538 → csvpath-0.0.541}/assets/integrations/sftpplus/handle_auto_arrival.py +0 -0
  86. {csvpath-0.0.538 → csvpath-0.0.541}/assets/integrations/sftpplus/handle_auto_arrival.sh +0 -0
  87. {csvpath-0.0.538 → csvpath-0.0.541}/assets/integrations/sftpplus/handle_mailbox_arrival.bat +0 -0
  88. {csvpath-0.0.538 → csvpath-0.0.541}/assets/integrations/sftpplus/handle_mailbox_arrival.py +0 -0
  89. {csvpath-0.0.538 → csvpath-0.0.541}/assets/integrations/sftpplus/handle_mailbox_arrival.sh +0 -0
  90. {csvpath-0.0.538 → csvpath-0.0.541}/assets/integrations/sqlite/csvpath +0 -0
  91. {csvpath-0.0.538 → csvpath-0.0.541}/assets/integrations/sqlite/schema.sql +0 -0
  92. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/__init__.py +0 -0
  93. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/cli/__init__.py +0 -0
  94. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/cli/asker.py +0 -0
  95. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/cli/cli.py +0 -0
  96. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/cli/const.py +0 -0
  97. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/cli/debug_config.py +0 -0
  98. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/cli/drill_down.py +0 -0
  99. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/cli/function_lister.py +0 -0
  100. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/cli/selecter.py +0 -0
  101. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/csvpaths.py +0 -0
  102. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/__init__.py +0 -0
  103. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/errors/error.py +0 -0
  104. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/errors/error_collector.py +0 -0
  105. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/errors/error_manager.py +0 -0
  106. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/files/file_metadata.py +0 -0
  107. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/files/file_registrar.py +0 -0
  108. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/files/files_listener.py +0 -0
  109. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/files/lines_and_headers_cacher.py +0 -0
  110. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ckan/ckan.py +0 -0
  111. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ckan/ckan_listener.py +0 -0
  112. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ckan/datafile.py +0 -0
  113. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ckan/dataset.py +0 -0
  114. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ol/event.py +0 -0
  115. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ol/event_result.py +0 -0
  116. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ol/job.py +0 -0
  117. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ol/ol_listener.py +0 -0
  118. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ol/run.py +0 -0
  119. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ol/run_state.py +0 -0
  120. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/ol/sender.py +0 -0
  121. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/otlp/error_metrics.py +0 -0
  122. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/otlp/metrics.py +0 -0
  123. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/otlp/otlp_error_listener.py +0 -0
  124. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/otlp/otlp_listener.py +0 -0
  125. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/otlp/otlp_result_listener.py +0 -0
  126. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/otlp/otlp_results_listener.py +0 -0
  127. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/scripts/scripts_results_listener.py +0 -0
  128. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sftp/sftp_sender.py +0 -0
  129. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sftpplus/arrival_handler.py +0 -0
  130. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sftpplus/rpc.py +0 -0
  131. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sftpplus/sftpplus_listener.py +0 -0
  132. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sftpplus/transfer_creator.py +0 -0
  133. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sftpplus/transfers.py +0 -0
  134. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/slack/event.py +0 -0
  135. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/slack/sender.py +0 -0
  136. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sql/engine.py +0 -0
  137. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sql/sql_file_listener.py +0 -0
  138. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sql/sql_listener.py +0 -0
  139. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sql/sql_paths_listener.py +0 -0
  140. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sql/sql_result_listener.py +0 -0
  141. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sql/sql_results_listener.py +0 -0
  142. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sql/tables.py +0 -0
  143. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sql/updates.py +0 -0
  144. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sqlite/schema.sql +0 -0
  145. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sqlite/sqlite_result_listener.py +0 -0
  146. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/sqlite/sqlite_results_listener.py +0 -0
  147. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/webhook/webhook_listener.py +0 -0
  148. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/integrations/webhook/webhook_results_listener.py +0 -0
  149. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/listener.py +0 -0
  150. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/metadata.py +0 -0
  151. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/paths/paths_listener.py +0 -0
  152. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/paths/paths_metadata.py +0 -0
  153. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/registrar.py +0 -0
  154. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/readers/file_errors_reader.py +0 -0
  155. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/readers/file_lines_reader.py +0 -0
  156. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/readers/file_printouts_reader.py +0 -0
  157. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/readers/file_unmatched_reader.py +0 -0
  158. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/result.py +0 -0
  159. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/result_file_reader.py +0 -0
  160. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/result_metadata.py +0 -0
  161. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/result_registrar.py +0 -0
  162. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/result_serializer.py +0 -0
  163. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/results_metadata.py +0 -0
  164. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/results/results_registrar.py +0 -0
  165. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/run/run_listener_stdout.py +0 -0
  166. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/run/run_metadata.py +0 -0
  167. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/run/run_registrar.py +0 -0
  168. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/managers/test_listener.py +0 -0
  169. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/__init__.py +0 -0
  170. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/__init__.py +0 -0
  171. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/args.py +0 -0
  172. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/counting/every.py +0 -0
  173. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/function_factory.py +0 -0
  174. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/function_finder.py +0 -0
  175. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/function_focus.py +0 -0
  176. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/headers/insert.py +0 -0
  177. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/headers/mismatch.py +0 -0
  178. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/headers/replace.py +0 -0
  179. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/headers/reset_headers.py +0 -0
  180. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/lines/advance.py +0 -0
  181. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/lines/after_blank.py +0 -0
  182. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/lines/dups.py +0 -0
  183. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/lines/first.py +0 -0
  184. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/lines/first_line.py +0 -0
  185. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/lines/last.py +0 -0
  186. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/lines/stop.py +0 -0
  187. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/math/above.py +0 -0
  188. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/math/add.py +0 -0
  189. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/math/divide.py +0 -0
  190. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/math/equals.py +0 -0
  191. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/math/intf.py +0 -0
  192. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/math/mod.py +0 -0
  193. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/math/multiply.py +0 -0
  194. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/math/odd.py +0 -0
  195. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/math/round.py +0 -0
  196. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/math/subtotal.py +0 -0
  197. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/math/subtract.py +0 -0
  198. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/math/sum.py +0 -0
  199. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/misc/importf.py +0 -0
  200. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/misc/random.py +0 -0
  201. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/print/jinjaf.py +0 -0
  202. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/print/print_line.py +0 -0
  203. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/print/print_queue.py +0 -0
  204. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/print/table.py +0 -0
  205. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/stats/percent.py +0 -0
  206. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  207. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/stats/stdev.py +0 -0
  208. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/strings/alter.py +0 -0
  209. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/strings/caps.py +0 -0
  210. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/strings/contains.py +0 -0
  211. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/strings/length.py +0 -0
  212. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/strings/lower.py +0 -0
  213. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/strings/metaphone.py +0 -0
  214. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/strings/starts_with.py +0 -0
  215. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/strings/strip.py +0 -0
  216. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/strings/substring.py +0 -0
  217. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/strings/upper.py +0 -0
  218. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/testing/debug.py +0 -0
  219. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/types/__init__.py +0 -0
  220. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/types/boolean.py +0 -0
  221. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/types/datef.py +0 -0
  222. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/types/decimal.py +0 -0
  223. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/types/email.py +0 -0
  224. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/types/string.py +0 -0
  225. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/types/type.py +0 -0
  226. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/types/url.py +0 -0
  227. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/variables/get.py +0 -0
  228. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/variables/pushpop.py +0 -0
  229. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/variables/put.py +0 -0
  230. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/functions/variables/track.py +0 -0
  231. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/lark_parser.py +0 -0
  232. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/lark_transformer.py +0 -0
  233. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/productions/__init__.py +0 -0
  234. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/productions/expression.py +0 -0
  235. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/productions/header.py +0 -0
  236. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/productions/reference.py +0 -0
  237. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/productions/term.py +0 -0
  238. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/productions/variable.py +0 -0
  239. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/util/exceptions.py +0 -0
  240. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/util/expression_encoder.py +0 -0
  241. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/util/expression_utility.py +0 -0
  242. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/util/lark_print_parser.py +0 -0
  243. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/util/print_parser.py +0 -0
  244. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/matching/util/runtime_data_collector.py +0 -0
  245. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/modes/error_mode.py +0 -0
  246. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/modes/files_mode.py +0 -0
  247. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/modes/logic_mode.py +0 -0
  248. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/modes/mode_controller.py +0 -0
  249. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/modes/print_mode.py +0 -0
  250. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/modes/return_mode.py +0 -0
  251. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/modes/run_mode.py +0 -0
  252. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/modes/source_mode.py +0 -0
  253. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/modes/transfer_mode.py +0 -0
  254. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/modes/unmatched_mode.py +0 -0
  255. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/modes/validation_mode.py +0 -0
  256. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/scanning/__init__.py +0 -0
  257. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/scanning/exceptions.py +0 -0
  258. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/scanning/parser.out +0 -0
  259. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/scanning/parsetab.py +0 -0
  260. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/scanning/scanner.py +0 -0
  261. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/scanning/scanning_lexer.py +0 -0
  262. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/azure/azure_data_reader.py +0 -0
  263. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/azure/azure_data_writer.py +0 -0
  264. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/azure/azure_fingerprinter.py +0 -0
  265. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/azure/azure_nos.py +0 -0
  266. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/azure/azure_utils.py +0 -0
  267. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/azure/azure_xlsx_data_reader.py +0 -0
  268. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/box.py +0 -0
  269. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/cache.py +0 -0
  270. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/caser.py +0 -0
  271. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/class_loader.py +0 -0
  272. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/code.py +0 -0
  273. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/config_exception.py +0 -0
  274. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/exceptions.py +0 -0
  275. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/file_info.py +0 -0
  276. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/file_readers.py +0 -0
  277. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/file_writers.py +0 -0
  278. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/gcs/gcs_data_reader.py +0 -0
  279. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/gcs/gcs_data_writer.py +0 -0
  280. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/gcs/gcs_fingerprinter.py +0 -0
  281. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/gcs/gcs_nos.py +0 -0
  282. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/gcs/gcs_utils.py +0 -0
  283. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/gcs/gcs_xlsx_data_reader.py +0 -0
  284. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/hasher.py +0 -0
  285. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/http/http_data_reader.py +0 -0
  286. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/intermediary.py +0 -0
  287. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/last_line_stats.py +0 -0
  288. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/line_counter.py +0 -0
  289. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/line_monitor.py +0 -0
  290. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/line_spooler.py +0 -0
  291. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/log_utility.py +0 -0
  292. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/pandas_data_reader.py +0 -0
  293. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/path_util.py +0 -0
  294. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/printer.py +0 -0
  295. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/references/ref_utils.py +0 -0
  296. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/references/reference_parser.py +0 -0
  297. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/references/results_reference_finder.py +0 -0
  298. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/run_home_maker.py +0 -0
  299. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/s3/s3_data_reader.py +0 -0
  300. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/s3/s3_data_writer.py +0 -0
  301. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/s3/s3_fingerprinter.py +0 -0
  302. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/s3/s3_nos.py +0 -0
  303. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/s3/s3_utils.py +0 -0
  304. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/s3/s3_xlsx_data_reader.py +0 -0
  305. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/sftp/sftp_config.py +0 -0
  306. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/sftp/sftp_data_reader.py +0 -0
  307. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/sftp/sftp_data_writer.py +0 -0
  308. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/sftp/sftp_fingerprinter.py +0 -0
  309. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/sftp/sftp_nos.py +0 -0
  310. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/sftp/sftp_walk.py +0 -0
  311. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/sftp/sftp_xlsx_data_reader.py +0 -0
  312. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/sqliter.py +0 -0
  313. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/template_util.py +0 -0
  314. {csvpath-0.0.538 → csvpath-0.0.541}/csvpath/util/var_utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: csvpath
3
- Version: 0.0.538
3
+ Version: 0.0.541
4
4
  Summary: A data preboarding framework for managing and validating CSV, Excel, and other tabular data files using a Collect, Store, Validate, Publish pattern to create a trusted publisher for downstream data consumers.
5
5
  Author: David Kershaw
6
6
  Author-email: dk107dk@hotmail.com
@@ -57,7 +57,7 @@ groups =
57
57
  #slack, marquez, ckan, sftp, sftpplus, otlp, default, sqlite
58
58
 
59
59
  # general purpose webhook caller
60
- webhook.results = from csvpath.managers.integrations.webhook.webhook_results_listener import WebhookResultListener
60
+ webhook.results = from csvpath.managers.integrations.webhook.webhook_results_listener import WebhookResultsListener
61
61
 
62
62
  # add a listener to exec scripts at the end of named-paths group runs
63
63
  scripts.results = from csvpath.managers.integrations.scripts.scripts_results_listener import ScriptsResultsListener
@@ -91,7 +91,7 @@ otlp.errors = from csvpath.managers.integrations.otlp.otlp_error_listener import
91
91
  sftpplus.paths = from csvpath.managers.integrations.sftpplus.sftpplus_listener import SftpPlusListener
92
92
 
93
93
  # add sftp to the list of groups above to push results to an sftp account
94
- sftp.results = from csvpath.managers.integrations.sftp.sftp_listener import SftpListener
94
+ sftp.results = from csvpath.managers.integrations.sftp.sftp_sender import SftpSender
95
95
 
96
96
  # add ckan to the list of groups above for alerts to slack webhooks
97
97
  ckan.results = from csvpath.managers.integrations.ckan.ckan_listener import CkanListener
@@ -57,7 +57,7 @@ groups =
57
57
  #slack, marquez, ckan, sftp, sftpplus, otlp, default, sqlite
58
58
 
59
59
  # general purpose webhook caller
60
- webhook.results = from csvpath.managers.integrations.webhook.webhook_results_listener import WebhookResultListener
60
+ webhook.results = from csvpath.managers.integrations.webhook.webhook_results_listener import WebhookResultsListener
61
61
 
62
62
  # add a listener to exec scripts at the end of named-paths group runs
63
63
  scripts.results = from csvpath.managers.integrations.scripts.scripts_results_listener import ScriptsResultsListener
@@ -91,7 +91,7 @@ otlp.errors = from csvpath.managers.integrations.otlp.otlp_error_listener import
91
91
  sftpplus.paths = from csvpath.managers.integrations.sftpplus.sftpplus_listener import SftpPlusListener
92
92
 
93
93
  # add sftp to the list of groups above to push results to an sftp account
94
- sftp.results = from csvpath.managers.integrations.sftp.sftp_listener import SftpListener
94
+ sftp.results = from csvpath.managers.integrations.sftp.sftp_sender import SftpSender
95
95
 
96
96
  # add ckan to the list of groups above for alerts to slack webhooks
97
97
  ckan.results = from csvpath.managers.integrations.ckan.ckan_listener import CkanListener
@@ -31,6 +31,11 @@ class FunctionDescriber:
31
31
  def sigs(cls, function):
32
32
  sigs = []
33
33
  args = function.args
34
+ if not args:
35
+ #
36
+ # this is possibly due to the very small number of unrefactored functions. (3?)
37
+ #
38
+ return sigs
34
39
  argsets = args.argsets
35
40
  for ai, a in enumerate(argsets):
36
41
  pa = ""
@@ -19,7 +19,6 @@ from .matching.matcher import Matcher
19
19
  from .scanning.scanner import Scanner
20
20
  from .util.metadata_parser import MetadataParser
21
21
  from .managers.errors.error import Error
22
- from .managers.errors.error_collector import ErrorCollector
23
22
  from .managers.errors.error_comms import ErrorCommunications
24
23
  from .managers.errors.error_manager import ErrorManager
25
24
  from .managers.metadata import Metadata
@@ -33,6 +32,7 @@ from .util.exceptions import (
33
32
  CsvPathsException,
34
33
  )
35
34
  from .matching.util.exceptions import MatchException
35
+ from .managers.errors.error_collector import ErrorCollector
36
36
 
37
37
 
38
38
  class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
@@ -584,7 +584,7 @@ class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
584
584
  @property
585
585
  def explain(self) -> bool:
586
586
  """@private
587
- when this property is True CsvPath dumps a match explaination
587
+ when this property is True CsvPath dumps a match explanation
588
588
  to INFO. this can be expensive. a 25% performance hit wouldn't
589
589
  be unexpected.
590
590
  """
@@ -672,7 +672,7 @@ class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
672
672
  # - logic-mode: AND | OR
673
673
  # - return-mode: matches | no-matches
674
674
  # - print-mode: default | no-default
675
- # - validation-mode: (no-)print | log | (no-)raise | quiet | (no-)match
675
+ # - validation-mode: (no-)print | log | (no-)raise | quiet | (no-)match | (no-)stop
676
676
  # - run-mode: no-run | run
677
677
  # - unmatched-mode: no-keep | keep
678
678
  # - source-mode: preceding | origin
@@ -975,7 +975,8 @@ class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
975
975
  def limit_collection_to(self, indexes: List[int]) -> None:
976
976
  """@private"""
977
977
  self._limit_collection_to = indexes
978
- self.logger.warning("Setting a limit on headers collected: %s", indexes)
978
+ if self._limit_collection_to and self._limit_collection_to != indexes:
979
+ self.logger.info("Limiting headers collected: %s", indexes)
979
980
 
980
981
  def stop(self) -> None:
981
982
  """@private"""
@@ -1137,7 +1138,7 @@ class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
1137
1138
  #
1138
1139
  # DataFileReader is abstract. instantiating it results in a concrete subclass.
1139
1140
  # pylint doesn't like that just because it doesn't see what we're doing.
1140
- # otoh, is this a bad way to do it? not sure but it works fine.
1141
+ # otoh, is this a bad way to do it? it works fine.
1141
1142
  #
1142
1143
  reader = DataFileReader( # pylint: disable=E0110
1143
1144
  self.scanner.filename, delimiter=self.delimiter, quotechar=self.quotechar
@@ -1264,9 +1265,13 @@ class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
1264
1265
  ls = []
1265
1266
  for k in self.limit_collection_to:
1266
1267
  if k is None or k >= len(line):
1267
- raise InputException(
1268
- f"[{self.identity}] Line {self.line_monitor.physical_line_number}: unknown header name: {k} of {self.limit_collection_to} in headers {self.headers}"
1269
- )
1268
+ #
1269
+ # FP change. didn't do do_i_raise and didn't handle w/error mgr
1270
+ #
1271
+ msg = f"[{self.identity}] Line {self.line_monitor.physical_line_number}: unknown header name: {k} of {self.limit_collection_to} in headers {self.headers}"
1272
+ self.error_manager.handle_error(source=self, msg=msg)
1273
+ if self.ecoms.do_i_raise():
1274
+ raise InputException(msg)
1270
1275
  ls.append(line[k])
1271
1276
  return ls
1272
1277
 
@@ -1321,6 +1326,12 @@ class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
1321
1326
  if use_cache:
1322
1327
  uc = self.csvpaths.config.get(section="cache", name="use_cache")
1323
1328
  use_cache = uc is None or uc.strip().lower() != "no"
1329
+ #
1330
+ # do we really want to only use cache if we're running a named-paths group?
1331
+ # users may want to run one-offs repeatedly, particularly in FP. otoh, we
1332
+ # don't have a file_manager and its a big change for probably a small number of
1333
+ # bad cases and it can be worked around by simply using a CsvPaths.
1334
+ #
1324
1335
  if self.csvpaths and use_cache is True:
1325
1336
  self.line_monitor = self.csvpaths.file_manager.lines_and_headers_cacher.get_new_line_monitor(
1326
1337
  self.scanner.filename
@@ -17,7 +17,7 @@ class ErrorCommunications:
17
17
  the error policy in config/config.ini (or whereever your config is)
18
18
  is the baseline. however, every csvpath can override the config
19
19
  for some of the error handling using a comment with the metadata
20
- field args-validation-mode. (soon to be validation-mode). config
20
+ field validation-mode. config
21
21
  has two setting values not tracked in metadata: quiet and log.
22
22
  """
23
23
 
@@ -62,7 +62,15 @@ class ErrorCommunications:
62
62
  def do_i_stop(self) -> bool:
63
63
  mode = None
64
64
  if self._csvpath and self._csvpath.stop_on_validation_errors is not None:
65
+ #
66
+ # looks wrong. function in FlightPath is not correct. doesn't match other do_i_...
67
+ #
65
68
  mode = self._csvpath.stop_on_validation_errors
69
+ #
70
+ # this was a change made for flightpath. not sure it works. it may well work.
71
+ # however atm visibility isn't great. come back later.
72
+ #
73
+ # return self._csvpath.stop_on_validation_errors
66
74
  policy = self.in_policy(OnError.STOP.value)
67
75
  return mode is True or policy is True
68
76
 
@@ -299,7 +299,10 @@ class FileManager:
299
299
  # cannot be a reference or part of a reference. has to just
300
300
  # be the simple name of the named file.
301
301
  #
302
- self.legal_name(name)
302
+ try:
303
+ self.legal_name(name)
304
+ except Exception:
305
+ return False
303
306
  #
304
307
  # the home should exist if the named file exists.
305
308
  #
@@ -367,13 +370,15 @@ class FileManager:
367
370
  if self.csvpaths.ecoms.do_i_raise():
368
371
  raise
369
372
 
370
- def legal_name(self, name:str) -> None:
373
+ def legal_name(self, name: str) -> None:
371
374
  if name is None:
372
375
  raise ValueError("Name cannot be None")
373
376
  if name.strip() == "":
374
377
  raise ValueError("Name cannot be empty")
375
378
  if name.find("/") > -1 or name.find("\\") > -1:
376
- raise ValueError(f"Not a legal name: {name}. Path seperators are not allowed.")
379
+ raise ValueError(
380
+ f"Not a legal name: {name}. Path seperators are not allowed."
381
+ )
377
382
  if name.find(".") > -1:
378
383
  raise ValueError(f"Not a legal name: {name}. Periods are not allowed.")
379
384
  if name.find("$") > -1:
@@ -397,8 +402,8 @@ class FileManager:
397
402
  #
398
403
  # legal_name handled at add_named_file
399
404
  #
400
- #self.legal_name(name)
401
- #if dirname is None or dirname.strip() == "":
405
+ # self.legal_name(name)
406
+ # if dirname is None or dirname.strip() == "":
402
407
  # raise ValueError("Dirname cannot be None or empty")
403
408
  #
404
409
  # need to support adding all files from directory under the same name. preferably
@@ -440,7 +445,7 @@ class FileManager:
440
445
  self, *, name: NamedFileName, path: str, template: str = None
441
446
  ) -> None:
442
447
  self.legal_name(name)
443
- #if name is None or name.strip() == "":
448
+ # if name is None or name.strip() == "":
444
449
  # raise ValueError("Name cannot be None or empty")
445
450
  if path is None or path.strip() == "":
446
451
  raise ValueError("Path cannot be None or empty")
@@ -1,4 +1,4 @@
1
- from .ol_listener import OpenLineageListener
1
+ from csvpath.managers.integrations.ol.ol_listener import OpenLineageListener
2
2
 
3
3
 
4
4
  class OpenLineageFileListener(OpenLineageListener):
@@ -1,7 +1,7 @@
1
1
  from openlineage.client import OpenLineageClient
2
2
 
3
- from ..metadata import Metadata
4
- from .ol_listener import OpenLineageListener
3
+ from csvpath.managers.metadata import Metadata
4
+ from csvpath.managers.integrations.ol.ol_listener import OpenLineageListener
5
5
 
6
6
 
7
7
  class OpenLineagePathsListener(OpenLineageListener):
@@ -1,4 +1,4 @@
1
- from ..ol_listener import OpenLineageListener
1
+ from csvpath.managers.integrations.ol.ol_listener import OpenLineageListener
2
2
 
3
3
 
4
4
  class OpenLineageResultListener(OpenLineageListener):
@@ -1,4 +1,4 @@
1
- from .ol_listener import OpenLineageListener
1
+ from csvpath.managers.integrations.ol.ol_listener import OpenLineageListener
2
2
 
3
3
 
4
4
  class OpenLineageResultsListener(OpenLineageListener):
@@ -1,4 +1,4 @@
1
- from .ol_listener import OpenLineageListener
1
+ from csvpath.managers.integrations.ol.ol_listener import OpenLineageListener
2
2
 
3
3
 
4
4
  class OpenLineageResultsListener(OpenLineageListener):
@@ -197,12 +197,20 @@ class PathsManager:
197
197
  raise InputException(msg)
198
198
 
199
199
  def add_named_paths_from_file(
200
- self, *, name: NamedPathsName, file_path: str, template=None
200
+ self,
201
+ *,
202
+ name: NamedPathsName,
203
+ file_path: str,
204
+ template=None,
205
+ append: bool = False,
201
206
  ) -> None:
207
+ #
208
+ # change for FP: added append as a pass-through
209
+ #
202
210
  self.csvpaths.logger.debug("Reading csvpaths file at %s", file_path)
203
211
  _ = self._get_csvpaths_from_file(file_path)
204
212
  self.add_named_paths(
205
- name=name, paths=_, source_path=file_path, template=template
213
+ name=name, paths=_, source_path=file_path, template=template, append=append
206
214
  )
207
215
 
208
216
  def add_named_paths_from_json(self, file_path: str) -> None:
@@ -248,12 +256,16 @@ class PathsManager:
248
256
  from_json: str = None,
249
257
  source_path: str = None,
250
258
  template: str = None,
259
+ append: bool = False,
251
260
  ) -> None:
252
261
  if template is not None:
253
262
  temu.valid(template)
254
263
  if from_file is not None:
264
+ #
265
+ # change for FP. added append as a pass-through
266
+ #
255
267
  return self.add_named_paths_from_file(
256
- name=name, file_path=from_file, template=template
268
+ name=name, file_path=from_file, template=template, append=append
257
269
  )
258
270
  elif from_dir is not None:
259
271
  return self.add_named_paths_from_dir(
@@ -273,7 +285,7 @@ class PathsManager:
273
285
  for _ in paths:
274
286
  self.csvpaths.logger.debug("Adding %s to %s", _, name)
275
287
  s = self._str_from_list(paths)
276
- t = self._copy_in(name, s)
288
+ t = self._copy_in(name, s, append=append)
277
289
  grp_paths = self.get_identified_paths_in(name, paths=paths)
278
290
  ids = [t[0] for t in grp_paths]
279
291
  for i, t in enumerate(ids):
@@ -630,9 +642,15 @@ class PathsManager:
630
642
  cs = s.split("---- CSVPATH ----")
631
643
  cs = [s for s in cs if s.strip() != ""]
632
644
  #
633
- # this update may not happen. it depends on if the group.csvpaths file has changed.
634
- # if someone put a new group.csvpaths file by hand we want to capture its fingerprint
635
- # for future reference. this shouldn't happen, but it probably will happen.
645
+ # this update may not result in broadcasting an update event to listeners.
646
+ # that all depends on if group.csvpaths was changed outside the manager.
647
+ # if someone put a new group.csvpaths file by hand we want to capture its
648
+ # fingerprint for future reference. this shouldn't happen, but it probably
649
+ # will happen.
650
+ #
651
+ # seen 1x with FlightPath. not yet clear if FP is doing something new and
652
+ # desireable or if it has a bug. in principle, still don't see a reason this
653
+ # update should obtain, unless a user edits a file they shouldn't.
636
654
  #
637
655
  self.registrar.update_manifest_if(name=name, group_file_path=grp, paths=cs)
638
656
  return cs
@@ -644,7 +662,21 @@ class PathsManager:
644
662
  f = f"{f}\n\n---- CSVPATH ----\n\n{_}"
645
663
  return f
646
664
 
647
- def _copy_in(self, name: NamedPathsName, csvpathstr: Csvpath) -> None:
665
+ def _copy_in(self, name: NamedPathsName, csvpathstr: Csvpath, append=False) -> None:
666
+ #
667
+ # if we have a set of paths we append these new paths
668
+ #
669
+ if self.has_named_paths(name) and append is True:
670
+ existing = self.get_named_paths(name)
671
+ estr = self._str_from_list(existing)
672
+ if not estr.strip().endswith(
673
+ "---- CSVPATH ----"
674
+ ) and not csvpathstr.strip().startswith("---- CSVPATH ----"):
675
+ csvpathstr = f"{estr}\n\n---- CSVPATH ----\n\n"
676
+ csvpathstr = f"{estr}{csvpathstr}"
677
+ #
678
+ # continue with the write
679
+ #
648
680
  temp = self._group_file_path(name)
649
681
  with DataFileWriter(path=temp, mode="w") as writer:
650
682
  writer.append(csvpathstr)
@@ -691,6 +723,32 @@ class PathsManager:
691
723
  ps.append(path[0])
692
724
  return ps
693
725
 
726
+ #
727
+ # this version correctly picks up csvpaths that the Framework identifies by index
728
+ # because they don't have user assigned identities. this was seen in FlightPath
729
+ # but applies in general.
730
+ #
731
+ def _get_from(self, npn: NamedPathsName, identity: Identity) -> list[Csvpath]:
732
+ index = expu.to_int(identity)
733
+ ps = []
734
+ paths = self.get_identified_paths_in(npn)
735
+ for i, path in enumerate(paths):
736
+ #
737
+ # if we have the identity or the identity is the index or we are collecting
738
+ # after our first collection because :from collects all csvpaths coming after
739
+ # a starting csvpath
740
+ #
741
+ if (path[0] == identity or (path[0] is None and index == i)) or len(ps) > 0:
742
+ ps.append(path[1])
743
+ """
744
+ if path[0] != identity and len(ps) == 0:
745
+ continue
746
+ ps.append(path[1])
747
+ """
748
+ return ps
749
+
750
+ """
751
+ original version
694
752
  def _get_from(self, npn: NamedPathsName, identity: Identity) -> list[Csvpath]:
695
753
  ps = []
696
754
  paths = self.get_identified_paths_in(npn)
@@ -699,6 +757,7 @@ class PathsManager:
699
757
  continue
700
758
  ps.append(path[1])
701
759
  return ps
760
+ """
702
761
 
703
762
  def get_preceeding_instance_identity(self, name, index: int) -> str:
704
763
  if index <= 0:
@@ -735,6 +794,7 @@ class PathsManager:
735
794
  idps.append((c.identity, path))
736
795
  return idps
737
796
 
797
+ """
738
798
  def _find_one(self, npn: NamedPathsName, identity: Identity) -> Csvpath:
739
799
  if npn is not None:
740
800
  paths = self.get_identified_paths_in(npn)
@@ -744,6 +804,29 @@ class PathsManager:
744
804
  raise InputException(
745
805
  f"Path identified as '{identity}' must be in the group identitied as '{npn}'"
746
806
  )
807
+ """
808
+
809
+ def _find_one(self, npn: NamedPathsName, identity: Identity) -> Csvpath:
810
+ #
811
+ # this version of the method is a change for FlightPath. the change is correct for
812
+ # all purposes, but showed up clearly in FP. the problem is that we don't test index
813
+ # for unidentitied paths. luckily we do return all paths with None as the identity
814
+ # for those w/o user specified id. for those we just need to test the index.
815
+ #
816
+ # this version assumes that if a csvpath is identitied we do not allow using the
817
+ # index to point to it. this may not be the right assumption, but it is arguably a
818
+ # good way to go. if the writer bothered to identify, the id is more specific than
819
+ # the index and so less error-prone.
820
+ #
821
+ index = expu.to_int(identity)
822
+ if npn is not None:
823
+ paths = self.get_identified_paths_in(npn)
824
+ for i, path in enumerate(paths):
825
+ if path[0] == identity or (path[0] is None and index == i):
826
+ return path[1]
827
+ raise InputException(
828
+ f"Path identified as '{identity}' must be in the group identitied as '{npn}'"
829
+ )
747
830
 
748
831
  def _name_from_name_part(self, name):
749
832
  i = name.rfind(".")
@@ -35,7 +35,7 @@ class PathsRegistrar(Registrar, Listener):
35
35
  mdata.fingerprint = self._fingerprint(name=mdata.named_paths_name)
36
36
  self.distribute_update(mdata)
37
37
 
38
- def update_manifest_if(self, *, group_file_path, name, paths=None):
38
+ def update_manifest_if(self, *, group_file_path, name, paths):
39
39
  #
40
40
  # if we find that the current group file does not have the same
41
41
  # fingerprint as the most recent on file, we register a new version.
@@ -47,20 +47,19 @@ class PathsRegistrar(Registrar, Listener):
47
47
  mpath = self.manifest_path(name)
48
48
  cf = self._most_recent_fingerprint(mpath)
49
49
  if f != cf:
50
- mdata = PathsMetadata()
50
+ mdata = PathsMetadata(self.csvpaths.config)
51
51
  mdata.archive_name = self.csvpaths.config.archive_name
52
52
  mdata.named_paths_name = name
53
- #
54
- # why two of these? :/
55
- #
56
- # mdata.named_paths_file = group_file_path
57
53
  mdata.group_file_path = group_file_path
58
54
  mdata.named_paths = paths
59
55
  mdata.named_paths_identities = [
60
- t[0] for t in self.manager.get_identified_paths_in(name)
56
+ #
57
+ # if we don't pass paths to get_identified_paths_in we will infinite loop
58
+ #
59
+ t[0]
60
+ for t in self.manager.get_identified_paths_in(name, paths)
61
61
  ]
62
- if paths:
63
- mdata.named_paths_count = len(paths)
62
+ mdata.named_paths_count = len(paths)
64
63
  mdata.manifest_path = mpath
65
64
  mdata.fingerprint = f
66
65
  self.distribute_update(mdata)
@@ -63,7 +63,7 @@ class PrintoutsReader(ResultReader):
63
63
 
64
64
  class ResultReadersFacade(ErrorsReader, UnmatchedReader, LinesReader, PrintoutsReader):
65
65
  #
66
- # as soonn as we get a run_dir and an instance we'll create the
66
+ # as soon as we get a run_dir and an instance we'll create the
67
67
  # instance_dir and load the readers
68
68
  #
69
69
  def __init__(self, result):
@@ -309,7 +309,12 @@ class ResultsManager: # pylint: disable=C0115
309
309
  path = self._csvpaths.config.archive_path
310
310
  if Nos(path).dir_exists():
311
311
  names = Nos(path).listdir()
312
- names = [n for n in names if not n.startswith(".")]
312
+ #
313
+ # listing dir shouldn't return manifest.json or any file. can do better here.
314
+ #
315
+ names = [
316
+ n for n in names if not n.startswith(".") and not n.endswith(".json")
317
+ ]
313
318
  names.sort()
314
319
  else:
315
320
  self._csvpaths.logger.warning(
@@ -513,7 +518,14 @@ class ResultsManager: # pylint: disable=C0115
513
518
  # CsvPaths instance, we would create a new one.
514
519
  #
515
520
  if name in self.named_results:
516
- return self.named_results[name]
521
+ #
522
+ # exp. removed 4 May.
523
+ # was/is this ever a good idea?
524
+ #
525
+ # seems to be important for a handful of unit tests.
526
+ #
527
+ rs = self.named_results[name]
528
+ return rs
517
529
  #
518
530
  # find and load the result, if exists. we find results home with the name. run_home is the
519
531
  # last run dir. the results we're looking for are the instance dirs in the run dir.
@@ -573,7 +585,9 @@ class ResultsManager: # pylint: disable=C0115
573
585
  nos = Nos(path)
574
586
  exists = nos.dir_exists()
575
587
  nonphy = nos.physical_dirs()
588
+ #
576
589
  # is not nonphy needed?
590
+ #
577
591
  if exists or not nonphy:
578
592
  runs = nos.listdir()
579
593
  if len(runs) > 0:
@@ -26,7 +26,7 @@ class ArgumentValidationHelper:
26
26
  # Validate each argument against the argset.
27
27
  # this part gets ugly. we should instead just say:
28
28
  # f"invalid {argset.matchable.name}. {argset.explain}"
29
- # and then write the explaination into the classes. (OMG! but it would be best, imho).
29
+ # and then write the explanation into the classes. (OMG! but it would be best, imho).
30
30
  #
31
31
  results = []
32
32
  for va in valid_argsets:
@@ -16,11 +16,26 @@ class All(MatchDecider):
16
16
  """checks that a number of match components return True"""
17
17
 
18
18
  def check_valid(self) -> None: # pragma: no cover
19
+ self.description = [
20
+ self._cap_name(),
21
+ self.wrap(
22
+ """\
23
+ Tests if all contained or referenced match components evaluate to True.
24
+ If all() has no arguments the check is if all headers have values.
25
+ """
26
+ ),
27
+ ]
19
28
  self.args = Args(matchable=self)
20
- self.args.argset(0)
21
- self.args.argset(1).arg(types=[None, Variables, Headers], actuals=[])
29
+ self.args.argset(0) # what would the function of all() w/o args be?
30
+ self.args.argset(1).arg(
31
+ name="a function indicating all headers or all variables",
32
+ types=[None, Variables, Headers],
33
+ actuals=[],
34
+ )
22
35
  self.args.argset().arg(
23
- types=[None, Function, Variable, Header], actuals=[None, Any]
36
+ name="one of a set of match components",
37
+ types=[None, Function, Variable, Header],
38
+ actuals=[None, Any],
24
39
  )
25
40
  self.args.validate(self.siblings())
26
41
  super().check_valid()
@@ -13,6 +13,21 @@ class And(MatchDecider):
13
13
  need more control."""
14
14
 
15
15
  def check_valid(self) -> None: # pragma: no cover
16
+ self.description = [
17
+ self._cap_name(),
18
+ self.wrap(
19
+ """
20
+ and() tests if its contained match components evaluate to True.
21
+
22
+ Matching is ANDed by default, but it can be set to OR. And and()
23
+ gives you a bit more control in certain situations, such as making.
24
+ a when/do expression that is based on multiple match components.
25
+
26
+ The functionality of and() overlaps with all(), but all() has
27
+ powers that are more specific than and().
28
+ """
29
+ ),
30
+ ]
16
31
  self.args = Args(matchable=self)
17
32
  a = self.args.argset()
18
33
  a.arg(types=[Matchable], actuals=[None, Any])
@@ -20,12 +20,38 @@ class Any(MatchDecider):
20
20
  """
21
21
 
22
22
  def check_valid(self) -> None:
23
+ self.description = [
24
+ self._cap_name(),
25
+ self.wrap(
26
+ """\
27
+ any() returns True if at least one contained match component
28
+ matches a given value.
29
+
30
+ With no arguments any() matches if there are values in any variable or header.
31
+
32
+ With a single headers() or variables() function any() returns True if there is
33
+ a match component of the the type indicated with a value.
34
+
35
+ With a second argument the test is for the specific value in any match component
36
+ of the indicated type.
37
+
38
+ any() is similar to or() or OR logic. While any() gives
39
+ you more fine-grained control, remember that you can
40
+ also use logic-mode to configure a csvpath to use OR as
41
+ the basis for matching.
42
+ """
43
+ ),
44
+ ]
23
45
  self.args = Args(matchable=self)
24
46
  a = self.args.argset(0)
25
47
 
26
48
  a = self.args.argset(2)
27
- a.arg(types=[Variables, Headers], actuals=[None, typing.Any])
28
- a.arg(types=[typing.Any], actuals=[None, typing.Any])
49
+ a.arg(
50
+ name="Indicates where to look",
51
+ types=[Variables, Headers],
52
+ actuals=[None, typing.Any],
53
+ )
54
+ a.arg(name="The value to find", types=[typing.Any], actuals=[None, typing.Any])
29
55
 
30
56
  a = self.args.argset(1)
31
57
  a.arg(types=[typing.Any, Variables, Headers], actuals=[None, typing.Any])