csvpath 0.0.473__tar.gz → 0.0.474__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.473 → csvpath-0.0.474}/PKG-INFO +1 -2
- {csvpath-0.0.473 → csvpath-0.0.474}/config/config.ini +4 -0
- csvpath-0.0.474/config/imports.txt +1 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/function_factory.py +11 -14
- csvpath-0.0.474/csvpath/matching/functions/function_finder.py +55 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/util/config.py +28 -1
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/implementing_functions.md +11 -2
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions.md +14 -1
- {csvpath-0.0.473 → csvpath-0.0.474}/pyproject.toml +1 -2
- csvpath-0.0.473/csvpath/matching/functions/stats/correlate.py +0 -41
- {csvpath-0.0.473 → csvpath-0.0.474}/LICENSE +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/README.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/__init__.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/csvpath.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/csvpaths.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/managers/__init__.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/managers/csvpaths_manager.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/managers/file_manager.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/managers/result.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/managers/results_manager.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/__init__.py +0 -0
- {csvpath-0.0.473/csvpath/scanning → csvpath-0.0.474/csvpath/matching/functions}/__init__.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/boolean/all.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/boolean/andf.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/boolean/any.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/boolean/between.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/boolean/empty.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/boolean/exists.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/boolean/inf.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/boolean/no.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/boolean/notf.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/boolean/orf.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/boolean/yes.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/counting/count.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/counting/count_headers.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/counting/count_lines.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/counting/count_scans.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/counting/counter.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/counting/every.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/counting/has_matches.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/counting/increment.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/counting/tally.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/counting/total_lines.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/dates/datef.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/dates/now.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/function.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/function_focus.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/headers/collect.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/headers/empty_stack.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/headers/end.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/headers/header_name.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/headers/headers.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/headers/mismatch.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/headers/replace.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/headers/reset_headers.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/lines/advance.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/lines/after_blank.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/lines/dups.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/lines/first.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/lines/first_line.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/lines/last.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/lines/stop.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/math/above.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/math/add.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/math/divide.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/math/equals.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/math/mod.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/math/multiply.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/math/round.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/math/subtract.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/math/sum.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/misc/importf.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/misc/intf.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/misc/nonef.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/misc/random.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/print/jinjaf.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/print/print_line.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/print/print_queue.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/print/printf.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/print/table.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/stats/minf.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/stats/percent.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/stats/percent_unique.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/stats/stdev.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/strings/concat.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/strings/length.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/strings/lower.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/strings/metaphone.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/strings/num.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/strings/regex.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/strings/starts_with.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/strings/strip.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/strings/substring.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/strings/upper.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/testing/debug.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/validation.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/validity/fail.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/validity/failed.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/variables/get.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/variables/pushpop.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/variables/put.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/variables/track.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/variables/variables.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/lark_parser.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/lark_transformer.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/matcher.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/productions/__init__.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/productions/equality.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/productions/expression.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/productions/header.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/productions/matchable.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/productions/qualified.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/productions/reference.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/productions/term.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/productions/variable.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/util/exceptions.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/util/expression_encoder.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/util/expression_utility.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/util/lark_print_parser.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/util/print_parser.py +0 -0
- {csvpath-0.0.473/csvpath/matching/functions → csvpath-0.0.474/csvpath/scanning}/__init__.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/scanning/exceptions.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/scanning/parser.out +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/scanning/parsetab.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/scanning/scanner.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/scanning/scanning_lexer.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/util/cache.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/util/config_exception.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/util/error.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/util/exceptions.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/util/last_line_stats.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/util/line_counter.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/util/line_monitor.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/util/log_utility.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/util/metadata_parser.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/csvpath/util/printer.py +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/asbool.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/assignment.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/config.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/examples.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/files.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/above.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/advance.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/after_blank.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/all.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/andor.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/any.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/average.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/between.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/collect.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/correlate.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/count.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/count_headers.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/counter.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/date.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/empty.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/empty_stack.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/end.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/every.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/fail.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/first.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/get.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/has_dups.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/has_matches.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/header.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/header_name.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/header_names_mismatch.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/import.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/in.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/increment.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/jinja.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/last.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/line_number.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/max.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/metaphone.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/mismatch.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/no.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/not.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/now.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/percent_unique.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/pop.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/print.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/print_line.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/print_queue.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/regex.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/replace.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/reset_headers.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/stdev.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/stop.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/string_functions.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/subtract.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/sum.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/tally.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/total_lines.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/track.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/variables.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/functions/variables_and_headers.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/grammar.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/headers.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/images/logo-wordmark-white-on-black-trimmed-padded.png +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/images/logo-wordmark-white-trimmed.png +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/paths.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/qualifiers.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/references.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/terms.md +0 -0
- {csvpath-0.0.473 → csvpath-0.0.474}/docs/variables.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: csvpath
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.474
|
|
4
4
|
Summary: A declarative language for data extraction and validation of CSV files
|
|
5
5
|
Author: David Kershaw
|
|
6
6
|
Author-email: dk107dk@hotmail.com
|
|
@@ -22,7 +22,6 @@ Requires-Dist: inflect (>=7.3.1,<8.0.0)
|
|
|
22
22
|
Requires-Dist: jinja2 (>=3.1.4,<4.0.0)
|
|
23
23
|
Requires-Dist: lark (>=1.2.2,<2.0.0)
|
|
24
24
|
Requires-Dist: metaphone (>=0.6,<0.7)
|
|
25
|
-
Requires-Dist: pandas (>=2.2.2,<3.0.0)
|
|
26
25
|
Requires-Dist: ply (>=3.11,<4.0)
|
|
27
26
|
Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
|
|
28
27
|
Requires-Dist: tabulate (>=0.9.0,<0.10.0)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from csvpath.matching.functions.boolean.yes import Yes as sure
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# pylint: disable=C0114
|
|
2
2
|
from csvpath.matching.productions.expression import Matchable
|
|
3
3
|
from .function import Function
|
|
4
|
+
from .function_finder import FunctionFinder
|
|
4
5
|
from .dates.now import Now
|
|
5
6
|
from .dates.datef import Date
|
|
6
7
|
from .strings.lower import Lower
|
|
@@ -56,7 +57,8 @@ from .stats.percent import Percent
|
|
|
56
57
|
from .stats.minf import Min, Max, Average
|
|
57
58
|
from .stats.percent_unique import PercentUnique
|
|
58
59
|
from .stats.stdev import Stdev
|
|
59
|
-
|
|
60
|
+
|
|
61
|
+
# from .stats.correlate import Correlate
|
|
60
62
|
from .print.printf import Print
|
|
61
63
|
from .print.table import HeaderTable, RowTable, VarTable, RunTable
|
|
62
64
|
from .print.print_line import PrintLine
|
|
@@ -260,8 +262,8 @@ class FunctionFactory:
|
|
|
260
262
|
f = Strip(matcher, name, child)
|
|
261
263
|
elif name == "jinja":
|
|
262
264
|
f = Jinjaf(matcher, name, child)
|
|
263
|
-
elif name == "correlate":
|
|
264
|
-
f = Correlate(matcher, name, child)
|
|
265
|
+
# elif name == "correlate":
|
|
266
|
+
# f = Correlate(matcher, name, child)
|
|
265
267
|
elif name in ["count_headers", "count_headers_in_line"]:
|
|
266
268
|
f = CountHeaders(matcher, name, child)
|
|
267
269
|
elif name == "percent_unique":
|
|
@@ -292,9 +294,6 @@ class FunctionFactory:
|
|
|
292
294
|
f = Stack(matcher, name, child)
|
|
293
295
|
elif name in ["stdev", "pstdev"]:
|
|
294
296
|
f = Stdev(matcher, name, child)
|
|
295
|
-
#
|
|
296
|
-
# dup_lines can also decide matches
|
|
297
|
-
#
|
|
298
297
|
elif name == "has_dups":
|
|
299
298
|
f = HasDups(matcher, name, child)
|
|
300
299
|
elif name == "count_dups":
|
|
@@ -373,15 +372,13 @@ class FunctionFactory:
|
|
|
373
372
|
f = Num(matcher, name, child)
|
|
374
373
|
elif name == "counter":
|
|
375
374
|
f = Counter(matcher, name, child)
|
|
376
|
-
|
|
377
375
|
else:
|
|
378
|
-
if
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
f = f(matcher, name, child)
|
|
376
|
+
if f is None and find_external_functions:
|
|
377
|
+
if FunctionFinder.EXTERNALS not in FunctionFactory.NOT_MY_FUNCTION:
|
|
378
|
+
FunctionFinder().load(matcher, cls)
|
|
379
|
+
if name in FunctionFactory.NOT_MY_FUNCTION:
|
|
380
|
+
f = cls.NOT_MY_FUNCTION[name]
|
|
381
|
+
f = f(matcher, name, child)
|
|
385
382
|
if not find_external_functions:
|
|
386
383
|
return None
|
|
387
384
|
if f is None:
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# pylint: disable=C0114
|
|
2
|
+
import os
|
|
3
|
+
import importlib
|
|
4
|
+
from csvpath.util.config_exception import ConfigurationException
|
|
5
|
+
from .boolean.yes import Yes
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FunctionFinder:
|
|
9
|
+
EXTERNALS = "externalfunctionsloaded"
|
|
10
|
+
|
|
11
|
+
@classmethod
|
|
12
|
+
def load(cls, matcher, func_fact) -> None:
|
|
13
|
+
# any problems loading will bubble up to the nearest
|
|
14
|
+
# expression and be handled there.
|
|
15
|
+
config = matcher.csvpath.config
|
|
16
|
+
# find the list
|
|
17
|
+
path = config.function_imports
|
|
18
|
+
# read the list
|
|
19
|
+
if path is None:
|
|
20
|
+
matcher.csvpath.logger.error("No [functions][imports] in config.ini")
|
|
21
|
+
return
|
|
22
|
+
if not os.path.exists(path):
|
|
23
|
+
matcher.csvpath.logger.error(
|
|
24
|
+
"No [functions][imports] path from config.ini does not exist"
|
|
25
|
+
)
|
|
26
|
+
return
|
|
27
|
+
with open(path, "r") as file:
|
|
28
|
+
i = 0
|
|
29
|
+
for line in file:
|
|
30
|
+
i += 1
|
|
31
|
+
cls._add_function(matcher, func_fact, line)
|
|
32
|
+
matcher.csvpath.logger.info("Added %s external functions", i)
|
|
33
|
+
# add a sentinel to keep us from attempting reload.
|
|
34
|
+
# this instance will never be found, but the dict will
|
|
35
|
+
# never be empty
|
|
36
|
+
func_fact.add_function(cls.EXTERNALS, Yes(None, cls.EXTERNALS))
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def _add_function(cls, matcher, func_fact, s: str) -> None:
|
|
40
|
+
s = s.strip()
|
|
41
|
+
if s != "":
|
|
42
|
+
instance = None
|
|
43
|
+
# instantiate the classes
|
|
44
|
+
# function_name module classname
|
|
45
|
+
cs = s.split(" ")
|
|
46
|
+
if len(cs) == 6 and cs[0] == "from" and cs[2] == "import" and cs[4] == "as":
|
|
47
|
+
module = importlib.import_module(cs[1])
|
|
48
|
+
class_ = getattr(module, cs[3])
|
|
49
|
+
instance = class_(matcher, cs[5])
|
|
50
|
+
# load to FunctionFactory.add
|
|
51
|
+
func_fact.add_function(cs[5], instance)
|
|
52
|
+
else:
|
|
53
|
+
raise ConfigurationException(
|
|
54
|
+
"Unclear external function import setup: {s}"
|
|
55
|
+
)
|
|
@@ -42,6 +42,7 @@ class Sections(Enum):
|
|
|
42
42
|
CSV_FILES = "csv_files"
|
|
43
43
|
ERRORS = "errors"
|
|
44
44
|
LOGGING = "logging"
|
|
45
|
+
FUNCTIONS = "functions"
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
class Config:
|
|
@@ -172,6 +173,17 @@ path =
|
|
|
172
173
|
self.log_file_size = self._get(
|
|
173
174
|
Sections.LOGGING.value, LogFile.LOG_FILE_SIZE.value
|
|
174
175
|
)
|
|
176
|
+
#
|
|
177
|
+
# path to external functions list. external functions are very optional.
|
|
178
|
+
# not blowing up when absent seems reasonable.
|
|
179
|
+
#
|
|
180
|
+
try:
|
|
181
|
+
self.function_imports = self._get(Sections.FUNCTIONS.value, "imports")
|
|
182
|
+
except Exception:
|
|
183
|
+
pass
|
|
184
|
+
#
|
|
185
|
+
# reload if another config path is set
|
|
186
|
+
#
|
|
175
187
|
path = self._get("config", "path")
|
|
176
188
|
if path:
|
|
177
189
|
path = path.strip().lower()
|
|
@@ -262,17 +274,32 @@ path =
|
|
|
262
274
|
|
|
263
275
|
# ======================================
|
|
264
276
|
|
|
277
|
+
@property
|
|
278
|
+
def configpath(self) -> str:
|
|
279
|
+
return self._configpath
|
|
280
|
+
|
|
281
|
+
@configpath.setter
|
|
282
|
+
def configpath(self, path: str) -> None:
|
|
283
|
+
self._configpath = path
|
|
284
|
+
|
|
265
285
|
@property
|
|
266
286
|
def cache_dir_path(self) -> str:
|
|
267
287
|
try:
|
|
268
288
|
path = self._get("cache", "path")
|
|
269
289
|
except Exception:
|
|
270
|
-
print("No cache path in config.ini at [cache][path]. Using 'cache'.")
|
|
271
290
|
path = "config"
|
|
272
291
|
self._config.add_section("cache")
|
|
273
292
|
self._config.set("cache", "path", path)
|
|
274
293
|
return path
|
|
275
294
|
|
|
295
|
+
@property
|
|
296
|
+
def function_imports(self) -> str:
|
|
297
|
+
return self._function_imports
|
|
298
|
+
|
|
299
|
+
@function_imports.setter
|
|
300
|
+
def function_imports(self, path: str) -> None:
|
|
301
|
+
self._function_imports = path
|
|
302
|
+
|
|
276
303
|
@property
|
|
277
304
|
def csvpath_file_extensions(self) -> list[str]:
|
|
278
305
|
return self._csvpath_file_extensions
|
|
@@ -80,17 +80,26 @@ When your function needs its arguments you can call:
|
|
|
80
80
|
- self._value_two(skip=skip)
|
|
81
81
|
- self._siblings()
|
|
82
82
|
|
|
83
|
-
When you need to get a value or a match from a child object you use `to_value()` or `matches()`. Remember to pass the skip list as
|
|
83
|
+
When you need to get a value or a match from a child object you use `to_value()` or `matches()`. Remember to pass the skip list as the named argument `skip`.
|
|
84
84
|
|
|
85
85
|
## Registering
|
|
86
86
|
|
|
87
|
-
To register your function for use, add it to the FunctionFactory like this:
|
|
87
|
+
To register your function for use, add it to the `FunctionFactory` like this:
|
|
88
88
|
|
|
89
89
|
```python
|
|
90
90
|
from csvpath.matching.functions.function_factory import FunctionFactory
|
|
91
91
|
FunctionFactory.add_function(name='iamafunction', function=my_function_instance)
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
Alternatively, add a file path to your `config.ini` file under the key `[functions][imports]` that points to a list of functions to register. The key is like:
|
|
95
|
+
|
|
96
|
+
[functions]
|
|
97
|
+
imports = my_imports/functions.txt
|
|
98
|
+
|
|
99
|
+
In the file list every function on its own line using a format like that of Python imports:
|
|
100
|
+
|
|
101
|
+
from a.b.c.my_function import MyFunction as iamafunction
|
|
102
|
+
|
|
94
103
|
To use your function do something like:
|
|
95
104
|
|
|
96
105
|
```bash
|
|
@@ -41,7 +41,20 @@ Some functions will optionally make use of an arbitrary name qualifier to better
|
|
|
41
41
|
|
|
42
42
|
## Custom Functions
|
|
43
43
|
|
|
44
|
-
Creating your own function is easy. Once you create a function, you register it with the `FunctionFactory` class. You
|
|
44
|
+
Creating your own function is easy. Once you create a function, you register it with the `FunctionFactory` class. You can register your functions either programmatically or by creating an import file listing your functions. Your import file must be referenced in your `config.ini` file at `[functions][imports]` like this:
|
|
45
|
+
|
|
46
|
+
[functions]
|
|
47
|
+
imports = my_project_assets/my_functions.imports
|
|
48
|
+
|
|
49
|
+
Each custom function has its own line in your imports file. The format is the same as you use for importing classes into Python files -- under the hood the mechanism is similar. E.g.
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from my_function.for_stuff.me import Me as function_me
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
In this example your class is `Me` and the name of the function you use in your csvpath is `function_me()`
|
|
56
|
+
|
|
57
|
+
Use your functions in csvpaths by simply referring to them by name like you would any built-in function.
|
|
45
58
|
|
|
46
59
|
<a href='https://github.com/dk107dk/csvpath/blob/main/docs/functions/implementing_functions.md'>Read more about implementing your own functions here.</a>
|
|
47
60
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "csvpath"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.474"
|
|
4
4
|
description = "A declarative language for data extraction and validation of CSV files"
|
|
5
5
|
authors = ["David Kershaw <dk107dk@hotmail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -27,7 +27,6 @@ include = ["config", "logs", "docs"]
|
|
|
27
27
|
python = "^3.12"
|
|
28
28
|
ply = "^3.11"
|
|
29
29
|
python-dateutil = "^2.9.0.post0"
|
|
30
|
-
pandas = "^2.2.2"
|
|
31
30
|
jinja2 = "^3.1.4"
|
|
32
31
|
inflect = "^7.3.1"
|
|
33
32
|
lark = "^1.2.2"
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# pylint: disable=C0114
|
|
2
|
-
import pandas as pd
|
|
3
|
-
from ..function_focus import ValueProducer
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class Correlate(ValueProducer):
|
|
7
|
-
"""does a statistical correlation test on the values of two headers"""
|
|
8
|
-
|
|
9
|
-
def check_valid(self) -> None:
|
|
10
|
-
self.validate_two_args()
|
|
11
|
-
super().check_valid()
|
|
12
|
-
|
|
13
|
-
def _produce_value(self, skip=None) -> None:
|
|
14
|
-
child = self.children[0]
|
|
15
|
-
left = child.left
|
|
16
|
-
right = child.right
|
|
17
|
-
leftlist = left.to_value(skip=skip)
|
|
18
|
-
rightlist = right.to_value(skip=skip)
|
|
19
|
-
leftlist, rightlist = self._trim(leftlist, rightlist)
|
|
20
|
-
ll = pd.Series(leftlist)
|
|
21
|
-
rl = pd.Series(rightlist)
|
|
22
|
-
corr = ll.corr(rl)
|
|
23
|
-
f = float(corr)
|
|
24
|
-
f = round(f, 2)
|
|
25
|
-
self.value = f
|
|
26
|
-
|
|
27
|
-
def _decide_match(self, skip=None) -> None:
|
|
28
|
-
self.to_value(skip=skip)
|
|
29
|
-
self.match = self._noop_match() # pragma: no cover
|
|
30
|
-
|
|
31
|
-
def _trim(self, leftlist, rightlist):
|
|
32
|
-
n = len(leftlist) if len(leftlist) < len(rightlist) else len(rightlist)
|
|
33
|
-
ll = []
|
|
34
|
-
rl = []
|
|
35
|
-
for i in range(0, n):
|
|
36
|
-
try:
|
|
37
|
-
ll.append(float(leftlist[i]))
|
|
38
|
-
rl.append(float(rightlist[i]))
|
|
39
|
-
except (TypeError, ValueError):
|
|
40
|
-
pass
|
|
41
|
-
return ll, rl
|
|
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
|
{csvpath-0.0.473 → csvpath-0.0.474}/csvpath/matching/functions/headers/header_names_mismatch.py
RENAMED
|
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
|
|
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
|
|
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
|
{csvpath-0.0.473 → csvpath-0.0.474}/docs/images/logo-wordmark-white-on-black-trimmed-padded.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|