csvpath 0.0.537__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.537 → csvpath-0.0.541}/PKG-INFO +1 -1
  2. {csvpath-0.0.537 → csvpath-0.0.541/assets}/config/config.ini +2 -2
  3. {csvpath-0.0.537 → csvpath-0.0.541}/assets/config/jenkins-local-filesystem-mysql.ini +9 -8
  4. {csvpath-0.0.537/assets → csvpath-0.0.541}/config/config.ini +2 -2
  5. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/cli/function_describer.py +5 -0
  6. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/csvpath.py +28 -9
  7. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/errors/error_comms.py +9 -1
  8. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/files/file_manager.py +44 -4
  9. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ol/file_listener_ol.py +1 -1
  10. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ol/paths_listener_ol.py +2 -2
  11. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ol/result_listener_ol.py +1 -1
  12. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ol/results_listener_ol.py +1 -1
  13. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ol/run_listener_ol.py +1 -1
  14. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/paths/paths_manager.py +91 -8
  15. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/paths/paths_registrar.py +8 -9
  16. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/readers/readers.py +1 -1
  17. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/results_manager.py +16 -2
  18. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/args_helper.py +1 -1
  19. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/boolean/all.py +18 -3
  20. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/boolean/andf.py +15 -0
  21. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/boolean/any.py +28 -2
  22. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/boolean/between.py +35 -3
  23. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/boolean/empty.py +17 -2
  24. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/boolean/exists.py +18 -1
  25. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/boolean/inf.py +23 -2
  26. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/boolean/no.py +9 -0
  27. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/boolean/notf.py +12 -0
  28. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/boolean/orf.py +17 -2
  29. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/boolean/yes.py +9 -0
  30. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/counting/count.py +41 -0
  31. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/counting/count_bytes.py +12 -0
  32. csvpath-0.0.541/csvpath/matching/functions/counting/count_headers.py +44 -0
  33. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/counting/count_lines.py +22 -0
  34. csvpath-0.0.541/csvpath/matching/functions/counting/count_scans.py +32 -0
  35. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/counting/counter.py +7 -1
  36. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/counting/has_matches.py +9 -0
  37. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/counting/increment.py +17 -2
  38. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/counting/tally.py +24 -1
  39. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/counting/total_lines.py +8 -0
  40. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/dates/now.py +23 -1
  41. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/function.py +16 -2
  42. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/headers/append.py +19 -2
  43. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/headers/collect.py +26 -5
  44. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/headers/empty_stack.py +17 -1
  45. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/headers/end.py +15 -1
  46. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/headers/header_name.py +37 -3
  47. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/headers/header_names_mismatch.py +25 -9
  48. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/headers/headers.py +17 -3
  49. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/misc/fingerprint.py +48 -0
  50. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/print/printf.py +46 -8
  51. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/stats/minf.py +33 -4
  52. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/strings/concat.py +10 -0
  53. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/strings/regex.py +30 -1
  54. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/types/nonef.py +4 -3
  55. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/validity/fail.py +8 -0
  56. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/validity/failed.py +3 -0
  57. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/validity/line.py +14 -2
  58. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/variables/variables.py +9 -10
  59. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/matcher.py +6 -6
  60. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/productions/equality.py +10 -2
  61. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/productions/matchable.py +1 -1
  62. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/productions/qualified.py +13 -4
  63. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/modes/explain_mode.py +2 -2
  64. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/config.py +201 -137
  65. csvpath-0.0.541/csvpath/util/date_util.py +35 -0
  66. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/metadata_parser.py +19 -1
  67. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/nos.py +4 -9
  68. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/references/files_reference_finder.py +148 -46
  69. {csvpath-0.0.537 → csvpath-0.0.541}/pyproject.toml +1 -1
  70. csvpath-0.0.537/csvpath/matching/functions/counting/count_headers.py +0 -20
  71. csvpath-0.0.537/csvpath/matching/functions/counting/count_scans.py +0 -15
  72. {csvpath-0.0.537 → csvpath-0.0.541}/LICENSE +0 -0
  73. {csvpath-0.0.537 → csvpath-0.0.541}/README.md +0 -0
  74. {csvpath-0.0.537 → csvpath-0.0.541}/assets/config/function.imports +0 -0
  75. {csvpath-0.0.537 → csvpath-0.0.541}/assets/config/jenkins-local-azure.ini +0 -0
  76. {csvpath-0.0.537 → csvpath-0.0.541}/assets/config/jenkins-local-filesystem.ini +0 -0
  77. {csvpath-0.0.537 → csvpath-0.0.541}/assets/config/jenkins-local-gcs.ini +0 -0
  78. {csvpath-0.0.537 → csvpath-0.0.541}/assets/config/jenkins-local-sftp.ini +0 -0
  79. {csvpath-0.0.537 → csvpath-0.0.541}/assets/config/jenkins-s3.ini +0 -0
  80. {csvpath-0.0.537 → csvpath-0.0.541}/assets/config/jenkins-windows-azure.ini +0 -0
  81. {csvpath-0.0.537 → csvpath-0.0.541}/assets/config/jenkins-windows-local.ini +0 -0
  82. {csvpath-0.0.537 → csvpath-0.0.541}/assets/config/jenkins-windows-sftp.ini +0 -0
  83. {csvpath-0.0.537 → csvpath-0.0.541}/assets/config/local-localhost-sftp.ini +0 -0
  84. {csvpath-0.0.537 → csvpath-0.0.541}/assets/integrations/sftpplus/handle_auto_arrival.bat +0 -0
  85. {csvpath-0.0.537 → csvpath-0.0.541}/assets/integrations/sftpplus/handle_auto_arrival.py +0 -0
  86. {csvpath-0.0.537 → csvpath-0.0.541}/assets/integrations/sftpplus/handle_auto_arrival.sh +0 -0
  87. {csvpath-0.0.537 → csvpath-0.0.541}/assets/integrations/sftpplus/handle_mailbox_arrival.bat +0 -0
  88. {csvpath-0.0.537 → csvpath-0.0.541}/assets/integrations/sftpplus/handle_mailbox_arrival.py +0 -0
  89. {csvpath-0.0.537 → csvpath-0.0.541}/assets/integrations/sftpplus/handle_mailbox_arrival.sh +0 -0
  90. {csvpath-0.0.537 → csvpath-0.0.541}/assets/integrations/sqlite/csvpath +0 -0
  91. {csvpath-0.0.537 → csvpath-0.0.541}/assets/integrations/sqlite/schema.sql +0 -0
  92. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/__init__.py +0 -0
  93. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/cli/__init__.py +0 -0
  94. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/cli/asker.py +0 -0
  95. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/cli/cli.py +0 -0
  96. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/cli/const.py +0 -0
  97. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/cli/debug_config.py +0 -0
  98. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/cli/drill_down.py +0 -0
  99. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/cli/function_lister.py +0 -0
  100. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/cli/selecter.py +0 -0
  101. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/csvpaths.py +0 -0
  102. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/__init__.py +0 -0
  103. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/errors/error.py +0 -0
  104. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/errors/error_collector.py +0 -0
  105. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/errors/error_manager.py +0 -0
  106. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/files/file_metadata.py +0 -0
  107. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/files/file_registrar.py +0 -0
  108. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/files/files_listener.py +0 -0
  109. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/files/lines_and_headers_cacher.py +0 -0
  110. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ckan/ckan.py +0 -0
  111. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ckan/ckan_listener.py +0 -0
  112. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ckan/datafile.py +0 -0
  113. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ckan/dataset.py +0 -0
  114. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ol/event.py +0 -0
  115. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ol/event_result.py +0 -0
  116. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ol/job.py +0 -0
  117. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ol/ol_listener.py +0 -0
  118. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ol/run.py +0 -0
  119. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ol/run_state.py +0 -0
  120. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/ol/sender.py +0 -0
  121. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/otlp/error_metrics.py +0 -0
  122. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/otlp/metrics.py +0 -0
  123. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/otlp/otlp_error_listener.py +0 -0
  124. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/otlp/otlp_listener.py +0 -0
  125. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/otlp/otlp_result_listener.py +0 -0
  126. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/otlp/otlp_results_listener.py +0 -0
  127. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/scripts/scripts_results_listener.py +0 -0
  128. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sftp/sftp_sender.py +0 -0
  129. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sftpplus/arrival_handler.py +0 -0
  130. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sftpplus/rpc.py +0 -0
  131. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sftpplus/sftpplus_listener.py +0 -0
  132. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sftpplus/transfer_creator.py +0 -0
  133. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sftpplus/transfers.py +0 -0
  134. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/slack/event.py +0 -0
  135. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/slack/sender.py +0 -0
  136. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sql/engine.py +0 -0
  137. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sql/sql_file_listener.py +0 -0
  138. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sql/sql_listener.py +0 -0
  139. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sql/sql_paths_listener.py +0 -0
  140. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sql/sql_result_listener.py +0 -0
  141. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sql/sql_results_listener.py +0 -0
  142. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sql/tables.py +0 -0
  143. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sql/updates.py +0 -0
  144. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sqlite/schema.sql +0 -0
  145. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sqlite/sqlite_result_listener.py +0 -0
  146. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/sqlite/sqlite_results_listener.py +0 -0
  147. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/webhook/webhook_listener.py +0 -0
  148. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/integrations/webhook/webhook_results_listener.py +0 -0
  149. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/listener.py +0 -0
  150. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/metadata.py +0 -0
  151. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/paths/paths_listener.py +0 -0
  152. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/paths/paths_metadata.py +0 -0
  153. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/registrar.py +0 -0
  154. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/readers/file_errors_reader.py +0 -0
  155. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/readers/file_lines_reader.py +0 -0
  156. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/readers/file_printouts_reader.py +0 -0
  157. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/readers/file_unmatched_reader.py +0 -0
  158. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/result.py +0 -0
  159. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/result_file_reader.py +0 -0
  160. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/result_metadata.py +0 -0
  161. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/result_registrar.py +0 -0
  162. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/result_serializer.py +0 -0
  163. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/results_metadata.py +0 -0
  164. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/results/results_registrar.py +0 -0
  165. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/run/run_listener_stdout.py +0 -0
  166. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/run/run_metadata.py +0 -0
  167. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/run/run_registrar.py +0 -0
  168. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/managers/test_listener.py +0 -0
  169. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/__init__.py +0 -0
  170. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/__init__.py +0 -0
  171. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/args.py +0 -0
  172. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/counting/every.py +0 -0
  173. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/function_factory.py +0 -0
  174. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/function_finder.py +0 -0
  175. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/function_focus.py +0 -0
  176. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/headers/insert.py +0 -0
  177. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/headers/mismatch.py +0 -0
  178. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/headers/replace.py +0 -0
  179. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/headers/reset_headers.py +0 -0
  180. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/lines/advance.py +0 -0
  181. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/lines/after_blank.py +0 -0
  182. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/lines/dups.py +0 -0
  183. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/lines/first.py +0 -0
  184. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/lines/first_line.py +0 -0
  185. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/lines/last.py +0 -0
  186. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/lines/stop.py +0 -0
  187. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/math/above.py +0 -0
  188. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/math/add.py +0 -0
  189. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/math/divide.py +0 -0
  190. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/math/equals.py +0 -0
  191. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/math/intf.py +0 -0
  192. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/math/mod.py +0 -0
  193. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/math/multiply.py +0 -0
  194. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/math/odd.py +0 -0
  195. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/math/round.py +0 -0
  196. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/math/subtotal.py +0 -0
  197. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/math/subtract.py +0 -0
  198. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/math/sum.py +0 -0
  199. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/misc/importf.py +0 -0
  200. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/misc/random.py +0 -0
  201. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/print/jinjaf.py +0 -0
  202. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/print/print_line.py +0 -0
  203. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/print/print_queue.py +0 -0
  204. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/print/table.py +0 -0
  205. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/stats/percent.py +0 -0
  206. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  207. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/stats/stdev.py +0 -0
  208. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/strings/alter.py +0 -0
  209. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/strings/caps.py +0 -0
  210. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/strings/contains.py +0 -0
  211. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/strings/length.py +0 -0
  212. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/strings/lower.py +0 -0
  213. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/strings/metaphone.py +0 -0
  214. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/strings/starts_with.py +0 -0
  215. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/strings/strip.py +0 -0
  216. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/strings/substring.py +0 -0
  217. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/strings/upper.py +0 -0
  218. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/testing/debug.py +0 -0
  219. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/types/__init__.py +0 -0
  220. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/types/boolean.py +0 -0
  221. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/types/datef.py +0 -0
  222. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/types/decimal.py +0 -0
  223. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/types/email.py +0 -0
  224. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/types/string.py +0 -0
  225. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/types/type.py +0 -0
  226. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/types/url.py +0 -0
  227. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/variables/get.py +0 -0
  228. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/variables/pushpop.py +0 -0
  229. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/variables/put.py +0 -0
  230. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/functions/variables/track.py +0 -0
  231. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/lark_parser.py +0 -0
  232. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/lark_transformer.py +0 -0
  233. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/productions/__init__.py +0 -0
  234. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/productions/expression.py +0 -0
  235. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/productions/header.py +0 -0
  236. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/productions/reference.py +0 -0
  237. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/productions/term.py +0 -0
  238. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/productions/variable.py +0 -0
  239. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/util/exceptions.py +0 -0
  240. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/util/expression_encoder.py +0 -0
  241. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/util/expression_utility.py +0 -0
  242. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/util/lark_print_parser.py +0 -0
  243. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/util/print_parser.py +0 -0
  244. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/matching/util/runtime_data_collector.py +0 -0
  245. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/modes/error_mode.py +0 -0
  246. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/modes/files_mode.py +0 -0
  247. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/modes/logic_mode.py +0 -0
  248. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/modes/mode_controller.py +0 -0
  249. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/modes/print_mode.py +0 -0
  250. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/modes/return_mode.py +0 -0
  251. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/modes/run_mode.py +0 -0
  252. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/modes/source_mode.py +0 -0
  253. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/modes/transfer_mode.py +0 -0
  254. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/modes/unmatched_mode.py +0 -0
  255. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/modes/validation_mode.py +0 -0
  256. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/scanning/__init__.py +0 -0
  257. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/scanning/exceptions.py +0 -0
  258. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/scanning/parser.out +0 -0
  259. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/scanning/parsetab.py +0 -0
  260. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/scanning/scanner.py +0 -0
  261. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/scanning/scanning_lexer.py +0 -0
  262. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/azure/azure_data_reader.py +0 -0
  263. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/azure/azure_data_writer.py +0 -0
  264. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/azure/azure_fingerprinter.py +0 -0
  265. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/azure/azure_nos.py +0 -0
  266. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/azure/azure_utils.py +0 -0
  267. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/azure/azure_xlsx_data_reader.py +0 -0
  268. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/box.py +0 -0
  269. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/cache.py +0 -0
  270. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/caser.py +0 -0
  271. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/class_loader.py +0 -0
  272. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/code.py +0 -0
  273. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/config_exception.py +0 -0
  274. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/exceptions.py +0 -0
  275. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/file_info.py +0 -0
  276. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/file_readers.py +0 -0
  277. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/file_writers.py +0 -0
  278. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/gcs/gcs_data_reader.py +0 -0
  279. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/gcs/gcs_data_writer.py +0 -0
  280. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/gcs/gcs_fingerprinter.py +0 -0
  281. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/gcs/gcs_nos.py +0 -0
  282. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/gcs/gcs_utils.py +0 -0
  283. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/gcs/gcs_xlsx_data_reader.py +0 -0
  284. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/hasher.py +0 -0
  285. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/http/http_data_reader.py +0 -0
  286. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/intermediary.py +0 -0
  287. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/last_line_stats.py +0 -0
  288. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/line_counter.py +0 -0
  289. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/line_monitor.py +0 -0
  290. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/line_spooler.py +0 -0
  291. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/log_utility.py +0 -0
  292. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/pandas_data_reader.py +0 -0
  293. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/path_util.py +0 -0
  294. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/printer.py +0 -0
  295. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/references/ref_utils.py +0 -0
  296. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/references/reference_parser.py +0 -0
  297. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/references/results_reference_finder.py +0 -0
  298. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/run_home_maker.py +0 -0
  299. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/s3/s3_data_reader.py +0 -0
  300. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/s3/s3_data_writer.py +0 -0
  301. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/s3/s3_fingerprinter.py +0 -0
  302. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/s3/s3_nos.py +0 -0
  303. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/s3/s3_utils.py +0 -0
  304. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/s3/s3_xlsx_data_reader.py +0 -0
  305. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/sftp/sftp_config.py +0 -0
  306. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/sftp/sftp_data_reader.py +0 -0
  307. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/sftp/sftp_data_writer.py +0 -0
  308. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/sftp/sftp_fingerprinter.py +0 -0
  309. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/sftp/sftp_nos.py +0 -0
  310. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/sftp/sftp_walk.py +0 -0
  311. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/sftp/sftp_xlsx_data_reader.py +0 -0
  312. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/sqliter.py +0 -0
  313. {csvpath-0.0.537 → csvpath-0.0.541}/csvpath/util/template_util.py +0 -0
  314. {csvpath-0.0.537 → 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.537
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
@@ -36,18 +36,19 @@ csvpaths = inputs/named_paths
36
36
  on_unmatched_file_fingerprints = halt
37
37
 
38
38
  [listeners]
39
- groups = default
39
+ groups = sql
40
+
40
41
  sql.file = from csvpath.managers.integrations.sql.sql_file_listener import SqlFileListener
41
42
  sql.paths = from csvpath.managers.integrations.sql.sql_paths_listener import SqlPathsListener
42
43
  sql.result = from csvpath.managers.integrations.sql.sql_result_listener import SqlResultListener
43
44
  sql.results = from csvpath.managers.integrations.sql.sql_results_listener import SqlResultsListener
44
- sqlite.result = from csvpath.managers.integrations.sqlite.sqlite_result_listener import SqliteResultListener
45
- sqlite.results = from csvpath.managers.integrations.sqlite.sqlite_results_listener import SqliteResultsListener
46
- default.file = from csvpath.managers.files.files_listener import FilesListener
47
- default.paths = from csvpath.managers.paths.paths_listener import PathsListener
48
45
  otlp.result = from csvpath.managers.integrations.otlp.otlp_result_listener import OpenTelemetryResultListener
49
46
  otlp.results = from csvpath.managers.integrations.otlp.otlp_results_listener import OpenTelemetryResultsListener
50
47
  otlp.errors = from csvpath.managers.integrations.otlp.otlp_error_listener import OpenTelemetryErrorListener
48
+ default.file = from csvpath.managers.files.files_listener import FilesListener
49
+ default.paths = from csvpath.managers.paths.paths_listener import PathsListener
50
+ sqlite.result = from csvpath.managers.integrations.sqlite.sqlite_result_listener import SqliteResultListener
51
+ sqlite.results = from csvpath.managers.integrations.sqlite.sqlite_results_listener import SqliteResultsListener
51
52
  sftpplus.paths = from csvpath.managers.integrations.sftpplus.sftpplus_listener import SftpPlusListener
52
53
  sftp.results = from csvpath.managers.integrations.sftp.sftp_listener import SftpListener
53
54
  ckan.results = from csvpath.managers.integrations.ckan.ckan_listener import CkanListener
@@ -68,7 +69,7 @@ password = tinpenny
68
69
 
69
70
  [sql]
70
71
  dialect = mysql
71
- connection_string = mysql://csvpath:hangzhou@192.168.66.1/csvpath
72
+ connection_string = mysql://csvpath:password1@192.168.66.1/csvpath
72
73
 
73
74
  [sqlite]
74
75
  db = archive/csvpath.db
@@ -81,7 +82,7 @@ port = SFTPPLUS_PORT
81
82
  admin_username = SFTPPLUS_ADMIN_USERNAME
82
83
  admin_password = SFTPPLUS_ADMIN_PASSWORD
83
84
  api_url = https://localhost:10020/json
84
- scripts_dir =
85
+ scripts_dir =
85
86
  execute_timeout = 300
86
87
 
87
88
  [ckan]
@@ -96,5 +97,5 @@ timeout = 5
96
97
  verify = False
97
98
 
98
99
  [slack]
99
- webhook_url =
100
+ webhook_url =
100
101
 
@@ -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
@@ -824,7 +824,15 @@ class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
824
824
  if self.csvpaths is None:
825
825
  return data
826
826
  name = self._get_name(data)
827
- path = self.csvpaths.file_manager.get_named_file(name)
827
+ #
828
+ # this will blow up frequently when name is an actual path. ie name == path
829
+ # below. since we want file manager to be discriminating we have to catch
830
+ # the error and reset the name
831
+ #
832
+ try:
833
+ path = self.csvpaths.file_manager.get_named_file(name)
834
+ except ValueError:
835
+ path = name
828
836
  if path is None:
829
837
  return data
830
838
  if path == name:
@@ -967,7 +975,8 @@ class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
967
975
  def limit_collection_to(self, indexes: List[int]) -> None:
968
976
  """@private"""
969
977
  self._limit_collection_to = indexes
970
- 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)
971
980
 
972
981
  def stop(self) -> None:
973
982
  """@private"""
@@ -1129,7 +1138,7 @@ class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
1129
1138
  #
1130
1139
  # DataFileReader is abstract. instantiating it results in a concrete subclass.
1131
1140
  # pylint doesn't like that just because it doesn't see what we're doing.
1132
- # 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.
1133
1142
  #
1134
1143
  reader = DataFileReader( # pylint: disable=E0110
1135
1144
  self.scanner.filename, delimiter=self.delimiter, quotechar=self.quotechar
@@ -1256,9 +1265,13 @@ class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
1256
1265
  ls = []
1257
1266
  for k in self.limit_collection_to:
1258
1267
  if k is None or k >= len(line):
1259
- raise InputException(
1260
- f"[{self.identity}] Line {self.line_monitor.physical_line_number}: unknown header name: {k} of {self.limit_collection_to} in headers {self.headers}"
1261
- )
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)
1262
1275
  ls.append(line[k])
1263
1276
  return ls
1264
1277
 
@@ -1313,6 +1326,12 @@ class CsvPath(ErrorCollector, Printer): # pylint: disable=R0902, R0904
1313
1326
  if use_cache:
1314
1327
  uc = self.csvpaths.config.get(section="cache", name="use_cache")
1315
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
+ #
1316
1335
  if self.csvpaths and use_cache is True:
1317
1336
  self.line_monitor = self.csvpaths.file_manager.lines_and_headers_cacher.get_new_line_monitor(
1318
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
 
@@ -295,6 +295,17 @@ class FileManager:
295
295
  # this feels like the better sig.
296
296
  #
297
297
  def has_named_file(self, name: NamedFileName) -> bool:
298
+ #
299
+ # cannot be a reference or part of a reference. has to just
300
+ # be the simple name of the named file.
301
+ #
302
+ try:
303
+ self.legal_name(name)
304
+ except Exception:
305
+ return False
306
+ #
307
+ # the home should exist if the named file exists.
308
+ #
298
309
  p = self.named_file_home(name)
299
310
  nos = self.nos
300
311
  nos.path = p
@@ -310,11 +321,19 @@ class FileManager:
310
321
 
311
322
  def remove_named_file(self, name: NamedFileName) -> None:
312
323
  """@private"""
324
+ #
325
+ # cannot delete any specific files. this is for the named_file
326
+ # as a whole. the named_file is immutable, so this is all-or-nothing
327
+ # and we expect it to happen rarely in a production env.
328
+ #
329
+ self.legal_name(name)
313
330
  p = os.path.join(self.named_files_dir, name)
314
331
  nos = self.nos
315
332
  nos.path = p
316
333
  if nos.exists():
317
334
  nos.remove()
335
+ return True
336
+ return False
318
337
 
319
338
  def remove_all_named_files(self) -> None:
320
339
  """@private"""
@@ -351,6 +370,22 @@ class FileManager:
351
370
  if self.csvpaths.ecoms.do_i_raise():
352
371
  raise
353
372
 
373
+ def legal_name(self, name: str) -> None:
374
+ if name is None:
375
+ raise ValueError("Name cannot be None")
376
+ if name.strip() == "":
377
+ raise ValueError("Name cannot be empty")
378
+ if name.find("/") > -1 or name.find("\\") > -1:
379
+ raise ValueError(
380
+ f"Not a legal name: {name}. Path seperators are not allowed."
381
+ )
382
+ if name.find(".") > -1:
383
+ raise ValueError(f"Not a legal name: {name}. Periods are not allowed.")
384
+ if name.find("$") > -1:
385
+ raise ValueError(f"Not a legal name: {name}. Dollarsigns are not allowed.")
386
+ if name.find("#") > -1:
387
+ raise ValueError(f"Not a legal name: {name}. Hashmarks are not allowed.")
388
+
354
389
  #
355
390
  # if name is provided all files selected will be registered under the same name in
356
391
  # the order they are found; which is likely not deterministic. template, if any, is
@@ -364,8 +399,12 @@ class FileManager:
364
399
  def add_named_files_from_dir(
365
400
  self, dirname: str, *, name=None, template: str = None, recurse=True
366
401
  ):
367
- if dirname is None or dirname.strip() == "":
368
- raise ValueError("Dirname cannot be None or empty")
402
+ #
403
+ # legal_name handled at add_named_file
404
+ #
405
+ # self.legal_name(name)
406
+ # if dirname is None or dirname.strip() == "":
407
+ # raise ValueError("Dirname cannot be None or empty")
369
408
  #
370
409
  # need to support adding all files from directory under the same name. preferably
371
410
  # in order of file created time, if possible.
@@ -405,8 +444,9 @@ class FileManager:
405
444
  def add_named_file(
406
445
  self, *, name: NamedFileName, path: str, template: str = None
407
446
  ) -> None:
408
- if name is None or name.strip() == "":
409
- raise ValueError("Name cannot be None or empty")
447
+ self.legal_name(name)
448
+ # if name is None or name.strip() == "":
449
+ # raise ValueError("Name cannot be None or empty")
410
450
  if path is None or path.strip() == "":
411
451
  raise ValueError("Path cannot be None or empty")
412
452
  if template is not None:
@@ -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()