csvpath 0.0.617__tar.gz → 0.0.619__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 (411) hide show
  1. {csvpath-0.0.617 → csvpath-0.0.619}/PKG-INFO +1 -1
  2. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/jenkins-windows-local.ini +3 -3
  3. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/windows/azure.bat +11 -2
  4. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/windows/gcs.bat +6 -2
  5. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/windows/local.bat +7 -2
  6. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/windows/s3.bat +8 -2
  7. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/windows/sftp.bat +8 -2
  8. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/csvpaths.py +11 -4
  9. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/files/file_manager.py +56 -1
  10. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/files/file_registrar.py +13 -9
  11. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/transfers_manager.py +6 -0
  12. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/sql/select.py +7 -0
  13. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/sql/sql_in.py +30 -15
  14. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/nos.py +85 -0
  15. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/path_util.py +35 -0
  16. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/sftp/sftp_config.py +48 -9
  17. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/sftp/sftp_data_reader.py +0 -30
  18. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/sftp/sftp_nos.py +90 -9
  19. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/sftp/sftp_server_creds.py +15 -5
  20. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/sqliter.py +2 -1
  21. {csvpath-0.0.617 → csvpath-0.0.619}/pyproject.toml +1 -1
  22. {csvpath-0.0.617 → csvpath-0.0.619}/LICENSE +0 -0
  23. {csvpath-0.0.617 → csvpath-0.0.619}/README.md +0 -0
  24. {csvpath-0.0.617 → csvpath-0.0.619}/assets/.DS_Store +0 -0
  25. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/config.ini +0 -0
  26. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/extra-functions.imports +0 -0
  27. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/function.imports +0 -0
  28. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/jenkins-local-azure.ini +0 -0
  29. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/jenkins-local-filesystem-mysql.ini +0 -0
  30. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/jenkins-local-gcs.ini +0 -0
  31. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/jenkins-local-s3.ini +0 -0
  32. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/jenkins-local-sftp.ini +0 -0
  33. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/jenkins-windows-azure.ini +0 -0
  34. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/jenkins-windows-gcs.ini +0 -0
  35. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/jenkins-windows-s3.ini +0 -0
  36. {csvpath-0.0.617 → csvpath-0.0.619}/assets/config/jenkins-windows-sftp.ini +0 -0
  37. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/.DS_Store +0 -0
  38. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/Mac.goenvironment.json +0 -0
  39. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/Windows.goenvironment.json +0 -0
  40. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/mac/azure-pipeline.gopipeline.json +0 -0
  41. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/mac/azure.sh +0 -0
  42. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/mac/gcs.sh +0 -0
  43. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/mac/google-pipeline.gopipeline.json +0 -0
  44. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/mac/local-pipeline.gopipeline copy.json +0 -0
  45. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/mac/local.sh +0 -0
  46. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/mac/s3-pipeline.gopipeline.json +0 -0
  47. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/mac/s3.sh +0 -0
  48. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/mac/sftp-pipeline.gopipeline.json +0 -0
  49. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/mac/sftp.sh +0 -0
  50. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/windows/windows-azure.gopipeline.json +0 -0
  51. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/windows/windows-gcs.gopipeline.json +0 -0
  52. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/windows/windows-local.gopipeline.json +0 -0
  53. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/windows/windows-s3.gopipeline.json +0 -0
  54. {csvpath-0.0.617 → csvpath-0.0.619}/assets/gocd/windows/windows-sftp.gopipeline.json +0 -0
  55. {csvpath-0.0.617 → csvpath-0.0.619}/assets/integrations/.DS_Store +0 -0
  56. {csvpath-0.0.617 → csvpath-0.0.619}/assets/integrations/sftpplus/handle_auto_arrival.bat +0 -0
  57. {csvpath-0.0.617 → csvpath-0.0.619}/assets/integrations/sftpplus/handle_auto_arrival.py +0 -0
  58. {csvpath-0.0.617 → csvpath-0.0.619}/assets/integrations/sftpplus/handle_auto_arrival.sh +0 -0
  59. {csvpath-0.0.617 → csvpath-0.0.619}/assets/integrations/sftpplus/handle_mailbox_arrival.bat +0 -0
  60. {csvpath-0.0.617 → csvpath-0.0.619}/assets/integrations/sftpplus/handle_mailbox_arrival.py +0 -0
  61. {csvpath-0.0.617 → csvpath-0.0.619}/assets/integrations/sftpplus/handle_mailbox_arrival.sh +0 -0
  62. {csvpath-0.0.617 → csvpath-0.0.619}/assets/integrations/sqlite/csvpath +0 -0
  63. {csvpath-0.0.617 → csvpath-0.0.619}/assets/integrations/sqlite/schema.sql +0 -0
  64. {csvpath-0.0.617 → csvpath-0.0.619}/assets/libs/release_candidate_maker-0.0.25-py3-none-any.whl +0 -0
  65. {csvpath-0.0.617 → csvpath-0.0.619}/assets/libs/release_candidate_maker-0.0.27-py3-none-any.whl +0 -0
  66. {csvpath-0.0.617 → csvpath-0.0.619}/assets/libs/release_candidate_maker-0.0.28-py3-none-any.whl +0 -0
  67. {csvpath-0.0.617 → csvpath-0.0.619}/assets/libs/release_candidate_maker-0.0.29-py3-none-any.whl +0 -0
  68. {csvpath-0.0.617 → csvpath-0.0.619}/assets/libs/release_candidate_maker-0.0.30.tar.gz +0 -0
  69. {csvpath-0.0.617 → csvpath-0.0.619}/assets/libs/release_candidate_maker-0.0.31.tar.gz +0 -0
  70. {csvpath-0.0.617 → csvpath-0.0.619}/assets/libs/release_candidate_maker-0.0.33.tar.gz +0 -0
  71. {csvpath-0.0.617 → csvpath-0.0.619}/assets/libs/release_candidate_maker-0.0.34.tar.gz +0 -0
  72. {csvpath-0.0.617 → csvpath-0.0.619}/assets/libs/release_candidate_maker-0.0.35.tar.gz +0 -0
  73. {csvpath-0.0.617 → csvpath-0.0.619}/assets/libs/release_candidate_maker-0.0.36.tar.gz +0 -0
  74. {csvpath-0.0.617 → csvpath-0.0.619}/config/config.ini +0 -0
  75. {csvpath-0.0.617 → csvpath-0.0.619}/config/env.json +0 -0
  76. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/__init__.py +0 -0
  77. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/cli/__init__.py +0 -0
  78. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/cli/asker.py +0 -0
  79. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/cli/cli.py +0 -0
  80. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/cli/const.py +0 -0
  81. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/cli/debug_config.py +0 -0
  82. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/cli/drill_down.py +0 -0
  83. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/cli/function_describer.py +0 -0
  84. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/cli/function_lister.py +0 -0
  85. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/cli/selecter.py +0 -0
  86. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/csvpath.py +0 -0
  87. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/__init__.py +0 -0
  88. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/errors/error.py +0 -0
  89. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/errors/error_collector.py +0 -0
  90. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/errors/error_comms.py +0 -0
  91. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/errors/error_manager.py +0 -0
  92. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/files/file_activator.py +0 -0
  93. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/files/file_describer.py +0 -0
  94. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/files/file_descriptor.py +0 -0
  95. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/files/file_metadata.py +0 -0
  96. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/files/file_names_rules.py +0 -0
  97. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/files/files_activation_listener.py +0 -0
  98. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/files/files_listener.py +0 -0
  99. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/files/lines_and_headers_cacher.py +0 -0
  100. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ckan/ckan.py +0 -0
  101. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ckan/ckan_listener.py +0 -0
  102. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ckan/datafile.py +0 -0
  103. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ckan/dataset.py +0 -0
  104. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ol/event.py +0 -0
  105. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ol/event_result.py +0 -0
  106. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ol/file_listener_ol.py +0 -0
  107. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ol/job.py +0 -0
  108. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ol/ol_listener.py +0 -0
  109. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ol/paths_listener_ol.py +0 -0
  110. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ol/result_listener_ol.py +0 -0
  111. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ol/results_listener_ol.py +0 -0
  112. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ol/run.py +0 -0
  113. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ol/run_listener_ol.py +0 -0
  114. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ol/run_state.py +0 -0
  115. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/ol/sender.py +0 -0
  116. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/otlp/error_metrics.py +0 -0
  117. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/otlp/metrics.py +0 -0
  118. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/otlp/otlp_error_listener.py +0 -0
  119. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/otlp/otlp_file_listener.py +0 -0
  120. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/otlp/otlp_listener.py +0 -0
  121. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/otlp/otlp_paths_listener.py +0 -0
  122. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/otlp/otlp_result_listener.py +0 -0
  123. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/otlp/otlp_results_listener.py +0 -0
  124. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/scripts/scripts_results_listener.py +0 -0
  125. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/sftp/sftp_sender.py +0 -0
  126. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/slack/event.py +0 -0
  127. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/slack/sender.py +0 -0
  128. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/sql/engine.py +0 -0
  129. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/sql/sql_file_listener.py +0 -0
  130. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/sql/sql_listener.py +0 -0
  131. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/sql/sql_paths_listener.py +0 -0
  132. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/sql/sql_result_listener.py +0 -0
  133. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/sql/sql_results_listener.py +0 -0
  134. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/sql/tables.py +0 -0
  135. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/sql/updates.py +0 -0
  136. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/sqlite/schema.sql +0 -0
  137. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/sqlite/sqlite_result_listener.py +0 -0
  138. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/sqlite/sqlite_results_listener.py +0 -0
  139. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/webhook/webhook_listener.py +0 -0
  140. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/integrations/webhook/webhook_results_listener.py +0 -0
  141. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/listener.py +0 -0
  142. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/metadata.py +0 -0
  143. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/paths/paths_describer.py +0 -0
  144. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/paths/paths_descriptor.py +0 -0
  145. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/paths/paths_listener.py +0 -0
  146. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/paths/paths_manager.py +0 -0
  147. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/paths/paths_metadata.py +0 -0
  148. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/paths/paths_registrar.py +0 -0
  149. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/registrar.py +0 -0
  150. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/readers/file_errors_reader.py +0 -0
  151. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/readers/file_lines_reader.py +0 -0
  152. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/readers/file_printouts_reader.py +0 -0
  153. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/readers/file_unmatched_reader.py +0 -0
  154. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/readers/readers.py +0 -0
  155. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/result.py +0 -0
  156. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/result_file_reader.py +0 -0
  157. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/result_metadata.py +0 -0
  158. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/result_registrar.py +0 -0
  159. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/result_serializer.py +0 -0
  160. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/results_manager.py +0 -0
  161. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/results_metadata.py +0 -0
  162. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/results/results_registrar.py +0 -0
  163. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/run/run_listener_stdout.py +0 -0
  164. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/run/run_metadata.py +0 -0
  165. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/run/run_registrar.py +0 -0
  166. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/server_config.py +0 -0
  167. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/managers/test_listener.py +0 -0
  168. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/__init__.py +0 -0
  169. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/__init__.py +0 -0
  170. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/args.py +0 -0
  171. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/args_helper.py +0 -0
  172. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/boolean/all.py +0 -0
  173. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/boolean/andf.py +0 -0
  174. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/boolean/any.py +0 -0
  175. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/boolean/between.py +0 -0
  176. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/boolean/empty.py +0 -0
  177. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/boolean/exists.py +0 -0
  178. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/boolean/inf.py +0 -0
  179. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/boolean/no.py +0 -0
  180. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/boolean/notf.py +0 -0
  181. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/boolean/orf.py +0 -0
  182. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/boolean/yes.py +0 -0
  183. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/counting/count.py +0 -0
  184. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/counting/count_bytes.py +0 -0
  185. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/counting/count_headers.py +0 -0
  186. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/counting/count_lines.py +0 -0
  187. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/counting/count_scans.py +0 -0
  188. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/counting/counter.py +0 -0
  189. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/counting/every.py +0 -0
  190. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/counting/has_matches.py +0 -0
  191. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/counting/increment.py +0 -0
  192. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/counting/tally.py +0 -0
  193. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/counting/total_lines.py +0 -0
  194. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/dates/now.py +0 -0
  195. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/dates/part.py +0 -0
  196. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/dates/roll.py +0 -0
  197. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/function.py +0 -0
  198. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/function_factory.py +0 -0
  199. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/function_finder.py +0 -0
  200. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/function_focus.py +0 -0
  201. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/append.py +0 -0
  202. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/collect.py +0 -0
  203. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/empty_stack.py +0 -0
  204. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/end.py +0 -0
  205. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/header_name.py +0 -0
  206. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
  207. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/headers.py +0 -0
  208. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/headers_stack.py +0 -0
  209. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/insert.py +0 -0
  210. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/line_before.py +0 -0
  211. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/mismatch.py +0 -0
  212. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/remove.py +0 -0
  213. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/rename.py +0 -0
  214. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/replace.py +0 -0
  215. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/headers/reset_headers.py +0 -0
  216. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/json/jsonpath.py +0 -0
  217. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/lines/advance.py +0 -0
  218. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/lines/after_blank.py +0 -0
  219. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/lines/dups.py +0 -0
  220. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/lines/first.py +0 -0
  221. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/lines/first_line.py +0 -0
  222. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/lines/last.py +0 -0
  223. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/lines/stop.py +0 -0
  224. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/math/above.py +0 -0
  225. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/math/add.py +0 -0
  226. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/math/divide.py +0 -0
  227. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/math/equals.py +0 -0
  228. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/math/intf.py +0 -0
  229. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/math/mod.py +0 -0
  230. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/math/multiply.py +0 -0
  231. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/math/odd.py +0 -0
  232. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/math/round.py +0 -0
  233. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/math/subtotal.py +0 -0
  234. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/math/subtract.py +0 -0
  235. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/math/sum.py +0 -0
  236. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/misc/env.py +0 -0
  237. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/misc/fingerprint.py +0 -0
  238. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/misc/importf.py +0 -0
  239. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/misc/metadata.py +0 -0
  240. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/misc/parquet.py +0 -0
  241. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/misc/random.py +0 -0
  242. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/misc/runtime.py +0 -0
  243. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/print/jinjaf.py +0 -0
  244. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/print/print_line.py +0 -0
  245. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/print/print_queue.py +0 -0
  246. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/print/printf.py +0 -0
  247. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/print/table.py +0 -0
  248. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/stats/minf.py +0 -0
  249. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/stats/nminmax.py +0 -0
  250. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/stats/percent.py +0 -0
  251. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/stats/percent_unique.py +0 -0
  252. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/stats/stdev.py +0 -0
  253. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/alter.py +0 -0
  254. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/caps.py +0 -0
  255. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/concat.py +0 -0
  256. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/contains.py +0 -0
  257. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/format.py +0 -0
  258. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/length.py +0 -0
  259. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/lower.py +0 -0
  260. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/metaphone.py +0 -0
  261. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/regex.py +0 -0
  262. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/starts_with.py +0 -0
  263. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/strip.py +0 -0
  264. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/substring.py +0 -0
  265. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/strings/upper.py +0 -0
  266. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/testing/debug.py +0 -0
  267. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/__init__.py +0 -0
  268. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/blank.py +0 -0
  269. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/boolean.py +0 -0
  270. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/datatype.py +0 -0
  271. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/datef.py +0 -0
  272. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/decimal.py +0 -0
  273. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/email.py +0 -0
  274. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/nonef.py +0 -0
  275. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/string.py +0 -0
  276. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/type.py +0 -0
  277. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/url.py +0 -0
  278. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/uuid.py +0 -0
  279. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/types/wildcard.py +0 -0
  280. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/validity/fail.py +0 -0
  281. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/validity/failed.py +0 -0
  282. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/validity/line.py +0 -0
  283. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/validity/matches.py +0 -0
  284. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/validity/percent_matching.py +0 -0
  285. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/variables/clear.py +0 -0
  286. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/variables/get.py +0 -0
  287. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/variables/index_of.py +0 -0
  288. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/variables/pushpop.py +0 -0
  289. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/variables/put.py +0 -0
  290. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/variables/slice.py +0 -0
  291. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/variables/sort.py +0 -0
  292. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/variables/track.py +0 -0
  293. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/variables/variables.py +0 -0
  294. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/functions/xml/xpath.py +0 -0
  295. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/lark_parser.py +0 -0
  296. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/lark_transformer.py +0 -0
  297. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/matcher.py +0 -0
  298. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/productions/__init__.py +0 -0
  299. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/productions/equality.py +0 -0
  300. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/productions/expression.py +0 -0
  301. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/productions/header.py +0 -0
  302. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/productions/matchable.py +0 -0
  303. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/productions/qualified.py +0 -0
  304. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/productions/reference.py +0 -0
  305. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/productions/term.py +0 -0
  306. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/productions/variable.py +0 -0
  307. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/util/exceptions.py +0 -0
  308. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/util/expression_encoder.py +0 -0
  309. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/util/expression_utility.py +0 -0
  310. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/util/lark_print_parser.py +0 -0
  311. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/util/parquet_utility.py +0 -0
  312. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/util/print_parser.py +0 -0
  313. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/matching/util/runtime_data_collector.py +0 -0
  314. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/modes/error_mode.py +0 -0
  315. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/modes/explain_mode.py +0 -0
  316. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/modes/files_mode.py +0 -0
  317. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/modes/logic_mode.py +0 -0
  318. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/modes/mode_controller.py +0 -0
  319. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/modes/print_mode.py +0 -0
  320. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/modes/return_mode.py +0 -0
  321. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/modes/run_mode.py +0 -0
  322. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/modes/source_mode.py +0 -0
  323. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/modes/transfer_mode.py +0 -0
  324. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/modes/unmatched_mode.py +0 -0
  325. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/modes/validation_mode.py +0 -0
  326. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/scanning/__init__.py +0 -0
  327. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/scanning/scanner2.py +0 -0
  328. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/scanning/scanner2_parser.py +0 -0
  329. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/scanning/scanner2_transformer.py +0 -0
  330. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/azure/azure_data_reader.py +0 -0
  331. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/azure/azure_data_writer.py +0 -0
  332. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/azure/azure_fingerprinter.py +0 -0
  333. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/azure/azure_json_data_reader.py +0 -0
  334. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/azure/azure_nos.py +0 -0
  335. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/azure/azure_timing_policy.py +0 -0
  336. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/azure/azure_utils.py +0 -0
  337. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/azure/azure_xlsx_data_reader.py +0 -0
  338. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/backend_check.py +0 -0
  339. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/box.py +0 -0
  340. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/cache.py +0 -0
  341. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/caser.py +0 -0
  342. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/class_loader.py +0 -0
  343. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/code.py +0 -0
  344. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/config.py +0 -0
  345. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/config_env.py +0 -0
  346. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/config_exception.py +0 -0
  347. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/date_util.py +0 -0
  348. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/exceptions.py +0 -0
  349. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/file_info.py +0 -0
  350. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/file_readers.py +0 -0
  351. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/file_utility.py +0 -0
  352. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/file_writers.py +0 -0
  353. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/gcs/gcs_data_reader.py +0 -0
  354. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/gcs/gcs_data_writer.py +0 -0
  355. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/gcs/gcs_fingerprinter.py +0 -0
  356. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/gcs/gcs_json_data_reader.py +0 -0
  357. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/gcs/gcs_nos.py +0 -0
  358. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/gcs/gcs_utils.py +0 -0
  359. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/gcs/gcs_xlsx_data_reader.py +0 -0
  360. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/hasher.py +0 -0
  361. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/http/http_data_reader.py +0 -0
  362. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/intermediary.py +0 -0
  363. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/json/json_data_reader.py +0 -0
  364. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/json/json_reader_helper.py +0 -0
  365. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/last_line_stats.py +0 -0
  366. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/line_counter.py +0 -0
  367. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/line_monitor.py +0 -0
  368. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/line_spooler.py +0 -0
  369. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/log_utility.py +0 -0
  370. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/metadata_parser.py +0 -0
  371. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/pandas_data_reader.py +0 -0
  372. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/printer.py +0 -0
  373. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/py_file_utility.py +0 -0
  374. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/files_reference_finder_2.py +0 -0
  375. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/files_tools/fingerprint_finder.py +0 -0
  376. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/files_tools/range_finder.py +0 -0
  377. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/ref_utils.py +0 -0
  378. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/reference_exceptions.py +0 -0
  379. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/reference_grammar.py +0 -0
  380. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/reference_manifest_entry_finder.py +0 -0
  381. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/reference_parser.py +0 -0
  382. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/reference_results.py +0 -0
  383. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/reference_transformer.py +0 -0
  384. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/results_reference_finder_2.py +0 -0
  385. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/results_tools/data_finder.py +0 -0
  386. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/results_tools/date_filter.py +0 -0
  387. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/results_tools/identity_finder.py +0 -0
  388. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/results_tools/path_filter.py +0 -0
  389. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/results_tools/resolve_possibles.py +0 -0
  390. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/results_tools/token_filters.py +0 -0
  391. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/results_tools/yesterday_or_today_translator.py +0 -0
  392. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/references/tools/date_completer.py +0 -0
  393. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/referrer_printer.py +0 -0
  394. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/run_home_maker.py +0 -0
  395. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/s3/s3_data_reader.py +0 -0
  396. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/s3/s3_data_writer.py +0 -0
  397. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/s3/s3_fingerprinter.py +0 -0
  398. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/s3/s3_json_data_reader.py +0 -0
  399. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/s3/s3_nos.py +0 -0
  400. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/s3/s3_utils.py +0 -0
  401. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/s3/s3_xlsx_data_reader.py +0 -0
  402. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/sftp/sftp_data_writer.py +0 -0
  403. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/sftp/sftp_fingerprinter.py +0 -0
  404. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/sftp/sftp_json_data_reader.py +0 -0
  405. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/sftp/sftp_walk.py +0 -0
  406. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/sftp/sftp_xlsx_data_reader.py +0 -0
  407. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/stopwatch.py +0 -0
  408. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/template_util.py +0 -0
  409. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/var_utility.py +0 -0
  410. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/xlsx/xlsx_data_reader.py +0 -0
  411. {csvpath-0.0.617 → csvpath-0.0.619}/csvpath/util/xlsx/xlsx_reader_helper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csvpath
