csvpath 0.0.587__tar.gz → 0.0.589__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 (376) hide show
  1. {csvpath-0.0.587 → csvpath-0.0.589}/PKG-INFO +1 -1
  2. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/function_factory.py +15 -7
  3. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/function_finder.py +33 -13
  4. csvpath-0.0.589/csvpath/util/class_loader.py +218 -0
  5. {csvpath-0.0.587 → csvpath-0.0.589}/pyproject.toml +1 -1
  6. csvpath-0.0.587/csvpath/util/class_loader.py +0 -105
  7. {csvpath-0.0.587 → csvpath-0.0.589}/LICENSE +0 -0
  8. {csvpath-0.0.587 → csvpath-0.0.589}/README.md +0 -0
  9. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/config.ini +0 -0
  10. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/extra-functions.imports +0 -0
  11. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/function.imports +0 -0
  12. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-local-azure.ini +0 -0
  13. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-local-filesystem-mysql.ini +0 -0
  14. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-local-gcs.ini +0 -0
  15. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-local-s3.ini +0 -0
  16. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-local-sftp.ini +0 -0
  17. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-windows-azure.ini +0 -0
  18. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-windows-gcs.ini +0 -0
  19. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-windows-local.ini +0 -0
  20. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-windows-s3.ini +0 -0
  21. {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-windows-sftp.ini +0 -0
  22. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/azure-pipeline.gopipeline.json +0 -0
  23. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/azure.sh +0 -0
  24. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/gcs-pipeline.gopipeline.json +0 -0
  25. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/gcs.sh +0 -0
  26. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/local-pipeline.gopipeline copy.json +0 -0
  27. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/local.sh +0 -0
  28. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/s3-pipeline.gopipeline.json +0 -0
  29. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/s3.sh +0 -0
  30. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/sftp-pipeline.gopipeline.json +0 -0
  31. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/sftp.sh +0 -0
  32. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/azure.bat +0 -0
  33. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/gcs.bat +0 -0
  34. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/local.bat +0 -0
  35. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/s3.bat +0 -0
  36. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/sftp.bat +0 -0
  37. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/windows-azure.gopipeline.json +0 -0
  38. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/windows-gcs.gopipeline.json +0 -0
  39. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/windows-local.gopipeline.json +0 -0
  40. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/windows-s3.gopipeline.json +0 -0
  41. {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/windows-sftp.gopipeline.json +0 -0
  42. {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sftpplus/handle_auto_arrival.bat +0 -0
  43. {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sftpplus/handle_auto_arrival.py +0 -0
  44. {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sftpplus/handle_auto_arrival.sh +0 -0
  45. {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sftpplus/handle_mailbox_arrival.bat +0 -0
  46. {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sftpplus/handle_mailbox_arrival.py +0 -0
  47. {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sftpplus/handle_mailbox_arrival.sh +0 -0
  48. {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sqlite/csvpath +0 -0
  49. {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sqlite/schema.sql +0 -0
  50. {csvpath-0.0.587 → csvpath-0.0.589}/config/config.ini +0 -0
  51. {csvpath-0.0.587 → csvpath-0.0.589}/config/env.json +0 -0
  52. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/__init__.py +0 -0
  53. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/__init__.py +0 -0
  54. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/asker.py +0 -0
  55. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/cli.py +0 -0
  56. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/const.py +0 -0
  57. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/debug_config.py +0 -0
  58. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/drill_down.py +0 -0
  59. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/function_describer.py +0 -0
  60. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/function_lister.py +0 -0
  61. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/selecter.py +0 -0
  62. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/csvpath.py +0 -0
  63. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/csvpaths.py +0 -0
  64. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/__init__.py +0 -0
  65. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/errors/error.py +0 -0
  66. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/errors/error_collector.py +0 -0
  67. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/errors/error_comms.py +0 -0
  68. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/errors/error_manager.py +0 -0
  69. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/files/file_manager.py +0 -0
  70. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/files/file_metadata.py +0 -0
  71. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/files/file_registrar.py +0 -0
  72. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/files/files_listener.py +0 -0
  73. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/files/lines_and_headers_cacher.py +0 -0
  74. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ckan/ckan.py +0 -0
  75. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ckan/ckan_listener.py +0 -0
  76. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ckan/datafile.py +0 -0
  77. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ckan/dataset.py +0 -0
  78. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/event.py +0 -0
  79. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/event_result.py +0 -0
  80. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/file_listener_ol.py +0 -0
  81. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/job.py +0 -0
  82. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/ol_listener.py +0 -0
  83. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/paths_listener_ol.py +0 -0
  84. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/result_listener_ol.py +0 -0
  85. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/results_listener_ol.py +0 -0
  86. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/run.py +0 -0
  87. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/run_listener_ol.py +0 -0
  88. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/run_state.py +0 -0
  89. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/sender.py +0 -0
  90. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/error_metrics.py +0 -0
  91. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/metrics.py +0 -0
  92. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/otlp_error_listener.py +0 -0
  93. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/otlp_file_listener.py +0 -0
  94. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/otlp_listener.py +0 -0
  95. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/otlp_paths_listener.py +0 -0
  96. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/otlp_result_listener.py +0 -0
  97. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/otlp_results_listener.py +0 -0
  98. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/scripts/scripts_results_listener.py +0 -0
  99. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sftp/sftp_sender.py +0 -0
  100. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sftpplus/arrival_handler.py +0 -0
  101. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sftpplus/rpc.py +0 -0
  102. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sftpplus/sftpplus_listener.py +0 -0
  103. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sftpplus/transfer_creator.py +0 -0
  104. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sftpplus/transfers.py +0 -0
  105. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/slack/event.py +0 -0
  106. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/slack/sender.py +0 -0
  107. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/engine.py +0 -0
  108. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/sql_file_listener.py +0 -0
  109. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/sql_listener.py +0 -0
  110. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/sql_paths_listener.py +0 -0
  111. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/sql_result_listener.py +0 -0
  112. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/sql_results_listener.py +0 -0
  113. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/tables.py +0 -0
  114. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/updates.py +0 -0
  115. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sqlite/schema.sql +0 -0
  116. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sqlite/sqlite_result_listener.py +0 -0
  117. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sqlite/sqlite_results_listener.py +0 -0
  118. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/webhook/webhook_listener.py +0 -0
  119. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/webhook/webhook_results_listener.py +0 -0
  120. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/listener.py +0 -0
  121. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/metadata.py +0 -0
  122. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/paths/paths_listener.py +0 -0
  123. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/paths/paths_manager.py +0 -0
  124. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/paths/paths_metadata.py +0 -0
  125. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/paths/paths_registrar.py +0 -0
  126. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/registrar.py +0 -0
  127. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/readers/file_errors_reader.py +0 -0
  128. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/readers/file_lines_reader.py +0 -0
  129. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/readers/file_printouts_reader.py +0 -0
  130. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/readers/file_unmatched_reader.py +0 -0
  131. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/readers/readers.py +0 -0
  132. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/result.py +0 -0
  133. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/result_file_reader.py +0 -0
  134. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/result_metadata.py +0 -0
  135. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/result_registrar.py +0 -0
  136. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/result_serializer.py +0 -0
  137. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/results_manager.py +0 -0
  138. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/results_metadata.py +0 -0
  139. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/results_registrar.py +0 -0
  140. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/run/run_listener_stdout.py +0 -0
  141. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/run/run_metadata.py +0 -0
  142. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/run/run_registrar.py +0 -0
  143. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/test_listener.py +0 -0
  144. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/__init__.py +0 -0
  145. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/__init__.py +0 -0
  146. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/args.py +0 -0
  147. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/args_helper.py +0 -0
  148. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/all.py +0 -0
  149. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/andf.py +0 -0
  150. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/any.py +0 -0
  151. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/between.py +0 -0
  152. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/empty.py +0 -0
  153. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/exists.py +0 -0
  154. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/inf.py +0 -0
  155. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/no.py +0 -0
  156. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/notf.py +0 -0
  157. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/orf.py +0 -0
  158. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/yes.py +0 -0
  159. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/count.py +0 -0
  160. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/count_bytes.py +0 -0
  161. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/count_headers.py +0 -0
  162. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/count_lines.py +0 -0
  163. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/count_scans.py +0 -0
  164. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/counter.py +0 -0
  165. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/every.py +0 -0
  166. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/has_matches.py +0 -0
  167. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/increment.py +0 -0
  168. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/tally.py +0 -0
  169. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/total_lines.py +0 -0
  170. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/dates/now.py +0 -0
  171. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/dates/part.py +0 -0
  172. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/dates/roll.py +0 -0
  173. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/function.py +0 -0
  174. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/function_focus.py +0 -0
  175. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/append.py +0 -0
  176. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/collect.py +0 -0
  177. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/empty_stack.py +0 -0
  178. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/end.py +0 -0
  179. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/header_name.py +0 -0
  180. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
  181. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/headers.py +0 -0
  182. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/headers_stack.py +0 -0
  183. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/insert.py +0 -0
  184. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/line_before.py +0 -0
  185. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/mismatch.py +0 -0
  186. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/remove.py +0 -0
  187. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/rename.py +0 -0
  188. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/replace.py +0 -0
  189. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/reset_headers.py +0 -0
  190. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/json/jsonpath.py +0 -0
  191. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/advance.py +0 -0
  192. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/after_blank.py +0 -0
  193. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/dups.py +0 -0
  194. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/first.py +0 -0
  195. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/first_line.py +0 -0
  196. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/last.py +0 -0
  197. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/stop.py +0 -0
  198. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/above.py +0 -0
  199. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/add.py +0 -0
  200. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/divide.py +0 -0
  201. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/equals.py +0 -0
  202. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/intf.py +0 -0
  203. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/mod.py +0 -0
  204. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/multiply.py +0 -0
  205. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/odd.py +0 -0
  206. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/round.py +0 -0
  207. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/subtotal.py +0 -0
  208. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/subtract.py +0 -0
  209. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/sum.py +0 -0
  210. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/misc/fingerprint.py +0 -0
  211. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/misc/importf.py +0 -0
  212. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/misc/random.py +0 -0
  213. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/print/jinjaf.py +0 -0
  214. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/print/print_line.py +0 -0
  215. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/print/print_queue.py +0 -0
  216. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/print/printf.py +0 -0
  217. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/print/table.py +0 -0
  218. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/stats/minf.py +0 -0
  219. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/stats/nminmax.py +0 -0
  220. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/stats/percent.py +0 -0
  221. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  222. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/stats/stdev.py +0 -0
  223. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/alter.py +0 -0
  224. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/caps.py +0 -0
  225. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/concat.py +0 -0
  226. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/contains.py +0 -0
  227. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/format.py +0 -0
  228. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/length.py +0 -0
  229. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/lower.py +0 -0
  230. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/metaphone.py +0 -0
  231. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/regex.py +0 -0
  232. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/starts_with.py +0 -0
  233. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/strip.py +0 -0
  234. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/substring.py +0 -0
  235. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/upper.py +0 -0
  236. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/testing/debug.py +0 -0
  237. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/__init__.py +0 -0
  238. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/blank.py +0 -0
  239. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/boolean.py +0 -0
  240. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/datatype.py +0 -0
  241. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/datef.py +0 -0
  242. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/decimal.py +0 -0
  243. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/email.py +0 -0
  244. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/nonef.py +0 -0
  245. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/string.py +0 -0
  246. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/type.py +0 -0
  247. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/url.py +0 -0
  248. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/wildcard.py +0 -0
  249. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/validity/fail.py +0 -0
  250. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/validity/failed.py +0 -0
  251. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/validity/line.py +0 -0
  252. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/clear.py +0 -0
  253. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/get.py +0 -0
  254. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/index_of.py +0 -0
  255. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/pushpop.py +0 -0
  256. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/put.py +0 -0
  257. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/track.py +0 -0
  258. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/variables.py +0 -0
  259. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/xml/xpath.py +0 -0
  260. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/lark_parser.py +0 -0
  261. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/lark_transformer.py +0 -0
  262. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/matcher.py +0 -0
  263. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/__init__.py +0 -0
  264. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/equality.py +0 -0
  265. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/expression.py +0 -0
  266. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/header.py +0 -0
  267. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/matchable.py +0 -0
  268. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/qualified.py +0 -0
  269. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/reference.py +0 -0
  270. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/term.py +0 -0
  271. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/variable.py +0 -0
  272. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/util/exceptions.py +0 -0
  273. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/util/expression_encoder.py +0 -0
  274. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/util/expression_utility.py +0 -0
  275. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/util/lark_print_parser.py +0 -0
  276. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/util/print_parser.py +0 -0
  277. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/util/runtime_data_collector.py +0 -0
  278. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/error_mode.py +0 -0
  279. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/explain_mode.py +0 -0
  280. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/files_mode.py +0 -0
  281. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/logic_mode.py +0 -0
  282. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/mode_controller.py +0 -0
  283. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/print_mode.py +0 -0
  284. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/return_mode.py +0 -0
  285. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/run_mode.py +0 -0
  286. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/source_mode.py +0 -0
  287. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/transfer_mode.py +0 -0
  288. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/unmatched_mode.py +0 -0
  289. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/validation_mode.py +0 -0
  290. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/scanning/__init__.py +0 -0
  291. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/scanning/scanner2.py +0 -0
  292. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/scanning/scanner2_parser.py +0 -0
  293. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/scanning/scanner2_transformer.py +0 -0
  294. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_data_reader.py +0 -0
  295. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_data_writer.py +0 -0
  296. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_fingerprinter.py +0 -0
  297. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_json_data_reader.py +0 -0
  298. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_nos.py +0 -0
  299. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_utils.py +0 -0
  300. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_xlsx_data_reader.py +0 -0
  301. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/backend_check.py +0 -0
  302. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/box.py +0 -0
  303. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/cache.py +0 -0
  304. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/caser.py +0 -0
  305. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/code.py +0 -0
  306. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/config.py +0 -0
  307. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/config_env.py +0 -0
  308. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/config_exception.py +0 -0
  309. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/date_util.py +0 -0
  310. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/exceptions.py +0 -0
  311. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/file_info.py +0 -0
  312. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/file_readers.py +0 -0
  313. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/file_writers.py +0 -0
  314. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_data_reader.py +0 -0
  315. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_data_writer.py +0 -0
  316. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_fingerprinter.py +0 -0
  317. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_json_data_reader.py +0 -0
  318. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_nos.py +0 -0
  319. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_utils.py +0 -0
  320. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_xlsx_data_reader.py +0 -0
  321. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/hasher.py +0 -0
  322. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/http/http_data_reader.py +0 -0
  323. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/intermediary.py +0 -0
  324. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/json/json_data_reader.py +0 -0
  325. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/json/json_reader_helper.py +0 -0
  326. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/last_line_stats.py +0 -0
  327. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/line_counter.py +0 -0
  328. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/line_monitor.py +0 -0
  329. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/line_spooler.py +0 -0
  330. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/log_utility.py +0 -0
  331. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/metadata_parser.py +0 -0
  332. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/nos.py +0 -0
  333. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/pandas_data_reader.py +0 -0
  334. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/path_util.py +0 -0
  335. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/printer.py +0 -0
  336. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/py_file_utility.py +0 -0
  337. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/files_reference_finder_2.py +0 -0
  338. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/files_tools/fingerprint_finder.py +0 -0
  339. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/files_tools/range_finder.py +0 -0
  340. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/ref_utils.py +0 -0
  341. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/reference_exceptions.py +0 -0
  342. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/reference_grammar.py +0 -0
  343. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/reference_manifest_entry_finder.py +0 -0
  344. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/reference_parser.py +0 -0
  345. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/reference_results.py +0 -0
  346. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/reference_transformer.py +0 -0
  347. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_reference_finder_2.py +0 -0
  348. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/data_finder.py +0 -0
  349. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/date_filter.py +0 -0
  350. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/identity_finder.py +0 -0
  351. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/path_filter.py +0 -0
  352. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/resolve_possibles.py +0 -0
  353. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/token_filters.py +0 -0
  354. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/yesterday_or_today_translator.py +0 -0
  355. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/tools/date_completer.py +0 -0
  356. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/run_home_maker.py +0 -0
  357. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_data_reader.py +0 -0
  358. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_data_writer.py +0 -0
  359. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_fingerprinter.py +0 -0
  360. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_json_data_reader.py +0 -0
  361. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_nos.py +0 -0
  362. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_utils.py +0 -0
  363. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_xlsx_data_reader.py +0 -0
  364. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_config.py +0 -0
  365. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_data_reader.py +0 -0
  366. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_data_writer.py +0 -0
  367. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_fingerprinter.py +0 -0
  368. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_json_data_reader.py +0 -0
  369. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_nos.py +0 -0
  370. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_walk.py +0 -0
  371. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_xlsx_data_reader.py +0 -0
  372. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sqliter.py +0 -0
  373. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/template_util.py +0 -0
  374. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/var_utility.py +0 -0
  375. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/xlsx/xlsx_data_reader.py +0 -0
  376. {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/xlsx/xlsx_reader_helper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: csvpath
3
- Version: 0.0.587
3
+ Version: 0.0.589
4
4
  Summary: A data preboarding framework for ingesting, managing, and validating CSV, Excel, and other tabular data files using a Collect, Store, Validate, Publish architecture to create a trusted publisher for downstream data consumers.
5
5
  Author: David Kershaw
6
6
  Author-email: info@csvpath.org
@@ -151,7 +151,7 @@ class FunctionFactory:
151
151
  raise InvalidNameException("Name must not be an empty string")
152
152
  if not cls.valid_function_name(name): # name.isalpha():
153
153
  raise InvalidNameException(f"Name {name} is not valid")
154
- cls._debug(function.matcher, "Looking for an existing function named %s", name)
154
+ cls._debug_one(function.matcher, "Looking for an existing function named %s", name)
155
155
  if cls.get_function(None, name=name, find_external_functions=False) is not None:
156
156
  function.matcher.csvpath.logger.warning(
157
157
  "Internal function is overriden by external function: %s", name
@@ -161,16 +161,24 @@ class FunctionFactory:
161
161
  raise InvalidChildException(
162
162
  "Function being registered must be passed as an instance"
163
163
  )
164
- cls._debug(function.matcher, "Adding %s as key to %s", name, function.__class__)
164
+ cls._debug_two(function.matcher, "Adding %s as key to %s", name, function.__class__)
165
165
  cls.NOT_MY_FUNCTION[name] = function.__class__
166
166
 
167
167
  @classmethod
168
- def _debug(cls, matcher, txt: str, obj=None, obj2=None) -> None:
168
+ def _debug_one(cls, matcher, txt: str, obj=None) -> None:
169
169
  if matcher is None:
170
170
  return
171
171
  if matcher.csvpath is None:
172
172
  return
173
- matcher.csvpath.logger.debug(txt, obj, obj2)
173
+ matcher.csvpath.logger.debug(txt, str(obj))
174
+
175
+ @classmethod
176
+ def _debug_two(cls, matcher, txt: str, obj=None, obj2=None) -> None:
177
+ if matcher is None:
178
+ return
179
+ if matcher.csvpath is None:
180
+ return
181
+ matcher.csvpath.logger.debug(txt, str(obj), str(obj2))
174
182
 
175
183
  #
176
184
  # valid function names start with a letter and contain only letters,
@@ -297,13 +305,13 @@ class FunctionFactory:
297
305
  # if proj not set we check for name
298
306
  #
299
307
  qname = cls.qname(matcher=matcher, name=name)
300
- cls._debug(matcher, "Qualified name of %s is %s", name, qname)
308
+ cls._debug_two(matcher, "Qualified name of %s is %s", name, qname)
301
309
  if qname in FunctionFactory.NOT_MY_FUNCTION:
302
310
  f = cls.NOT_MY_FUNCTION[qname]
303
311
  f = f(matcher, name, child)
304
- cls._debug(matcher, "Found %s as %s", qname, f)
312
+ cls._debug_two(matcher, "Found %s as %s", qname, f)
305
313
  if f is None:
306
- cls._debug(
314
+ cls._debug_two(
307
315
  matcher, "%s not in: %s", qname, FunctionFactory.NOT_MY_FUNCTION
308
316
  )
309
317
  return f
@@ -24,7 +24,7 @@ class FunctionFinder: # pylint: disable=R0903
24
24
  if path is None or path.strip() == "":
25
25
  matcher.csvpath.logger.error("No [functions][imports] in config.ini")
26
26
  return
27
- cls._debug(matcher, "Functions import file is at %s", path)
27
+ cls._debug_one(matcher, "Functions import file is at %s", path)
28
28
  if not os.path.exists(path):
29
29
  matcher.csvpath.logger.error(
30
30
  f"[functions][imports] path {path} in {config.configpath} does not exist"
@@ -39,23 +39,37 @@ class FunctionFinder: # pylint: disable=R0903
39
39
  line = str(line).strip()
40
40
  if line == "" or line.startswith("#"):
41
41
  continue
42
- cls._debug(matcher, "Adding function %s", line)
43
- cls._add_function(matcher, func_fact, line)
42
+ cls._debug_one(matcher, "Adding function %s", line)
43
+ try:
44
+ cls._add_function(matcher, func_fact, line)
45
+ except Exception:
46
+ matcher.csvpath.logger.exception(
47
+ f"Could not add function for '{line}'"
48
+ )
44
49
  matcher.csvpath.logger.info("Added %s external functions", i)
45
50
  # add a sentinel to keep us from attempting reload.
46
51
  # this instance will never be found, but the dict will
47
52
  # never be empty
48
53
  e = cls.externals_sentinel(matcher)
49
54
  func_fact.add_function(e, Yes(None, e))
50
- cls._debug(matcher, "Added sentinel function %s", e)
55
+ cls._debug_one(matcher, "Added sentinel function %s", e)
51
56
 
52
57
  @classmethod
53
- def _debug(cls, matcher, txt: str, obj=None, obj2=None) -> None:
58
+ def _debug_one(cls, matcher, txt: str, obj=None) -> None:
54
59
  if matcher is None:
55
60
  return
56
61
  if matcher.csvpath is None:
57
62
  return
58
- matcher.csvpath.logger.debug(txt, obj, obj2)
63
+ matcher.csvpath.logger.debug(txt, str(obj))
64
+
65
+ @classmethod
66
+ def _debug_two(cls, matcher, txt: str, obj=None, obj2=None) -> None:
67
+ if matcher is None:
68
+ return
69
+ if matcher.csvpath is None:
70
+ return
71
+ matcher.csvpath.logger.debug(txt, str(obj), str(obj2))
72
+
59
73
 
60
74
  @classmethod
61
75
  def externals_sentinel(cls, matcher) -> str:
@@ -91,14 +105,20 @@ class FunctionFinder: # pylint: disable=R0903
91
105
  # lines in config are like:
92
106
  # from module import class as function-name
93
107
  #
94
- matcher.csvpath.logger.debug("Import line is %s", cs)
108
+ cls._debug_one(matcher, "Import line is %s", cs)
95
109
  if len(cs) == 6 and cs[0] == "from" and cs[2] == "import" and cs[4] == "as":
96
110
  config = matcher.csvpath.config
97
- instance = ClassLoader.load_private_function(config, s, matcher, cs[5])
98
- qname = func_fact.qname(matcher=matcher, name=cs[5])
99
- matcher.csvpath.logger.debug(
100
- "Adding custom function %s: %s", qname, instance
101
- )
102
- func_fact.add_function(qname, instance)
111
+ try:
112
+ instance = ClassLoader.load_private_function(config, s, matcher, cs[5])
113
+ qname = func_fact.qname(matcher=matcher, name=cs[5])
114
+ cls._debug_two(matcher, "Adding custom function %s: %s", qname, instance)
115
+ func_fact.add_function(qname, instance)
116
+ except Exception:
117
+ if matcher is not None and matcher.csvpath is not None:
118
+ matcher.csvpath.logger.exception(f"Cannot load class {cs}")
119
+ #
120
+ # matcher and csvpath will be present, but we check to be sure. there's no
121
+ # fallback because it is an unlikely scenario that would have its own logic.
122
+ #
103
123
  else:
104
124
  raise ConfigurationException("Unclear external function imports: {s}")
@@ -0,0 +1,218 @@
1
+ import importlib
2
+ import os
3
+ from typing import Any
4
+
5
+
6
+ class ClassLoadingError(RuntimeError):
7
+ ...
8
+
9
+
10
+ class ClassLoader:
11
+ #
12
+ # load is fine for classes we expect. e.g. we load specific types of data readers and writers
13
+ # using this method without any concerns about different projects needing to not collide. today
14
+ # we treat integration listeners the same way, but longer term we need those to be able to be
15
+ # custom loaded too.
16
+ #
17
+ @classmethod
18
+ def load(cls, s: str, args: list = None, kwargs: dict = None) -> Any:
19
+ s = s.strip()
20
+ if s != "":
21
+ instance = None
22
+ cs = s.split(" ")
23
+ #
24
+ # lines in config are like:
25
+ # from module import class
26
+ #
27
+ if len(cs) == 4 and cs[0] == "from" and cs[2] == "import":
28
+ module = importlib.import_module(cs[1])
29
+ class_ = getattr(module, cs[3])
30
+ args = args if args is not None else []
31
+ kwargs = kwargs if kwargs is not None else {}
32
+ instance = class_(*args, **kwargs)
33
+ return instance
34
+ else:
35
+ raise ClassLoadingError(f"Unclear class loading import statement: {s}")
36
+ return None
37
+
38
+ #
39
+ # this loads a custom function using a name that is distinct across projects so there
40
+ # is no risk of name collisions.
41
+ #
42
+ @classmethod
43
+ def load_private_function(cls, config, stmt: str, *args, **kwargs):
44
+ imports = config.get(section="functions", name="imports")
45
+ if not imports or str(imports).strip() == "":
46
+ raise ValueError("Imports cannot be None or ''")
47
+ imports = os.path.dirname(imports)
48
+ return cls.load_private_class(imports, stmt, *args, **kwargs)
49
+
50
+ """
51
+ @classmethod
52
+ def load_private_class(cls, base_path: str, stmt: str, *args, **kwargs):
53
+ if not stmt or stmt.strip() == "":
54
+ raise ValueError("Load statement cannot be None or ''")
55
+ module_name = None
56
+ class_name = None
57
+ #
58
+ # remove the imports file name. functions must be in or below the dir
59
+ # where the functions file is.
60
+ #
61
+ # /x/y/z/function.imports
62
+ # /x/y/z
63
+ # from a.b.c import C as cone
64
+ #
65
+ # we look in /x/y/z/a/b/c.py for class C
66
+ # base module clss
67
+ #
68
+ cs = stmt.split(" ")
69
+ if len(cs) >= 4 and cs[0] == "from" and cs[2] == "import":
70
+ module_name = cs[1]
71
+ class_name = cs[3]
72
+ else:
73
+ raise ClassLoadingError(f"Unclear class loading import statement: {stmt}")
74
+ #
75
+ # Resolve the file path for the module
76
+ #
77
+ module_path = os.path.join(base_path, module_name)
78
+ module_path = module_path.replace(".", os.sep)
79
+ module_path = f"{module_path}.py"
80
+ if not os.path.exists(module_path):
81
+ raise ImportError(f"Module {module_name} not found in {module_path}")
82
+ #
83
+ # create a unique module spec. we hash the full path to the bytes in order
84
+ # to make sure we have a distinct class, even if one project names and locates
85
+ # a class in the exact same relative location.
86
+ #
87
+ # e.g. project A has a function.imports file at config/function.imports that defines a class B as:
88
+ # from b import B as bee
89
+ # project B has a function.imports file at config/function.imports that defines a class B as:
90
+ # from b import B as bee
91
+ # These two class Bs would be identified exactly the same way even though they are different. We
92
+ # don't ever want a request for project B's class B to be returned when project A requests a
93
+ # class B. The hash keeps the names distinct.
94
+ #
95
+ try:
96
+ import py_compile
97
+ py_compile.compile(str(module_path), doraise=True)
98
+ print(f"Compiled fine")
99
+ except Exception as ex:
100
+ print(f"Cannot compile: {ex}")
101
+
102
+ try:
103
+ print("ABS:", os.path.abspath(module_path))
104
+ print("REAL:", os.path.realpath(module_path))
105
+ print("EXISTS:", os.path.exists(module_path))
106
+ print("ISFILE:", os.path.isfile(module_path))
107
+ print("ACCESS_R:", os.access(module_path, os.R_OK))
108
+ print("ACCESS_X:", os.access(module_path, os.X_OK))
109
+ except Exception as ex:
110
+ print(f"Cannot print module_path attributes: {ex}")
111
+
112
+ spec = importlib.util.spec_from_file_location(
113
+ f"{module_name}_{hash(module_path)}", # unique name per loader instance
114
+ str(module_path),
115
+ )
116
+ module = importlib.util.module_from_spec(spec)
117
+ loader = spec.loader
118
+ if loader is None:
119
+ raise ImportError(f"Could not load spec for {module_name} at {module_path}")
120
+ loader.exec_module(module)
121
+ cls = getattr(module, class_name)
122
+ instance = cls(*args, **kwargs)
123
+ return instance
124
+ """
125
+
126
+ @classmethod
127
+ def load_private_class(cls, base_path: str, stmt: str, *args, **kwargs):
128
+ if not stmt or stmt.strip() == "":
129
+ raise ValueError("Load statement cannot be None or ''")
130
+ module_name = None
131
+ class_name = None
132
+ #
133
+ # remove the imports file name. functions must be in or below the dir
134
+ # where the functions file is.
135
+ #
136
+ # /x/y/z/function.imports
137
+ # /x/y/z
138
+ # from a.b.c import C as cone
139
+ #
140
+ # we look in /x/y/z/a/b/c.py for class C
141
+ # base module clss
142
+ #
143
+ cs = stmt.split(" ")
144
+ if len(cs) >= 4 and cs[0] == "from" and cs[2] == "import":
145
+ module_name = cs[1]
146
+ class_name = cs[3]
147
+ else:
148
+ raise ClassLoadingError(f"Unclear class loading import statement: {stmt}")
149
+ #
150
+ # Resolve the file path for the module
151
+ #
152
+ module_path = os.path.join(base_path, module_name)
153
+ module_path = module_path.replace(".", os.sep)
154
+ module_path = f"{module_path}.py"
155
+ if not os.path.exists(module_path):
156
+ raise ImportError(f"Module {module_name} not found in {module_path}")
157
+ #
158
+ # create a unique module spec. we hash the full path to the bytes in order
159
+ # to make sure we have a distinct class, even if one project names and locates
160
+ # a class in the exact same relative location.
161
+ #
162
+ # e.g. project A has a function.imports file at config/function.imports that defines a class B as:
163
+ # from b import B as bee
164
+ # project B has a function.imports file at config/function.imports that defines a class B as:
165
+ # from b import B as bee
166
+ # These two class Bs would be identified exactly the same way even though they are different. We
167
+ # don't ever want a request for project B's class B to be returned when project A requests a
168
+ # class B. The hash keeps the names distinct.
169
+ #
170
+ compiled_path = None
171
+ try:
172
+ import py_compile
173
+ # py_compile.compile(str(module_path), doraise=True)
174
+ compiled_path = py_compile.compile(
175
+ str(module_path),
176
+ cfile=str(module_path) + "c", # or any path you choose
177
+ doraise=True,
178
+ )
179
+ print(f"Classloader: compiled fine to: {compiled_path}")
180
+
181
+ except Exception as ex:
182
+ print(f"Classloader: cannot compile: {ex}")
183
+ #
184
+ # debugging. can remove
185
+ #
186
+ try:
187
+ print("Classloader: ABS:", os.path.abspath(module_path))
188
+ print("Classloader: REAL:", os.path.realpath(module_path))
189
+ print("Classloader: EXISTS:", os.path.exists(module_path))
190
+ print("Classloader: ISFILE:", os.path.isfile(module_path))
191
+ print("Classloader: ACCESS_R:", os.access(module_path, os.R_OK))
192
+ print("Classloader: ACCESS_X:", os.access(module_path, os.X_OK))
193
+ except Exception as ex:
194
+ print(f"Classloader: cannot print module_path attributes: {ex}")
195
+ #
196
+ # end debugging.
197
+ #
198
+ """
199
+ spec = importlib.util.spec_from_file_location(
200
+ f"{module_name}_{hash(module_path)}", # unique name per loader instance
201
+ str(module_path),
202
+ )
203
+ """
204
+ spec = importlib.util.spec_from_file_location(
205
+ f"{module_name}_{hash(compiled_path)}", compiled_path
206
+ )
207
+ # module = importlib.util.module_from_spec(spec)
208
+ # spec.loader.exec_module(module)
209
+
210
+ module = importlib.util.module_from_spec(spec)
211
+ loader = spec.loader
212
+ if loader is None:
213
+ raise ImportError(f"Classloader: could not load spec for {module_name} at {module_path}")
214
+ loader.exec_module(module)
215
+ cls = getattr(module, class_name)
216
+ instance = cls(*args, **kwargs)
217
+ print(f"Classloader: returning instance: {instance}")
218
+ return instance
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "csvpath"
3
- version = "0.0.587"
3
+ version = "0.0.589"
4
4
  description = "A data preboarding framework for ingesting, managing, and validating CSV, Excel, and other tabular data files using a Collect, Store, Validate, Publish architecture to create a trusted publisher for downstream data consumers."
5
5
  authors = ["David Kershaw <info@csvpath.org>"]
6
6
  readme = "README.md"
@@ -1,105 +0,0 @@
1
- import importlib
2
- import os
3
- from typing import Any
4
-
5
-
6
- class ClassLoadingError(RuntimeError):
7
- ...
8
-
9
-
10
- class ClassLoader:
11
- #
12
- # load is fine for classes we expect. e.g. we load specific types of data readers and writers
13
- # using this method without any concerns about different projects needing to not collide. today
14
- # we treat integration listeners the same way, but longer term we need those to be able to be
15
- # custom loaded too.
16
- #
17
- @classmethod
18
- def load(cls, s: str, args: list = None, kwargs: dict = None) -> Any:
19
- s = s.strip()
20
- if s != "":
21
- instance = None
22
- cs = s.split(" ")
23
- #
24
- # lines in config are like:
25
- # from module import class
26
- #
27
- if len(cs) == 4 and cs[0] == "from" and cs[2] == "import":
28
- module = importlib.import_module(cs[1])
29
- class_ = getattr(module, cs[3])
30
- args = args if args is not None else []
31
- kwargs = kwargs if kwargs is not None else {}
32
- instance = class_(*args, **kwargs)
33
- return instance
34
- else:
35
- raise ClassLoadingError(f"Unclear class loading import statement: {s}")
36
- return None
37
-
38
- #
39
- # this loads a custom function using a name that is distinct across projects so there
40
- # is no risk of name collisions.
41
- #
42
- @classmethod
43
- def load_private_function(cls, config, stmt: str, *args, **kwargs):
44
- imports = config.get(section="functions", name="imports")
45
- if not imports or str(imports).strip() == "":
46
- raise ValueError("Imports cannot be None or ''")
47
- imports = os.path.dirname(imports)
48
- return cls.load_private_class(imports, stmt, *args, **kwargs)
49
-
50
- @classmethod
51
- def load_private_class(cls, base_path: str, stmt: str, *args, **kwargs):
52
- if not stmt or stmt.strip() == "":
53
- raise ValueError("Load statement cannot be None or ''")
54
- module_name = None
55
- class_name = None
56
- #
57
- # remove the imports file name. functions must be in or below the dir
58
- # where the functions file is.
59
- #
60
- # /x/y/z/function.imports
61
- # /x/y/z
62
- # from a.b.c import C as cone
63
- #
64
- # we look in /x/y/z/a/b/c.py for class C
65
- # base module clss
66
- #
67
- cs = stmt.split(" ")
68
- if len(cs) >= 4 and cs[0] == "from" and cs[2] == "import":
69
- module_name = cs[1]
70
- class_name = cs[3]
71
- else:
72
- raise ClassLoadingError(f"Unclear class loading import statement: {stmt}")
73
- #
74
- # Resolve the file path for the module
75
- #
76
- module_path = os.path.join(base_path, module_name)
77
- module_path = module_path.replace(".", os.sep)
78
- module_path = f"{module_path}.py"
79
- if not os.path.exists(module_path):
80
- raise ImportError(f"Module {module_name} not found in {module_path}")
81
- #
82
- # create a unique module spec. we hash the full path to the bytes in order
83
- # to make sure we have a distinct class, even if one project names and locates
84
- # a class in the exact same relative location.
85
- #
86
- # e.g. project A has a function.imports file at config/function.imports that defines a class B as:
87
- # from b import B as bee
88
- # project B has a function.imports file at config/function.imports that defines a class B as:
89
- # from b import B as bee
90
- # These two class Bs would be identified exactly the same way even though they are different. We
91
- # don't ever want a request for project B's class B to be returned when project A requests a
92
- # class B. The hash keeps the names distinct.
93
- #
94
- spec = importlib.util.spec_from_file_location(
95
- f"{module_name}_{hash(module_path)}", # unique name per loader instance
96
- str(module_path),
97
- )
98
- module = importlib.util.module_from_spec(spec)
99
- loader = spec.loader
100
- if loader is None:
101
- raise ImportError(f"Could not load spec for {module_name} at {module_path}")
102
- loader.exec_module(module)
103
- cls = getattr(module, class_name)
104
- instance = cls(*args, **kwargs)
105
- return instance
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes