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.
- {csvpath-0.0.587 → csvpath-0.0.589}/PKG-INFO +1 -1
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/function_factory.py +15 -7
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/function_finder.py +33 -13
- csvpath-0.0.589/csvpath/util/class_loader.py +218 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/pyproject.toml +1 -1
- csvpath-0.0.587/csvpath/util/class_loader.py +0 -105
- {csvpath-0.0.587 → csvpath-0.0.589}/LICENSE +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/README.md +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/config.ini +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/extra-functions.imports +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/function.imports +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-local-azure.ini +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-local-filesystem-mysql.ini +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-local-gcs.ini +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-local-s3.ini +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-local-sftp.ini +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-windows-azure.ini +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-windows-gcs.ini +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-windows-local.ini +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-windows-s3.ini +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/config/jenkins-windows-sftp.ini +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/azure-pipeline.gopipeline.json +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/azure.sh +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/gcs-pipeline.gopipeline.json +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/gcs.sh +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/local-pipeline.gopipeline copy.json +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/local.sh +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/s3-pipeline.gopipeline.json +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/s3.sh +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/sftp-pipeline.gopipeline.json +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/mac/sftp.sh +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/azure.bat +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/gcs.bat +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/local.bat +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/s3.bat +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/sftp.bat +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/windows-azure.gopipeline.json +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/windows-gcs.gopipeline.json +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/windows-local.gopipeline.json +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/windows-s3.gopipeline.json +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/gocd/windows/windows-sftp.gopipeline.json +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sftpplus/handle_auto_arrival.bat +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sftpplus/handle_auto_arrival.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sftpplus/handle_auto_arrival.sh +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sftpplus/handle_mailbox_arrival.bat +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sftpplus/handle_mailbox_arrival.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sftpplus/handle_mailbox_arrival.sh +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sqlite/csvpath +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/assets/integrations/sqlite/schema.sql +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/config/config.ini +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/config/env.json +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/__init__.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/__init__.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/asker.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/cli.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/const.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/debug_config.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/drill_down.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/function_describer.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/function_lister.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/cli/selecter.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/csvpath.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/csvpaths.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/__init__.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/errors/error.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/errors/error_collector.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/errors/error_comms.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/errors/error_manager.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/files/file_manager.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/files/file_metadata.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/files/file_registrar.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/files/files_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/files/lines_and_headers_cacher.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ckan/ckan.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ckan/ckan_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ckan/datafile.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ckan/dataset.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/event.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/event_result.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/file_listener_ol.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/job.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/ol_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/paths_listener_ol.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/result_listener_ol.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/results_listener_ol.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/run.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/run_listener_ol.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/run_state.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/ol/sender.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/error_metrics.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/metrics.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/otlp_error_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/otlp_file_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/otlp_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/otlp_paths_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/otlp_result_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/otlp/otlp_results_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/scripts/scripts_results_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sftp/sftp_sender.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sftpplus/arrival_handler.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sftpplus/rpc.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sftpplus/sftpplus_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sftpplus/transfer_creator.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sftpplus/transfers.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/slack/event.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/slack/sender.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/engine.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/sql_file_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/sql_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/sql_paths_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/sql_result_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/sql_results_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/tables.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sql/updates.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sqlite/schema.sql +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sqlite/sqlite_result_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/sqlite/sqlite_results_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/webhook/webhook_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/integrations/webhook/webhook_results_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/metadata.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/paths/paths_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/paths/paths_manager.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/paths/paths_metadata.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/paths/paths_registrar.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/registrar.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/readers/file_errors_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/readers/file_lines_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/readers/file_printouts_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/readers/file_unmatched_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/readers/readers.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/result.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/result_file_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/result_metadata.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/result_registrar.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/result_serializer.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/results_manager.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/results_metadata.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/results/results_registrar.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/run/run_listener_stdout.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/run/run_metadata.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/run/run_registrar.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/managers/test_listener.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/__init__.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/__init__.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/args.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/args_helper.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/all.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/andf.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/any.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/between.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/empty.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/exists.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/inf.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/no.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/notf.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/orf.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/boolean/yes.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/count.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/count_bytes.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/count_headers.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/count_lines.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/count_scans.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/counter.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/every.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/has_matches.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/increment.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/tally.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/counting/total_lines.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/dates/now.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/dates/part.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/dates/roll.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/function.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/function_focus.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/append.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/collect.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/empty_stack.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/end.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/header_name.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/headers.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/headers_stack.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/insert.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/line_before.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/mismatch.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/remove.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/rename.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/replace.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/headers/reset_headers.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/json/jsonpath.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/advance.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/after_blank.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/dups.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/first.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/first_line.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/last.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/lines/stop.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/above.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/add.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/divide.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/equals.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/intf.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/mod.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/multiply.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/odd.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/round.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/subtotal.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/subtract.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/math/sum.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/misc/fingerprint.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/misc/importf.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/misc/random.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/print/jinjaf.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/print/print_line.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/print/print_queue.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/print/printf.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/print/table.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/stats/minf.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/stats/nminmax.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/stats/percent.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/stats/percent_unique.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/stats/stdev.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/alter.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/caps.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/concat.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/contains.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/format.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/length.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/lower.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/metaphone.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/regex.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/starts_with.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/strip.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/substring.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/strings/upper.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/testing/debug.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/__init__.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/blank.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/boolean.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/datatype.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/datef.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/decimal.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/email.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/nonef.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/string.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/type.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/url.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/types/wildcard.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/validity/fail.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/validity/failed.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/validity/line.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/clear.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/get.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/index_of.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/pushpop.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/put.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/track.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/variables/variables.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/functions/xml/xpath.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/lark_parser.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/lark_transformer.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/matcher.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/__init__.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/equality.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/expression.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/header.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/matchable.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/qualified.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/reference.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/term.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/productions/variable.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/util/exceptions.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/util/expression_encoder.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/util/expression_utility.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/util/lark_print_parser.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/util/print_parser.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/matching/util/runtime_data_collector.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/error_mode.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/explain_mode.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/files_mode.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/logic_mode.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/mode_controller.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/print_mode.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/return_mode.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/run_mode.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/source_mode.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/transfer_mode.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/unmatched_mode.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/modes/validation_mode.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/scanning/__init__.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/scanning/scanner2.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/scanning/scanner2_parser.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/scanning/scanner2_transformer.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_data_writer.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_fingerprinter.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_json_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_nos.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_utils.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/azure/azure_xlsx_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/backend_check.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/box.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/cache.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/caser.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/code.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/config.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/config_env.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/config_exception.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/date_util.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/exceptions.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/file_info.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/file_readers.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/file_writers.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_data_writer.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_fingerprinter.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_json_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_nos.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_utils.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/gcs/gcs_xlsx_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/hasher.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/http/http_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/intermediary.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/json/json_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/json/json_reader_helper.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/last_line_stats.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/line_counter.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/line_monitor.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/line_spooler.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/log_utility.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/metadata_parser.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/nos.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/pandas_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/path_util.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/printer.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/py_file_utility.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/files_reference_finder_2.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/files_tools/fingerprint_finder.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/files_tools/range_finder.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/ref_utils.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/reference_exceptions.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/reference_grammar.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/reference_manifest_entry_finder.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/reference_parser.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/reference_results.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/reference_transformer.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_reference_finder_2.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/data_finder.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/date_filter.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/identity_finder.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/path_filter.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/resolve_possibles.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/token_filters.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/results_tools/yesterday_or_today_translator.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/references/tools/date_completer.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/run_home_maker.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_data_writer.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_fingerprinter.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_json_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_nos.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_utils.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/s3/s3_xlsx_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_config.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_data_writer.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_fingerprinter.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_json_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_nos.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_walk.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sftp/sftp_xlsx_data_reader.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/sqliter.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/template_util.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/var_utility.py +0 -0
- {csvpath-0.0.587 → csvpath-0.0.589}/csvpath/util/xlsx/xlsx_data_reader.py +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
312
|
+
cls._debug_two(matcher, "Found %s as %s", qname, f)
|
|
305
313
|
if f is None:
|
|
306
|
-
cls.
|
|
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.
|
|
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.
|
|
43
|
-
|
|
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.
|
|
55
|
+
cls._debug_one(matcher, "Added sentinel function %s", e)
|
|
51
56
|
|
|
52
57
|
@classmethod
|
|
53
|
-
def
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"Adding custom function %s: %s", qname, instance
|
|
101
|
-
|
|
102
|
-
|
|
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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|