3
- Version: 0.0.617
3
+ Version: 0.0.619
4
4
  Summary: CsvPath Framework is a data preboarding automation library for receiving, validating, and tracking CSV, Excel, JSONL and other tabular data files before they can corrupt downstream data consumers.
5
5
  License-File: LICENSE
6
6
  Author: David Kershaw
@@ -26,7 +26,7 @@ path = cache
26
26
  use_cache = no
27
27
 
28
28
  [functions]
29
- imports =
29
+ imports =
30
30
 
31
31
  [results]
32
32
  archive = tmp\local\archive
@@ -86,7 +86,7 @@ port = SFTPPLUS_PORT
86
86
  admin_username = SFTPPLUS_ADMIN_USERNAME
87
87
  admin_password = SFTPPLUS_ADMIN_PASSWORD
88
88
  api_url = https://. . . :10020/json
89
- scripts_dir =
89
+ scripts_dir =
90
90
  execute_timeout = 300
91
91
 
92
92
  [ckan]
@@ -101,7 +101,7 @@ timeout = 5
101
101
  verify = False
102
102
 
103
103
  [slack]
104
- webhook_url =
104
+ webhook_url =
105
105
 
106
106
  [scripts]
107
107
  run_scripts = yes
@@ -26,9 +26,18 @@ set OTEL_RESOURCE_ATTRIBUTES=""
26
26
 
27
27
  echo %CSVPATH_CONFIG_PATH%
28
28
  call c:\dev\win-exports.bat
29
- cmd.exe /C c:\Users\python\.local\bin\poetry.exe install
30
- cmd.exe /C c:\Users\python\.local\bin\poetry.exe run pytest
31
29
 
30
+ IF NOT EXIST "%USERPROFILE%\.local\bin\poetry.exe" (
31
+ echo ERROR: The Poetry binary was not found.
32
+ EXIT /B 1
33
+ )
34
+
35
+ cmd.exe /C "%USERPROFILE%\.local\bin\poetry.exe" install
36
+ cmd.exe /C "%USERPROFILE%\.local\bin\poetry.exe" run pytest
37
+ if %ERRORLEVEL% neq 0 (
38
+ echo [ERROR] The pytest failed with code %ERRORLEVEL%.
39
+ exit /b %ERRORLEVEL%
40
+ )
32
41
 
33
42
  net stop w32time
34
43
  w32tm /unregister
@@ -25,9 +25,13 @@ set OTEL_SERVICE_NAME=""
25
25
  set OTEL_RESOURCE_ATTRIBUTES=""
26
26
 
27
27
  call c:\dev\win-exports.bat
28
- cmd.exe /C c:\Users\python\.local\bin\poetry.exe install
29
- cmd.exe /C c:\Users\python\.local\bin\poetry.exe run pytest
30
28
 
