csvpath 0.0.494__tar.gz → 0.0.495__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.494 → csvpath-0.0.495}/PKG-INFO +1 -1
- {csvpath-0.0.494 → csvpath-0.0.495}/config/config.ini +5 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/csvpath.py +124 -11
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/csvpaths.py +126 -24
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/managers/file_manager.py +13 -1
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/managers/file_registrar.py +1 -1
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/managers/line_spooler.py +8 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/managers/paths_registrar.py +1 -1
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/managers/result.py +28 -8
- csvpath-0.0.495/csvpath/managers/result_registrar.py +129 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/managers/result_serializer.py +27 -9
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/managers/results_manager.py +80 -3
- csvpath-0.0.495/csvpath/managers/results_registrar.py +69 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/strings/regex.py +4 -4
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/util/runtime_data_collector.py +58 -2
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/config.py +31 -0
- csvpath-0.0.495/csvpath/util/csvpaths_registrar.py +99 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/pyproject.toml +1 -1
- {csvpath-0.0.494 → csvpath-0.0.495}/LICENSE +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/README.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/__init__.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/cli/__init__.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/cli/cli.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/cli/drill_down.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/managers/__init__.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/managers/paths_manager.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/__init__.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/__init__.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/args.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/boolean/all.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/boolean/andf.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/boolean/any.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/boolean/between.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/boolean/empty.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/boolean/exists.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/boolean/inf.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/boolean/no.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/boolean/notf.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/boolean/orf.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/boolean/yes.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/counting/count.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/counting/count_bytes.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/counting/count_headers.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/counting/count_lines.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/counting/count_scans.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/counting/counter.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/counting/every.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/counting/has_matches.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/counting/increment.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/counting/tally.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/counting/total_lines.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/dates/now.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/function.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/function_factory.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/function_finder.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/function_focus.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/headers/append.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/headers/collect.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/headers/empty_stack.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/headers/end.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/headers/header_name.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/headers/headers.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/headers/mismatch.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/headers/replace.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/headers/reset_headers.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/lines/advance.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/lines/after_blank.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/lines/dups.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/lines/first.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/lines/first_line.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/lines/last.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/lines/stop.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/math/above.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/math/add.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/math/divide.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/math/equals.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/math/intf.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/math/mod.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/math/multiply.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/math/round.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/math/subtotal.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/math/subtract.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/math/sum.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/misc/fingerprint.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/misc/importf.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/misc/random.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/print/jinjaf.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/print/print_line.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/print/print_queue.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/print/printf.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/print/table.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/stats/minf.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/stats/percent.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/stats/percent_unique.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/stats/stdev.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/strings/concat.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/strings/length.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/strings/lower.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/strings/metaphone.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/strings/starts_with.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/strings/strip.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/strings/substring.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/strings/upper.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/testing/debug.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/types/__init__.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/types/boolean.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/types/datef.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/types/decimal.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/types/nonef.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/types/string.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/types/type.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/validity/fail.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/validity/failed.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/validity/line.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/variables/get.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/variables/pushpop.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/variables/put.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/variables/track.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/functions/variables/variables.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/lark_parser.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/lark_transformer.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/matcher.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/productions/__init__.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/productions/equality.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/productions/expression.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/productions/header.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/productions/matchable.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/productions/qualified.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/productions/reference.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/productions/term.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/productions/variable.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/util/exceptions.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/util/expression_encoder.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/util/expression_utility.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/util/lark_print_parser.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/matching/util/print_parser.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/scanning/__init__.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/scanning/exceptions.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/scanning/parser.out +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/scanning/parsetab.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/scanning/scanner.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/scanning/scanning_lexer.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/cache.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/config_exception.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/error.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/exceptions.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/file_readers.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/last_line_stats.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/line_counter.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/line_monitor.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/log_utility.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/metadata_parser.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/pandas_data_reader.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/printer.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/reference_parser.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/csvpath/util/s3_data_reader.py +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/asbool.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/assignment.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/comments.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/config.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/examples.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/files.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/above.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/advance.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/after_blank.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/all.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/andor.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/any.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/average.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/between.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/collect.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/correlate.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/count.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/count_bytes.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/count_headers.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/counter.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/date.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/empty.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/empty_stack.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/end.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/every.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/fail.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/fingerprint.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/first.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/get.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/has_dups.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/has_matches.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/header.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/header_name.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/header_names_mismatch.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/implementing_functions.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/import.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/in.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/increment.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/intf.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/jinja.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/last.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/line.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/line_number.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/max.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/metaphone.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/mismatch.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/no.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/not.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/now.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/percent_unique.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/pop.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/print.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/print_line.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/print_queue.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/random.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/regex.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/replace.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/reset_headers.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/stdev.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/stop.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/string_functions.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/subtotal.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/subtract.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/sum.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/tally.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/total_lines.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/track.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/types.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/variables.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions/variables_and_headers.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/functions.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/grammar.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/headers.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/images/logo-wordmark-white-on-black-trimmed-padded.png +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/images/logo-wordmark-white-trimmed.png +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/paths.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/printing.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/qualifiers.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/references.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/terms.md +0 -0
- {csvpath-0.0.494 → csvpath-0.0.495}/docs/variables.md +0 -0
|
@@ -233,6 +233,14 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
|
|
|
233
233
|
self._errors: List[Error] = None
|
|
234
234
|
self._error_collector = None
|
|
235
235
|
#
|
|
236
|
+
# transfers from transfer-mode: ((data | unmatched):var-name)(,*)
|
|
237
|
+
# this setting tells CsvPaths to copy resulting data.csv and/or
|
|
238
|
+
# unmatched.csv to one or more target locations below the config.ini's
|
|
239
|
+
# transfer directory. the name "data" or "unmatched" is paired with
|
|
240
|
+
# a var name that indicates the path to write the indicated file.
|
|
241
|
+
#
|
|
242
|
+
self._transfers = None
|
|
243
|
+
#
|
|
236
244
|
# saves the scan and match parts of paths for reference. mainly helpful
|
|
237
245
|
# for testing the CsvPath library itself; not used end users. the run
|
|
238
246
|
# name becomes the file name of the saved path parts.
|
|
@@ -308,7 +316,7 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
|
|
|
308
316
|
self._function_times_value = {}
|
|
309
317
|
self._created_at = datetime.now()
|
|
310
318
|
self._run_started_at = None
|
|
311
|
-
|
|
319
|
+
self._all_expected_files = []
|
|
312
320
|
self._collecting = False
|
|
313
321
|
self._unmatched = None
|
|
314
322
|
self._unmatched_available = False
|
|
@@ -364,11 +372,11 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
|
|
|
364
372
|
return self._run_started_at
|
|
365
373
|
|
|
366
374
|
@property
|
|
367
|
-
def
|
|
375
|
+
def will_run(self) -> bool:
|
|
368
376
|
return self._run_mode
|
|
369
377
|
|
|
370
|
-
@
|
|
371
|
-
def
|
|
378
|
+
@will_run.setter
|
|
379
|
+
def will_run(self, mode) -> None:
|
|
372
380
|
self._run_mode = mode
|
|
373
381
|
|
|
374
382
|
def _up_function_time_match(self, c, t) -> None:
|
|
@@ -449,6 +457,7 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
|
|
|
449
457
|
is preferred over name. E.g.:
|
|
450
458
|
~ name: my path description: an example ~
|
|
451
459
|
"""
|
|
460
|
+
# this ordering is relied on in Result and possibly elsewhere
|
|
452
461
|
if not self.metadata:
|
|
453
462
|
return ""
|
|
454
463
|
if "id" in self.metadata:
|
|
@@ -471,7 +480,7 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
|
|
|
471
480
|
self._config = Config()
|
|
472
481
|
return self._config
|
|
473
482
|
|
|
474
|
-
def has_errors(self) -> bool:
|
|
483
|
+
def has_errors(self) -> bool:
|
|
475
484
|
if self.errors and len(self.errors) > 0:
|
|
476
485
|
return True
|
|
477
486
|
if self.error_collector:
|
|
@@ -720,6 +729,7 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
|
|
|
720
729
|
# - run-mode: no-run | run
|
|
721
730
|
# - unmatched-mode: no-keep | keep
|
|
722
731
|
# - source-mode: preceding | origin
|
|
732
|
+
# - files-mode: all | no-data | no-unmatched | no-printouts | data | unmatched | errors | meta | vars | printouts
|
|
723
733
|
#
|
|
724
734
|
self.update_logic_mode_if()
|
|
725
735
|
self.update_run_mode_if()
|
|
@@ -729,6 +739,87 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
|
|
|
729
739
|
self.update_arg_validation_mode_if()
|
|
730
740
|
self.update_unmatched_mode_if()
|
|
731
741
|
self.update_data_from_preceding_if()
|
|
742
|
+
self.update_expected_files_if()
|
|
743
|
+
self.update_transfer_mode_if()
|
|
744
|
+
|
|
745
|
+
# =====================
|
|
746
|
+
|
|
747
|
+
@property
|
|
748
|
+
def transfer_mode(self) -> str:
|
|
749
|
+
return self.metadata.get("transfer-mode")
|
|
750
|
+
|
|
751
|
+
@property
|
|
752
|
+
def source_mode(self) -> str:
|
|
753
|
+
return self.metadata.get("source-mode")
|
|
754
|
+
|
|
755
|
+
@property
|
|
756
|
+
def files_mode(self) -> str:
|
|
757
|
+
return self.metadata.get("files-mode")
|
|
758
|
+
|
|
759
|
+
@property
|
|
760
|
+
def validation_mode(self) -> str:
|
|
761
|
+
return self.metadata.get("validation-mode")
|
|
762
|
+
|
|
763
|
+
@property
|
|
764
|
+
def run_mode(self) -> str:
|
|
765
|
+
return self.metadata.get("run-mode")
|
|
766
|
+
|
|
767
|
+
@property
|
|
768
|
+
def logic_mode(self) -> str:
|
|
769
|
+
return "AND" if self.AND else "OR"
|
|
770
|
+
|
|
771
|
+
@property
|
|
772
|
+
def return_mode(self) -> str:
|
|
773
|
+
return self.metadata.get("return-mode")
|
|
774
|
+
|
|
775
|
+
@property
|
|
776
|
+
def explain_mode(self) -> str:
|
|
777
|
+
return self.metadata.get("explain-mode")
|
|
778
|
+
|
|
779
|
+
@property
|
|
780
|
+
def print_mode(self) -> str:
|
|
781
|
+
return self.metadata.get("print-mode")
|
|
782
|
+
|
|
783
|
+
@property
|
|
784
|
+
def unmatched_mode(self) -> str:
|
|
785
|
+
return self.metadata.get("unmatched-mode")
|
|
786
|
+
|
|
787
|
+
# =====================
|
|
788
|
+
|
|
789
|
+
@property
|
|
790
|
+
def transfers(self) -> list[tuple[str, str]]:
|
|
791
|
+
return self._transfers
|
|
792
|
+
|
|
793
|
+
def update_transfer_mode_if(self) -> None:
|
|
794
|
+
m = self.transfer_mode
|
|
795
|
+
if m is not None:
|
|
796
|
+
self._transfers = []
|
|
797
|
+
for t in m.split(","):
|
|
798
|
+
i = t.find(">")
|
|
799
|
+
if i == -1:
|
|
800
|
+
raise InputException(
|
|
801
|
+
"Transfer mode directive must be in the form file > location"
|
|
802
|
+
)
|
|
803
|
+
file = t[0:i].strip()
|
|
804
|
+
location = t[i + 1 :].strip()
|
|
805
|
+
self._transfers.append((file, location))
|
|
806
|
+
|
|
807
|
+
def update_expected_files_if(self) -> None:
|
|
808
|
+
fm = self.files_mode
|
|
809
|
+
if fm is None:
|
|
810
|
+
return []
|
|
811
|
+
fs = [s for s in fm.split(",")]
|
|
812
|
+
_ = []
|
|
813
|
+
for s in fs:
|
|
814
|
+
s = s.strip()
|
|
815
|
+
if s not in ["data", "unmatched", "vars", "errors", "meta", "printouts"]:
|
|
816
|
+
self.logger.warning(
|
|
817
|
+
"Unknown file-mode token %s. Mode tokens may be separated by , and will be trimmed.",
|
|
818
|
+
s,
|
|
819
|
+
)
|
|
820
|
+
continue
|
|
821
|
+
_.append(s)
|
|
822
|
+
self.all_expected_files = _
|
|
732
823
|
|
|
733
824
|
def update_data_from_preceding_if(self) -> None:
|
|
734
825
|
if self.metadata and "source-mode" in self.metadata:
|
|
@@ -758,9 +849,9 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
|
|
|
758
849
|
def update_run_mode_if(self) -> None:
|
|
759
850
|
if self.metadata and "run-mode" in self.metadata:
|
|
760
851
|
if f"{self.metadata['run-mode']}".strip() == "no-run":
|
|
761
|
-
self.
|
|
852
|
+
self.will_run = False
|
|
762
853
|
elif f"{self.metadata['run-mode']}".strip() == "run":
|
|
763
|
-
self.
|
|
854
|
+
self.will_run = True
|
|
764
855
|
else:
|
|
765
856
|
self.logger.warning(
|
|
766
857
|
"Incorrect metadata field value 'run-mode': %s",
|
|
@@ -824,6 +915,14 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
|
|
|
824
915
|
self.metadata["print-mode"],
|
|
825
916
|
)
|
|
826
917
|
|
|
918
|
+
@property
|
|
919
|
+
def all_expected_files(self) -> list[str]:
|
|
920
|
+
return self._all_expected_files
|
|
921
|
+
|
|
922
|
+
@all_expected_files.setter
|
|
923
|
+
def all_expected_files(self, efs: list[str]) -> None:
|
|
924
|
+
self._all_expected_files = efs
|
|
925
|
+
|
|
827
926
|
def _pick_named_path(self, name, *, specific=None) -> str:
|
|
828
927
|
if not self.csvpaths:
|
|
829
928
|
raise CsvPathsException("No CsvPaths object available")
|
|
@@ -972,6 +1071,14 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
|
|
|
972
1071
|
def is_valid(self, tf: bool) -> None:
|
|
973
1072
|
self._is_valid = tf
|
|
974
1073
|
|
|
1074
|
+
@property
|
|
1075
|
+
def completed(self) -> bool:
|
|
1076
|
+
if not self.scanner or not self.line_monitor:
|
|
1077
|
+
return False
|
|
1078
|
+
if self.scanner.is_last(self.line_monitor.physical_line_number):
|
|
1079
|
+
return True
|
|
1080
|
+
return False
|
|
1081
|
+
|
|
975
1082
|
@property
|
|
976
1083
|
def from_line(self): # pragma: no cover pylint: disable=C0116
|
|
977
1084
|
if self.scanner is None:
|
|
@@ -1066,12 +1173,18 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
|
|
|
1066
1173
|
nexts -= 1
|
|
1067
1174
|
else:
|
|
1068
1175
|
break
|
|
1069
|
-
# we don't want to hold on to
|
|
1070
|
-
# we do want to return
|
|
1176
|
+
# we don't want to hold on to data more than needed. but
|
|
1177
|
+
# we do want to return data if we're not spooling. the
|
|
1071
1178
|
# way we do that is to keep the local var available with the
|
|
1072
1179
|
# list and/or the spooler. the caller needs to be aware of
|
|
1073
1180
|
# both possibilities, but both offer __len__ and append.
|
|
1074
|
-
|
|
1181
|
+
#
|
|
1182
|
+
# we keep the self.lines if it is not a list because that
|
|
1183
|
+
# makes it available to the runtime data collector so we can
|
|
1184
|
+
# see the line count in the metadata, saving opening a
|
|
1185
|
+
# potentially large data.csv to find out how many lines.
|
|
1186
|
+
if isinstance(self.lines, list):
|
|
1187
|
+
self.lines = None
|
|
1075
1188
|
return lines
|
|
1076
1189
|
|
|
1077
1190
|
def fast_forward(self, csvpath=None) -> None:
|
|
@@ -1090,7 +1203,7 @@ class CsvPath(CsvPathPublic, ErrorCollector, Printer): # pylint: disable=R0902,
|
|
|
1090
1203
|
if self.scanner is None and csvpath is not None:
|
|
1091
1204
|
self.parse(csvpath)
|
|
1092
1205
|
start = time.time()
|
|
1093
|
-
if self.
|
|
1206
|
+
if self.will_run is True:
|
|
1094
1207
|
for line in self._next_line():
|
|
1095
1208
|
b = self._consider_line(line)
|
|
1096
1209
|
if b:
|
|
@@ -10,10 +10,12 @@ from .util.error import ErrorHandler, ErrorCollector, Error
|
|
|
10
10
|
from .util.config import Config
|
|
11
11
|
from .util.log_utility import LogUtility
|
|
12
12
|
from .util.metadata_parser import MetadataParser
|
|
13
|
-
from .util.exceptions import InputException
|
|
13
|
+
from .util.exceptions import InputException, CsvPathsException
|
|
14
|
+
from .util.csvpaths_registrar import CsvPathsRegistrar, CsvPathsFilesystemRegistrar
|
|
14
15
|
from .managers.paths_manager import PathsManager
|
|
15
16
|
from .managers.file_manager import FileManager
|
|
16
17
|
from .managers.results_manager import ResultsManager
|
|
18
|
+
from .managers.results_registrar import ResultsRegistrar
|
|
17
19
|
from .managers.result import Result
|
|
18
20
|
from . import CsvPath
|
|
19
21
|
|
|
@@ -148,6 +150,20 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
148
150
|
self._skip_all = False
|
|
149
151
|
self._advance_all = 0
|
|
150
152
|
self._current_run_time = None
|
|
153
|
+
self._csvpaths_registrars = []
|
|
154
|
+
self._csvpaths_registrars.append(CsvPathsFilesystemRegistrar(self))
|
|
155
|
+
self._run_time_str = None
|
|
156
|
+
|
|
157
|
+
def run_time_str(self, pathsname=None) -> str:
|
|
158
|
+
if self._run_time_str is None and pathsname is None:
|
|
159
|
+
raise CsvPathsException(
|
|
160
|
+
"Cannot have None in both run_time_str and pathsname"
|
|
161
|
+
)
|
|
162
|
+
if self._run_time_str is None:
|
|
163
|
+
self._run_time_str = self.results_manager.get_run_time_str(
|
|
164
|
+
pathsname, self.current_run_time
|
|
165
|
+
)
|
|
166
|
+
return self._run_time_str
|
|
151
167
|
|
|
152
168
|
@property
|
|
153
169
|
def current_run_time(self) -> datetime:
|
|
@@ -193,6 +209,15 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
193
209
|
def advance_all(self, lines: int) -> None: # pragma: no cover
|
|
194
210
|
self._advance_all = lines
|
|
195
211
|
|
|
212
|
+
@property
|
|
213
|
+
def csvpaths_registrars(self) -> list[CsvPathsRegistrar]:
|
|
214
|
+
if self._csvpaths_registrars is None:
|
|
215
|
+
self._csvpaths_registrars = []
|
|
216
|
+
return self._csvpaths_registrars
|
|
217
|
+
|
|
218
|
+
def add_csvpaths_registrar(self, creg) -> None:
|
|
219
|
+
self.csvpaths_registrars.append(creg)
|
|
220
|
+
|
|
196
221
|
@property
|
|
197
222
|
def errors(self) -> List[Error]: # pylint: disable=C0116
|
|
198
223
|
return self._errors
|
|
@@ -216,13 +241,18 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
216
241
|
|
|
217
242
|
def collect_paths(self, *, pathsname, filename) -> None:
|
|
218
243
|
paths = self.paths_manager.get_named_paths(pathsname)
|
|
244
|
+
if paths is None:
|
|
245
|
+
raise InputException(f"No named-paths found for {pathsname}")
|
|
219
246
|
file = self.file_manager.get_named_file(filename)
|
|
247
|
+
if file is None:
|
|
248
|
+
raise InputException(f"No named-file found for {filename}")
|
|
220
249
|
self.logger.info("Prepping %s and %s", filename, pathsname)
|
|
221
250
|
self.clean(paths=pathsname)
|
|
222
251
|
self.logger.info(
|
|
223
252
|
"Beginning collect_paths %s with %s paths", pathsname, len(paths)
|
|
224
253
|
)
|
|
225
|
-
crt = self.
|
|
254
|
+
crt = self.run_time_str(pathsname)
|
|
255
|
+
results = []
|
|
226
256
|
for i, path in enumerate(paths):
|
|
227
257
|
csvpath = self.csvpath()
|
|
228
258
|
result = Result(
|
|
@@ -237,29 +267,25 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
237
267
|
# want to never fail during a run
|
|
238
268
|
try:
|
|
239
269
|
self.results_manager.add_named_result(result)
|
|
240
|
-
self._load_csvpath(
|
|
270
|
+
self._load_csvpath(
|
|
271
|
+
csvpath=csvpath,
|
|
272
|
+
path=path,
|
|
273
|
+
file=file,
|
|
274
|
+
pathsname=pathsname,
|
|
275
|
+
filename=filename,
|
|
276
|
+
)
|
|
241
277
|
lines = result.lines
|
|
278
|
+
self.logger.debug("Collecting lines using a %s", type(lines))
|
|
242
279
|
csvpath.collect(lines=lines)
|
|
243
|
-
# lines = csvpath.collect()
|
|
244
280
|
if lines is None:
|
|
245
281
|
self.logger.error( # pragma: no cover
|
|
246
282
|
"Unexpected None for lines after collect_paths: file: %s, match: %s",
|
|
247
283
|
file,
|
|
248
284
|
csvpath.match,
|
|
249
285
|
)
|
|
250
|
-
"""
|
|
251
286
|
#
|
|
252
|
-
# this
|
|
253
|
-
# to not be helpful at all.
|
|
287
|
+
# this is obviously not a good idea for very large files!
|
|
254
288
|
#
|
|
255
|
-
if len(lines) == 0:
|
|
256
|
-
self.logger.warning( # pragma: no cover
|
|
257
|
-
"No lines collected in collect_paths: file: %s match: %s",
|
|
258
|
-
file,
|
|
259
|
-
csvpath.match,
|
|
260
|
-
)
|
|
261
|
-
"""
|
|
262
|
-
# result.lines = lines
|
|
263
289
|
result.unmatched = csvpath.unmatched
|
|
264
290
|
except Exception as ex: # pylint: disable=W0718
|
|
265
291
|
ex.trace = traceback.format_exc()
|
|
@@ -272,18 +298,32 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
272
298
|
self.results_manager.save(result)
|
|
273
299
|
raise e
|
|
274
300
|
self.results_manager.save(result)
|
|
301
|
+
results.append(result)
|
|
302
|
+
rr = ResultsRegistrar(
|
|
303
|
+
csvpaths=self, run_dir=crt, pathsname=pathsname, results=results
|
|
304
|
+
)
|
|
305
|
+
rr.write_manifest()
|
|
306
|
+
#
|
|
307
|
+
# update/write run manifests here
|
|
308
|
+
# - validity (are all paths valid)
|
|
309
|
+
# - paths-completeness (did they all run and complete)
|
|
310
|
+
# - method (collect, fast_forward, next)
|
|
311
|
+
# - timestamp
|
|
312
|
+
#
|
|
275
313
|
self.clear_run_coordination()
|
|
276
314
|
self.logger.info(
|
|
277
315
|
"Completed collect_paths %s with %s paths", pathsname, len(paths)
|
|
278
316
|
)
|
|
279
317
|
|
|
280
318
|
def _load_csvpath(
|
|
281
|
-
self, csvpath: CsvPath, path: str, file: str, pathsname: str = None
|
|
319
|
+
self, *, csvpath: CsvPath, path: str, file: str, pathsname: str = None, filename
|
|
282
320
|
) -> None:
|
|
321
|
+
# file is the physical file (+/- if preceding mode) filename is the named-file name
|
|
283
322
|
self.logger.debug("Beginning to load csvpath %s with file %s", path, file)
|
|
284
323
|
# we strip comments from above the path so we need to extract them first
|
|
285
324
|
path = MetadataParser(self).extract_metadata(instance=csvpath, csvpath=path)
|
|
286
|
-
|
|
325
|
+
identity = csvpath.identity
|
|
326
|
+
self.logger.debug("Csvpath %s after metadata extract: %s", identity, path)
|
|
287
327
|
# update the settings using the metadata fields we just collected
|
|
288
328
|
csvpath.update_settings_from_metadata()
|
|
289
329
|
#
|
|
@@ -316,6 +356,20 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
316
356
|
apath = f"${file}{path[f:]}"
|
|
317
357
|
self.logger.info("Parsing csvpath %s", apath)
|
|
318
358
|
csvpath.parse(apath)
|
|
359
|
+
#
|
|
360
|
+
# ready to run. time to register the run.
|
|
361
|
+
#
|
|
362
|
+
crt = self.run_time_str(pathsname)
|
|
363
|
+
fingerprint = self.file_manager.get_fingerprint_for_name(filename)
|
|
364
|
+
for _ in self.csvpaths_registrars:
|
|
365
|
+
_.update_manifest(
|
|
366
|
+
csvpath=csvpath,
|
|
367
|
+
filepath=file,
|
|
368
|
+
instancepath=crt,
|
|
369
|
+
fingerprint=fingerprint,
|
|
370
|
+
identity=identity,
|
|
371
|
+
)
|
|
372
|
+
self.logger.debug("Done loading csvpath")
|
|
319
373
|
|
|
320
374
|
def fast_forward_paths(self, *, pathsname, filename):
|
|
321
375
|
paths = self.paths_manager.get_named_paths(pathsname)
|
|
@@ -328,7 +382,8 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
328
382
|
len(paths),
|
|
329
383
|
filename,
|
|
330
384
|
)
|
|
331
|
-
crt = self.
|
|
385
|
+
crt = self.run_time_str(pathsname)
|
|
386
|
+
results = []
|
|
332
387
|
for i, path in enumerate(paths):
|
|
333
388
|
csvpath = self.csvpath()
|
|
334
389
|
self.logger.debug("Beginning to FF CsvPath instance: %s", csvpath)
|
|
@@ -342,7 +397,13 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
342
397
|
)
|
|
343
398
|
try:
|
|
344
399
|
self.results_manager.add_named_result(result)
|
|
345
|
-
self._load_csvpath(
|
|
400
|
+
self._load_csvpath(
|
|
401
|
+
csvpath=csvpath,
|
|
402
|
+
path=path,
|
|
403
|
+
file=file,
|
|
404
|
+
pathsname=pathsname,
|
|
405
|
+
filename=filename,
|
|
406
|
+
)
|
|
346
407
|
self.logger.info(
|
|
347
408
|
"Parsed csvpath %s pointed at %s and starting to fast-forward",
|
|
348
409
|
i,
|
|
@@ -363,6 +424,11 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
363
424
|
self.results_manager.save(result)
|
|
364
425
|
raise e
|
|
365
426
|
self.results_manager.save(result)
|
|
427
|
+
results.append(result)
|
|
428
|
+
rr = ResultsRegistrar(
|
|
429
|
+
csvpaths=self, run_dir=crt, pathsname=pathsname, results=results
|
|
430
|
+
)
|
|
431
|
+
rr.write_manifest()
|
|
366
432
|
self.clear_run_coordination()
|
|
367
433
|
self.logger.info(
|
|
368
434
|
"Completed fast_forward_paths %s with %s paths", pathsname, len(paths)
|
|
@@ -377,7 +443,8 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
377
443
|
self.logger.info("Prepping %s and %s", filename, pathsname)
|
|
378
444
|
self.clean(paths=pathsname)
|
|
379
445
|
self.logger.info("Beginning next_paths with %s paths", len(paths))
|
|
380
|
-
crt = self.
|
|
446
|
+
crt = self.run_time_str(pathsname)
|
|
447
|
+
results = []
|
|
381
448
|
for i, path in enumerate(paths):
|
|
382
449
|
if self._skip_all:
|
|
383
450
|
skip_err = "Found the skip-all signal set. skip_all() is"
|
|
@@ -412,7 +479,13 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
412
479
|
csvpath.is_valid = False
|
|
413
480
|
try:
|
|
414
481
|
self.results_manager.add_named_result(result)
|
|
415
|
-
self._load_csvpath(
|
|
482
|
+
self._load_csvpath(
|
|
483
|
+
csvpath=csvpath,
|
|
484
|
+
path=path,
|
|
485
|
+
file=file,
|
|
486
|
+
pathsname=pathsname,
|
|
487
|
+
filename=filename,
|
|
488
|
+
)
|
|
416
489
|
for line in csvpath.next():
|
|
417
490
|
line.append(result)
|
|
418
491
|
if collect:
|
|
@@ -430,6 +503,11 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
430
503
|
self.results_manager.save(result)
|
|
431
504
|
raise e
|
|
432
505
|
self.results_manager.save(result)
|
|
506
|
+
results.append(result)
|
|
507
|
+
rr = ResultsRegistrar(
|
|
508
|
+
csvpaths=self, run_dir=crt, pathsname=pathsname, results=results
|
|
509
|
+
)
|
|
510
|
+
rr.write_manifest()
|
|
433
511
|
self.clear_run_coordination()
|
|
434
512
|
|
|
435
513
|
# =============== breadth first processing ================
|
|
@@ -505,10 +583,13 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
505
583
|
raise InputException(
|
|
506
584
|
f"Pathsname '{pathsname}' must name a list of csvpaths"
|
|
507
585
|
)
|
|
586
|
+
|
|
508
587
|
csvpath_objects = self._load_csvpath_objects(
|
|
509
588
|
paths=paths,
|
|
510
589
|
named_file=fn,
|
|
511
590
|
collect_when_not_matched=collect_when_not_matched,
|
|
591
|
+
filename=filename,
|
|
592
|
+
pathsname=pathsname,
|
|
512
593
|
)
|
|
513
594
|
self._prep_csvpath_results(
|
|
514
595
|
csvpath_objects=csvpath_objects, filename=filename, pathsname=pathsname
|
|
@@ -639,21 +720,42 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
639
720
|
yield line
|
|
640
721
|
if sum(stopped_count) == len(csvpath_objects):
|
|
641
722
|
break
|
|
723
|
+
results = []
|
|
642
724
|
for r in csvpath_objects:
|
|
643
725
|
result = r[1]
|
|
726
|
+
results.append(result)
|
|
644
727
|
result.unmatched = r[0].unmatched
|
|
645
728
|
self.results_manager.save(result)
|
|
729
|
+
rr = ResultsRegistrar(
|
|
730
|
+
csvpaths=self,
|
|
731
|
+
run_dir=results[0].run_dir,
|
|
732
|
+
pathsname=pathsname,
|
|
733
|
+
results=results,
|
|
734
|
+
)
|
|
735
|
+
rr.write_manifest()
|
|
646
736
|
self.clear_run_coordination()
|
|
647
737
|
|
|
648
738
|
def _load_csvpath_objects(
|
|
649
|
-
self,
|
|
739
|
+
self,
|
|
740
|
+
*,
|
|
741
|
+
paths: List[str],
|
|
742
|
+
named_file: str,
|
|
743
|
+
collect_when_not_matched=False,
|
|
744
|
+
filename,
|
|
745
|
+
pathsname,
|
|
650
746
|
):
|
|
651
747
|
csvpath_objects = []
|
|
652
748
|
for path in paths:
|
|
653
749
|
csvpath = self.csvpath()
|
|
654
750
|
csvpath.collect_when_not_matched = collect_when_not_matched
|
|
655
751
|
try:
|
|
656
|
-
self._load_csvpath(
|
|
752
|
+
self._load_csvpath(
|
|
753
|
+
csvpath=csvpath,
|
|
754
|
+
path=path,
|
|
755
|
+
file=named_file,
|
|
756
|
+
filename=filename,
|
|
757
|
+
pathsname=pathsname,
|
|
758
|
+
)
|
|
657
759
|
if csvpath.data_from_preceding is True:
|
|
658
760
|
self.logger.warning(
|
|
659
761
|
"Csvpath identified as {csvpath.identity} is set to use preceding data, but CsvPaths's by_line methods do not permit that"
|
|
@@ -671,7 +773,7 @@ class CsvPaths(CsvPathsPublic, CsvPathsCoordinator, ErrorCollector):
|
|
|
671
773
|
return csvpath_objects
|
|
672
774
|
|
|
673
775
|
def _prep_csvpath_results(self, *, csvpath_objects, filename, pathsname):
|
|
674
|
-
crt = self.
|
|
776
|
+
crt = self.run_time_str(pathsname)
|
|
675
777
|
for i, csvpath in enumerate(csvpath_objects):
|
|
676
778
|
try:
|
|
677
779
|
#
|
|
@@ -13,7 +13,7 @@ from ..util.error import ErrorHandler
|
|
|
13
13
|
from ..util.cache import Cache
|
|
14
14
|
from ..util.file_readers import DataFileReader
|
|
15
15
|
from ..util.reference_parser import ReferenceParser
|
|
16
|
-
from ..util.exceptions import InputException
|
|
16
|
+
from ..util.exceptions import InputException, FileException
|
|
17
17
|
from .file_registrar import FileRegistrar
|
|
18
18
|
|
|
19
19
|
|
|
@@ -218,6 +218,18 @@ class FileManager(CsvPathsFileManager): # pylint: disable=C0115
|
|
|
218
218
|
path, filetype=filetype, delimiter=delimiter, quotechar=quotechar
|
|
219
219
|
)
|
|
220
220
|
|
|
221
|
+
def get_fingerprint_for_name(self, name) -> str:
|
|
222
|
+
if name.startswith("$"):
|
|
223
|
+
# atm, we don't give fingerprints for references doing rewind/replay
|
|
224
|
+
return ""
|
|
225
|
+
mpath = self.registrar.manifest_path(name)
|
|
226
|
+
man = self.registrar.get_manifest(mpath)
|
|
227
|
+
if man is None or len(man) == 0:
|
|
228
|
+
raise FileException(
|
|
229
|
+
f"No fingerprint available for named-file name: {name} at manifest path: {mpath}: manifest: {man}"
|
|
230
|
+
)
|
|
231
|
+
return man[len(man) - 1]["fingerprint"]
|
|
232
|
+
|
|
221
233
|
def _name_from_name_part(self, name):
|
|
222
234
|
i = name.rfind(".")
|
|
223
235
|
if i == -1:
|
|
@@ -119,7 +119,7 @@ class FileRegistrar:
|
|
|
119
119
|
jdata = self.get_manifest(manifestpath)
|
|
120
120
|
jdata.append(mdata)
|
|
121
121
|
with open(manifestpath, "w", encoding="utf-8") as file:
|
|
122
|
-
json.dump(jdata, file)
|
|
122
|
+
json.dump(jdata, file, indent=2)
|
|
123
123
|
|
|
124
124
|
def register_named_file(self, *, name: str, path: str) -> None:
|
|
125
125
|
# does the source file exist?
|
|
@@ -69,6 +69,14 @@ class CsvLineSpooler(LineSpooler):
|
|
|
69
69
|
self.writer = csv.writer(self.sink)
|
|
70
70
|
|
|
71
71
|
def next(self):
|
|
72
|
+
if self.path is None:
|
|
73
|
+
self._instance_data_file_path()
|
|
74
|
+
if os.path.exists(self.path) is False:
|
|
75
|
+
self.result.csvpath.logger.debug(
|
|
76
|
+
"There is no data.csv at %s. This may or may not be a problem.",
|
|
77
|
+
self.path,
|
|
78
|
+
)
|
|
79
|
+
return
|
|
72
80
|
for line in DataFileReader(
|
|
73
81
|
self.path,
|
|
74
82
|
filetype="csv",
|
|
@@ -99,7 +99,7 @@ class PathsRegistrar:
|
|
|
99
99
|
mdata["time"] = f"{datetime.now()}"
|
|
100
100
|
jdata.append(mdata)
|
|
101
101
|
with open(manifestpath, "w", encoding="utf-8") as file:
|
|
102
|
-
json.dump(jdata, file)
|
|
102
|
+
json.dump(jdata, file, indent=2)
|
|
103
103
|
|
|
104
104
|
def assure_manifest(self, name: str) -> None:
|
|
105
105
|
nhome = self.named_paths_home(name)
|
|
@@ -9,6 +9,7 @@ from ..util.printer import Printer
|
|
|
9
9
|
from .. import CsvPath
|
|
10
10
|
from .result_serializer import ResultSerializer
|
|
11
11
|
from .line_spooler import LineSpooler, CsvLineSpooler
|
|
12
|
+
from ..util.exceptions import CsvPathsException
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class Result(ErrorCollector, Printer): # pylint: disable=R0902
|
|
@@ -48,6 +49,21 @@ class Result(ErrorCollector, Printer): # pylint: disable=R0902
|
|
|
48
49
|
self._run_dir = run_dir
|
|
49
50
|
self._unmatched = None
|
|
50
51
|
self._data_file_path = None
|
|
52
|
+
if (
|
|
53
|
+
csvpath.metadata is None
|
|
54
|
+
or csvpath.identity is None
|
|
55
|
+
or csvpath.identity == ""
|
|
56
|
+
):
|
|
57
|
+
if csvpath.metadata is None:
|
|
58
|
+
raise CsvPathsException(
|
|
59
|
+
"Metadata cannot be None. Check order of operations."
|
|
60
|
+
)
|
|
61
|
+
#
|
|
62
|
+
# "NAME" is the least favored identifier. if we parse metadata after setting this
|
|
63
|
+
# identity and the csvpath uses any of the other five identifiers it will take
|
|
64
|
+
# precedence over this index. if the csvpath uses NAME it will overwrite.
|
|
65
|
+
#
|
|
66
|
+
csvpath.metadata["NAME"] = self.run_index
|
|
51
67
|
|
|
52
68
|
@property
|
|
53
69
|
def run_time(self) -> datetime:
|
|
@@ -139,14 +155,19 @@ class Result(ErrorCollector, Printer): # pylint: disable=R0902
|
|
|
139
155
|
self._lines = ls
|
|
140
156
|
|
|
141
157
|
def append(self, line: List[Any]) -> None:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
self._lines
|
|
158
|
+
self.lines.append(line)
|
|
159
|
+
# orig
|
|
160
|
+
# if self._lines is None:
|
|
161
|
+
# self._lines = []
|
|
162
|
+
# self._lines.append(line)
|
|
145
163
|
|
|
146
164
|
def __len__(self) -> int:
|
|
147
|
-
if self.
|
|
148
|
-
self._lines
|
|
149
|
-
|
|
165
|
+
if isinstance(self.lines, list):
|
|
166
|
+
return len(self._lines)
|
|
167
|
+
i = 0
|
|
168
|
+
for _ in self.lines.next():
|
|
169
|
+
i += 1
|
|
170
|
+
return i
|
|
150
171
|
|
|
151
172
|
@property
|
|
152
173
|
def unmatched(self) -> list[list[Any]]:
|
|
@@ -183,8 +204,7 @@ class Result(ErrorCollector, Printer): # pylint: disable=R0902
|
|
|
183
204
|
def collect_error(self, error: Error) -> None: # pylint: disable=C0116
|
|
184
205
|
self._errors.append(error)
|
|
185
206
|
|
|
186
|
-
|
|
187
|
-
def has_errors(self) -> bool: # pylint: disable=C0116
|
|
207
|
+
def has_errors(self) -> bool:
|
|
188
208
|
return self.errors_count > 0
|
|
189
209
|
|
|
190
210
|
@property
|