29
+ cmd.exe /C "%USERPROFILE%\.local\bin\poetry.exe" install
30
+ cmd.exe /C "%USERPROFILE%\.local\bin\poetry.exe" run pytest
31
+ IF %ERRORLEVEL% NEQ 0 (
32
+ echo "Tests failed. Failing the build..."
33
+ exit /b %ERRORLEVEL%
34
+ )
31
35
 
32
36
  net stop w32time
33
37
  w32tm /unregister
@@ -49,8 +49,13 @@ echo(
49
49
  ::
50
50
  :: do the build
51
51
  ::
52
- cmd.exe /C c:\Users\python\.local\bin\poetry.exe install
53
- cmd.exe /C c:\Users\python\.local\bin\poetry.exe run pytest
52
+ cmd.exe /C "%USERPROFILE%\.local\bin\poetry.exe" install
53
+ cmd.exe /C "%USERPROFILE%\.local\bin\poetry.exe" run pytest
54
+ if %ERRORLEVEL% neq 0 (
55
+ echo [ERROR] The pytest failed with code %ERRORLEVEL%.
56
+ exit /b %ERRORLEVEL%
57
+ )
58
+
54
59
 
55
60
 
56
61
  net stop w32time
@@ -27,8 +27,14 @@ set OTEL_RESOURCE_ATTRIBUTES=""
27
27
 
28
28
 
29
29
  call c:\dev\win-exports.bat
30
- cmd.exe /C c:\Users\python\.local\bin\poetry.exe install
31
- cmd.exe /C c:\Users\python\.local\bin\poetry.exe run pytest
30
+
31
+ cmd.exe /C "%USERPROFILE%\.local\bin\poetry.exe" install
32
+ cmd.exe /C "%USERPROFILE%\.local\bin\poetry.exe" run pytest
33
+ if %ERRORLEVEL% neq 0 (
34
+ echo [ERROR] The pytest failed with code %ERRORLEVEL%.
35
+ exit /b %ERRORLEVEL%
36
+ )
37
+
32
38
 
33
39
 
34
40
  net stop w32time
@@ -25,8 +25,14 @@ set OTEL_SERVICE_NAME=""
25
25
  set OTEL_RESOURCE_ATTRIBUTES=""
26
26
 
27
27
  call c:\dev\win-exports.bat
28
- cmd.exe /C c:\Users\python\.local\bin\poetry.exe install
29
- cmd.exe /C c:\Users\python\.local\bin\poetry.exe run pytest
28
+
29
+ cmd.exe /C "%USERPROFILE%\.local\bin\poetry.exe" install
30
+ cmd.exe /C "%USERPROFILE%\.local\bin\poetry.exe" run pytest
31
+ if %ERRORLEVEL% neq 0 (
32
+ echo [ERROR] The pytest failed with code %ERRORLEVEL%.
33
+ exit /b %ERRORLEVEL%
34
+ )
35
+
30
36
 
31
37
 
32
38
  net stop w32time
@@ -4,7 +4,6 @@ of the CsvPath library. it makes it easier to scale your CSV quality control."""
4
4
  import os
5
5
  import traceback
6
6
  import atexit
7
- import threading
8
7
 
9
8
  from uuid import uuid4
10
9
  from abc import ABC, abstractmethod
@@ -226,9 +225,17 @@ class CsvPaths(CsvPathsCoordinator, ErrorCollector):
226
225
  #
227
226
  #
228
227
  #
229
- self.logger.info(
230
- f"Initialized CsvPaths: {self} in thread: {threading.current_thread()}"
231
- )
228
+ # this log line didn't add especial value. but it did set the logger
229
+ # to a certain log file before we had a chance to do a cd-and-reload
230
+ # to switch into a particular project. the fix isn't just to remove the
231
+ # line, it's also to make the logger travel with the config used. but
232
+ # removing the log line is easy enough and we don't lose much. And the
233
+ # real fix was already in set_config_path_and_reload() -- it was just
234
+ # releasing/renewing the logger.
235
+ #
236
+ # self.logger.info(
237
+ # f"Initialized CsvPaths: {self} in thread: {threading.current_thread()}"
238
+ # )
232
239
 
233
240
  @property
234
241
  def logger(self):
@@ -283,6 +283,13 @@ class FileManager:
283
283
  home = pathu.resep(home)
284
284
  return home
285
285
 
286
+ #
287
+ # creates a named-file before registering any files.
288
+ #
289
+ def assure_named_file(self, name: NamedFileName) -> None:
290
+ home = self.assure_named_file_home(name)
291
+ self.registrar.manifest_path(home)
292
+
286
293
  def configure_named_file(self, name: NamedFileName, descriptor: Config) -> None:
287
294
  #
288
295
  # updates the named-file's descriptor by replacement
@@ -665,7 +672,9 @@ class FileManager:
665
672
  self._registration_failed(_)
666
673
  #
667
674
  return
675
+ self.csvpaths.logger.info("Adding named file %s: can be loaded", name)
668
676
  self.legal_name(name)
677
+ self.csvpaths.logger.info("Adding named file %s: name is legal", name)
669
678
  if path is None or path.strip() == "":
670
679
  _ = {
671
680
  "name": name,
@@ -678,7 +687,13 @@ class FileManager:
678
687
  if template is None:
679
688
  template = self.describer.get_template(name)
680
689
  if template is not None:
690
+ self.csvpaths.logger.debug(
691
+ "Adding named file %s: checking template %s", name, template
692
+ )
681
693
  temu.valid(template, file=True)
694
+ self.csvpaths.logger.info(
695
+ "Adding named file %s: template is valid or None: %s", name, template
696
+ )
682
697
  if config is not None:
683
698
  #
684
699
  # doing config here enables copy_in() to pull down files
@@ -687,6 +702,9 @@ class FileManager:
687
702
  # configured in advance, but that doesn't have to be the
688
703
  # case.
689
704
  #
705
+ self.csvpaths.logger.info(
706
+ "Adding named file %s: configuring named-file", name
707
+ )
690
708
  self.configure_named_file(name, config)
691
709
  path = pathu.resep(path)
692
710
  self.csvpaths.logger.debug("[%s] Path after resep %s", registration_uuid, path)
@@ -696,6 +714,10 @@ class FileManager:
696
714
  local = config.get(section="inputs", name="allow_local_files", default=False)
697
715
  local = str(local).strip().lower() in ["on", "yes", "true"]
698
716
  nos = Nos(path)
717
+ self.csvpaths.logger.info(
718
+ "Adding named file %s: checking permission, if needed, to register local and http files",
719
+ name,
720
+ )
699
721
  #
700
722
  # can the descriptor override the project's prohibition on http(s) loads?
701
723
  # no. the project may be controlled by a context like FlightPath Server, where
@@ -729,6 +751,9 @@ class FileManager:
729
751
  if self.csvpaths.ecoms.do_i_raise():
730
752
  raise FileException(msg)
731
753
  return
754
+ self.csvpaths.logger.info(
755
+ "Adding named file %s: registration of %s permitted", name, path
756
+ )
732
757
  #
733
758
  # we should know enough to redirect if handed a dir path. we'll not recurse
734
759
  # because the caller hasn't given us enough info to know if we should.
@@ -737,6 +762,7 @@ class FileManager:
737
762
  # method. if using FlightPath Server, the server should allow them to be likewise
738
763
  # more specific. this branch is essentially a fallback presumed to be covering for
739
764
  # lazy developers and people who are working without better information.
765
+ #
740
766
  if nos.path.find("#") > -1:
741
767
  #
742
768
  # if we passed in a root minor, a.k.a. "mark", we need to strip
@@ -744,13 +770,35 @@ class FileManager:
744
770
  #
745
771
  nos = Nos(nos.path[0 : nos.path.find("#")])
746
772
  #
747
- # note for now we treat any http as a file
773
+ # note for now we treat any http as a file.
774
+ #
775
+ # also note that this Nos must be savvy to any ServerConfig that may
776
+ # be available. it should use the possibly cached backend, if that
777
+ # matches, but if not, it must search any ServerConfig to configure
778
+ # itself to do operations on one of those servers.
779
+ #
780
+ # server config can be passed to a non-sftp nos. there won't be any
781
+ # complaints, but it won't do anything. atm, the judgement call is that
782
+ # we save an if-test by allowing any nos to receive server config and
783
+ # accepting the cost of searching for any server config in json.
784
+ #
785
+ config = self.describer.get_config(name)
786
+ servers = config.sources
787
+ nos.server_config = servers
788
+ #
789
+ # for _ in servers:
790
+ # if _.matches(nos.path):
791
+ # nos.do._config = SftpConfig(_)
748
792
  #
749
793
  isfile = nos.is_http or nos.isfile()
794
+ self.csvpaths.logger.debug(
795
+ "Adding named file %s: path %s is a file? %s", name, path, isfile
796
+ )
750
797
  if not isfile:
751
798
  return self.add_named_files_from_dir(
752
799
  path, name=name, template=template, recurse=False
753
800
  )
801
+ self.csvpaths.logger.debug("Adding named file %s: continuing with file", name)
754
802
  try:
755
803
  self.csvpaths.logger.debug(
756
804
  "[%s] Ready to register %s", registration_uuid, path
@@ -896,6 +944,9 @@ class FileManager:
896
944
  mdata.template = data.get("template") or ""
897
945
  mdata.uuid_string = data.get("registration_uuid")
898
946
  mdata.status = "Registration failed"
947
+ self.csvpaths.logger.warn(
948
+ "[%s] Registration failed for %s", mdata.named_file_name, data
949
+ )
899
950
  lst.metadata_update(mdata)
900
951
 
901
952
  def _validate_xlsx_mark(self, path: str, mark: str) -> None:
@@ -927,8 +978,12 @@ class FileManager:
927
978
  fname = self._clean_file_name(fname)
928
979
  temp = f"{home}{sep}{fname}"
929
980
  copy = pathu.parts(path)[0] == pathu.parts(home)[0]
981
+ copy = copy and nos.is_local
930
982
  if copy:
931
983
  nos.path = path
984
+ config = self.describer.get_config(name)
985
+ servers = config.sources
986
+ nos.server_config = servers
932
987
  nos.copy(temp)
933
988
  else:
934
989
  self._copy_down(name=name, path=path, temp=temp, mode="wb")
@@ -154,15 +154,19 @@ class FileRegistrar(Registrar, Listener):
154
154
  raise InputException(
155
155
  f"File mgr and registrar marks should match: {mdata.mark}, {mark}"
156
156
  )
157
- if (
158
- # Nos doesn't handle http files. they are special--inbound only.
159
- not path.startswith("http:")
160
- and not path.startswith("https:")
161
- and not Nos(path).exists()
162
- ):
163
- # if not path.startswith("s3:") and not os.path.exists(path):
164
- #
165
- raise InputException(f"Path {path} does not exist")
157
+ opath = Nos(path)
158
+ #
159
+ # if we're registering a non-local file and it's an sftp file it may be
160
+ # on an sftp server that is configured in the named-file description. so
161
+ # we setup nos to be able to check, just in case.
162
+ #
163
+ config = self.csvpaths.file_manager.describer.get_config(mdata.named_file_name)
164
+ servers = config.sources
165
+ opath.server_config = servers
166
+
167
+ if not opath.is_http:
168
+ if not opath.exists():
169
+ raise InputException(f"Path {opath.path} does not exist")
166
170
  #
167
171
  # if the fingerprint already exists we don't store the file again.
168
172
  # we rename the file to the fingerprint. from this point the registrar
@@ -6,6 +6,7 @@ from csvpath.managers.paths.paths_descriptor import Transfer, Transfers
6
6
 
7
7
  from csvpath.util.nos import Nos
8
8
  from csvpath.util.path_util import PathUtility as pathu
9
+ from csvpath.util.var_utility import VarUtility as vaut
9
10
 
10
11
 
11
12
  class TransfersManager:
@@ -299,6 +300,11 @@ class TransfersManager:
299
300
  msg = f"Variable {t} is invalid: {f}"
300
301
  self.csvpaths.error_manager.handle_error(source=self, msg=msg)
301
302
  raise InputException(msg)
303
+
304
+ #
305
+ # make sure we have vars interpolated
306
+ #
307
+ f = vaut.parse_var_value(self.csvpaths.config, t, f)
302
308
  #
303
309
  # if we're shipping to another backend, we don't need to change the target location
304
310
  #
@@ -79,6 +79,7 @@ class Select(ValueProducer):
79
79
  ##################
80
80
 
81
81
  def _query(self, *, table: str, column: str, where: str, conn: str) -> bool:
82
+ engine = None
82
83
  try:
83
84
  engine = Db.get_engine(conn=conn)
84
85
  return self._do_query(
@@ -86,6 +87,12 @@ class Select(ValueProducer):
86
87
  )
87
88
  except Exception:
88
89
  print(traceback.format_exc())
90
+ finally:
91
+ if engine is not None:
92
+ try:
93
+ engine.dispose()
94
+ except Exception:
95
+ ...
89
96
 
90
97
  def _do_query(self, *, table: str, column: str, where: str, engine: Engine) -> list:
91
98
  table = sa.table(table, sa.column(column))
@@ -1,5 +1,5 @@
1
1
  from typing import Any
2
- from sqlalchemy import create_engine, Engine
2
+ from sqlalchemy import Engine
3
3
  import sqlalchemy as sa
4
4
  import traceback
5
5
 
@@ -11,7 +11,6 @@ from csvpath.matching.functions.args import Args
11
11
 
12
12
 
13
13
  class SqlIn(ValueProducer, MatchDecider):
14
-
15
14
  def __init__(self, matcher: Any, name: str, child: Matchable = None) -> None:
16
15
  super().__init__(matcher, name=name, child=child)
17
16
  self._cached = None
@@ -69,38 +68,56 @@ class SqlIn(ValueProducer, MatchDecider):
69
68
  conn = self._value_four(skip=skip)
70
69
  cache = self._value_five(skip=skip)
71
70
  cache = False if cache is None else cache
72
- self.value = self._query(table=table, column=column, value=v, conn=conn, cache=cache)
71
+ self.value = self._query(
72
+ table=table, column=column, value=v, conn=conn, cache=cache
73
+ )
73
74
 
74
75
  def _decide_match(self, skip=None) -> None:
75
76
  self.match = self.to_value(skip=skip)
76
77
 
77
- ##################
78
+ ##################
78
79
 
79
- def _query(self, *, table:str, column:str, value:Any, cache:bool, conn:str) -> bool:
80
+ def _query(
81
+ self, *, table: str, column: str, value: Any, cache: bool, conn: str
82
+ ) -> bool:
83
+ engine = None
80
84
  try:
81
85
  engine = Db.get_engine(conn=conn)
82
- return self._do_query(table=table, column=column, value=value, cache=cache, engine=engine)
83
- except Exception as ex:
86
+ return self._do_query(
87
+ table=table, column=column, value=value, cache=cache, engine=engine
88
+ )
89
+ except Exception:
84
90
  print(traceback.format_exc())
85
-
86
- def _do_query(self, *, table:str, column:str, value:Any, cache:bool, engine:Engine) -> bool:
91
+ finally:
92
+ if engine is not None:
93
+ try:
94
+ engine.dispose()
95
+ except Exception:
96
+ ...
97
+
98
+ def _do_query(
99
+ self, *, table: str, column: str, value: Any, cache: bool, engine: Engine
100
+ ) -> bool:
87
101
  if cache is True:
88
102
  if self._cached is None:
89
103
  self._do_cache(value=value, table=table, column=column, engine=engine)
90
104
  return value in self._cached
91
105
  else:
92
- return self._do_lookup(value=value, table=table, column=column, engine=engine)
106
+ return self._do_lookup(
107
+ value=value, table=table, column=column, engine=engine
108
+ )
93
109
 
94
- def _do_cache(self, *, value:Any, table:str, column:str, engine:Engine) -> bool:
110
+ def _do_cache(self, *, value: Any, table: str, column: str, engine: Engine) -> bool:
95
111
  table = sa.table(table, sa.column(column))
96
112
  sql = sa.select(sa.column(column)).select_from(table)
97
113
 
98
-
99
114
  with engine.connect() as conn:
100
115
  rows = conn.execute(sql).fetchall()
101
116
  self._cached = {row[0]: None for row in rows}
102
117
 
103
- def _do_lookup(self, *, value:Any, table:str, column:str, engine:Engine) -> bool:
118
+ def _do_lookup(
119
+ self, *, value: Any, table: str, column: str, engine: Engine
120
+ ) -> bool:
104
121
  table = sa.table(table, sa.column(column))
105
122
  query = (
106
123
  sa.select(sa.column(column))
@@ -111,5 +128,3 @@ class SqlIn(ValueProducer, MatchDecider):
111
128
  with engine.connect() as conn:
112
129
  result = conn.execute(query).fetchone()
113
130
  return result is not None
114
-
115
-
@@ -6,6 +6,9 @@ from .config import Config
6
6
  from .path_util import PathUtility as pathu
7
7
  from .class_loader import ClassLoader
8
8
  from typing import Self
9
+ from csvpath.util.sftp.sftp_config import SftpConfig
10
+ from csvpath.util.sftp.sftp_server_creds import SftpServerCreds
11
+ from csvpath.managers.server_config import ServerConfig
9
12
 
10
13
 
11
14
  class Nos:
@@ -14,6 +17,7 @@ class Nos:
14
17
  self._do = None
15
18
  self._config = config
16
19
  self.path = path
20
+ self._servers = None
17
21
 
18
22
  def __str__(self) -> str:
19
23
  return f"{type(self)}: do: {self.do}, path: {self.path}"
@@ -92,6 +96,8 @@ class Nos:
92
96
 
93
97
  @property
94
98
  def location(self) -> str:
99
+ #
100
+ # pathu.location(path) is now available. prefer that going forward.
95
101
  #
96
102
  # returns None if a local path. there may be some gray areas around mounted drives?
97
103
  # otherwise, returns the first path part after the protocol. port is included, if any.
@@ -106,6 +112,9 @@ class Nos:
106
112
 
107
113
  @property
108
114
  def location_and_port(self) -> tuple[str, int]:
115
+ #
116
+ # pathu.location_and_port(path) is now available. prefer that going forward.
117
+ #
109
118
  location = self.location
110
119
  if location is None:
111
120
  return None
@@ -134,6 +143,82 @@ class Nos:
134
143
  return path[7:]
135
144
  return path
136
145
 
146
+ #
147
+ # SFTP only:
148
+ # server configs are set on named-files and named-paths for non-local file
149
+ # registration and post run transfers, respectively. if we have a matching
150
+ # config, we will use it, not the backend, even if the backend is configured
151
+ # for sftp.
152
+ #
153
+ # ServerConfig connections/clients are not cached/reused like the regular
154
+ # SFTP backend is.
155
+ #
156
+ # also see DataFileReader and DataFileWriter's ServerConfig logic.
157
+ #
158
+ @property
159
+ def server_config(self) -> list[ServerConfig]:
160
+ return self._servers
161
+
162
+ @server_config.setter
163
+ def server_config(self, servers: list[ServerConfig]) -> None:
164
+ #
165
+ # when we set server config on a nos we're enabling the SFTP not only
166
+ # from the cached backend location, but also uncached creds stored in a
167
+ # named-file or named-paths definition json.
168
+ #
169
+ # for an example see: TestUtilNos.test_nos_server_config_1
170
+ # or see FileManager.add_named_file() around like 750:
171
+ #
172
+ # config = self.describer.get_config(name)
173
+ # servers = config.sources
174
+ # nos.server_config = servers
175
+ #
176
+ # if there is a match, that is what is used, if no match, it should
177
+ # fall back to the backend sftp config, if any.
178
+ #
179
+ if servers is None:
180
+ return
181
+ if not self.is_sftp:
182
+ #
183
+ # do we need to worry about people adding server config to non-SFTP
184
+ # Nos? there isn't much practical advantage and we can simplify use
185
+ # just a bit by making a non-sftp a no-op.
186
+ #
187
+ return
188
+ if len(servers) == 0:
189
+ return
190
+ self._servers = servers
191
+ server, port = self.location_and_port
192
+ for k, v in servers.items():
193
+ #
194
+ # there is a lot of use of _ (underscored) methods that are supposed
195
+ # to be hiding below here. that could and probably should change, but
196
+ # simply making the methods not _ would not better guarantee that we
197
+ # be careful with the way Nos, DataFileReader, DataFileWriter and their
198
+ # implementation classes are handled.
199
+ #
200
+ if v.address == server and v.port == port:
201
+ instance = ClassLoader.load(
202
+ "from csvpath.util.sftp.sftp_nos import SftpDo",
203
+ args=[self.path, False],
204
+ )
205
+ self._do = instance
206
+ self._do.server_config = v
207
+ #
208
+ # for getting Sftp server creds we need a csvpath.util.Config.
209
+ # it isn't certain we'll have one ourselves; however, the SftpDo
210
+ # will look for one in Box or create one for us.
211
+ #
212
+ if self._config is None:
213
+ self._config = self._do._csvpath_config()
214
+ c = SftpConfig(self._config)
215
+ c.username, c.password = SftpServerCreds.server_credentials(self)
216
+ c.server = server
217
+ c.port = port
218
+ c._do_load()
219
+ self._do._config = c
220
+ break
221
+
137
222
  @property
138
223
  def do(self):
139
224
  if self.path is not None and self._do is None:
@@ -79,6 +79,9 @@ class PathUtility:
79
79
 
80
80
  @classmethod
81
81
  def stripp(cls, apath: str) -> str:
82
+ #
83
+ # removes protocol + location, incl. port.
84
+ #
82
85
  i = apath.find("://")
83
86
  j = -1
84
87
  if i > -1:
@@ -88,6 +91,38 @@ class PathUtility:
88
91
  apath = apath[j + 1 :]
89
92
  return apath
90
93
 
94
+ @classmethod
95
+ def location(cls, path: str):
96
+ #
97
+ # find the location of a non-local path. i.e. in sftp://mylocation:22/a file.txt
98
+ # the return would be mylocation:22
99
+ #
100
+ i = path.find("://")
101
+ if i == -1:
102
+ return None
103
+ path = path[i + 3 :]
104
+ i = path.find("/")
105
+ if i == -1:
106
+ return path
107
+ return path[0:i]
108
+
109
+ @classmethod
110
+ def location_and_port(cls, path: str) -> tuple[str, int]:
111
+ #
112
+ # find the location of a non-local path. \
113
+ #
114
+ # in sftp://mylocation:22/a file.txt the return would be (mylocation,22)
115
+ # in sftp://mylocation/a file.txt the return would be (mylocation,None)
116
+ #
117
+ location = cls.location(path)
118
+ if location is None:
119
+ return None
120
+ i = location.find(":")
121
+ if i == -1:
122
+ return (location, None)
123
+ port = location[i + 1 :]
124
+ return location[0:i], port
125
+
91
126
  @classmethod
92
127
  def equal(cls, pathone: str, pathtwo: str, stripp=False) -> bool:
93
128
  #