csvpath 0.0.471__tar.gz → 0.0.472__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.471 → csvpath-0.0.472}/PKG-INFO +1 -1
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/matchable.py +10 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/config.py +15 -14
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/advance.md +1 -1
- csvpath-0.0.472/docs/functions/has_matches.md +17 -0
- csvpath-0.0.472/docs/functions/implementing_functions.md +107 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/import.md +1 -1
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/metaphone.md +1 -1
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions.md +1 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/paths.md +2 -2
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/references.md +1 -1
- {csvpath-0.0.471 → csvpath-0.0.472}/pyproject.toml +1 -1
- csvpath-0.0.471/docs/functions/implementing_functions.md +0 -85
- {csvpath-0.0.471 → csvpath-0.0.472}/LICENSE +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/README.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/config/config.ini +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/__init__.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/csvpath.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/csvpaths.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/managers/__init__.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/managers/csvpaths_manager.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/managers/file_manager.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/managers/result.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/managers/results_manager.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/__init__.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/__init__.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/all.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/andf.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/any.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/between.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/empty.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/exists.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/inf.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/no.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/notf.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/orf.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/boolean/yes.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/count.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/count_headers.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/count_lines.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/count_scans.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/every.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/has_matches.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/increment.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/tally.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/counting/total_lines.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/dates/datef.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/dates/now.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/function.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/function_factory.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/function_focus.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/collect.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/empty_stack.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/end.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/header_name.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/header_names_mismatch.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/headers.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/mismatch.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/replace.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/headers/reset_headers.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/advance.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/after_blank.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/dups.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/first.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/first_line.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/last.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/lines/stop.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/above.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/add.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/divide.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/equals.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/mod.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/multiply.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/round.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/subtract.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/math/sum.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/misc/importf.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/misc/intf.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/misc/nonef.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/misc/random.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/print/jinjaf.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/print/print_line.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/print/print_queue.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/print/printf.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/print/table.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/stats/correlate.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/stats/minf.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/stats/percent.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/stats/percent_unique.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/stats/stdev.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/concat.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/length.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/lower.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/metaphone.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/num.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/regex.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/starts_with.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/strip.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/substring.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/strings/upper.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/testing/debug.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/validation.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/validity/fail.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/validity/failed.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/variables/get.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/variables/pushpop.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/variables/put.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/variables/track.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/functions/variables/variables.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/lark_parser.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/lark_transformer.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/matcher.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/__init__.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/equality.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/expression.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/header.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/qualified.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/reference.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/term.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/productions/variable.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/util/exceptions.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/util/expression_encoder.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/util/expression_utility.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/util/lark_print_parser.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/matching/util/print_parser.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/scanning/__init__.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/scanning/exceptions.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/scanning/parser.out +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/scanning/parsetab.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/scanning/scanner.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/scanning/scanning_lexer.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/cache.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/config_exception.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/error.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/exceptions.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/last_line_stats.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/line_counter.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/line_monitor.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/log_utility.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/metadata_parser.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/csvpath/util/printer.py +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/asbool.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/assignment.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/config.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/examples.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/files.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/above.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/after_blank.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/all.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/andor.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/any.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/average.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/between.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/collect.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/correlate.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/count.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/count_headers.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/date.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/empty.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/empty_stack.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/end.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/every.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/fail.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/first.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/get.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/has_dups.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/header.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/header_name.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/header_names_mismatch.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/in.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/increment.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/jinja.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/last.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/line_number.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/max.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/mismatch.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/no.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/not.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/now.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/percent_unique.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/pop.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/print.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/print_line.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/print_queue.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/regex.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/replace.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/reset_headers.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/stdev.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/stop.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/string_functions.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/subtract.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/sum.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/tally.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/total_lines.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/track.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/variables.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/functions/variables_and_headers.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/grammar.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/headers.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/images/logo-wordmark-white-on-black-trimmed-padded.png +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/images/logo-wordmark-white-trimmed.png +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/qualifiers.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/terms.md +0 -0
- {csvpath-0.0.471 → csvpath-0.0.472}/docs/variables.md +0 -0
|
@@ -38,6 +38,7 @@ class Matchable(Qualified):
|
|
|
38
38
|
return name
|
|
39
39
|
|
|
40
40
|
def _noop_match(self) -> bool:
|
|
41
|
+
"""deprecated. use self.default_match()"""
|
|
41
42
|
return self.match if self.match is not None else True
|
|
42
43
|
|
|
43
44
|
def _noop_value(self) -> bool:
|
|
@@ -122,5 +123,14 @@ class Matchable(Qualified):
|
|
|
122
123
|
# with the current parse tree this shouldn't happen
|
|
123
124
|
return None
|
|
124
125
|
|
|
126
|
+
def _siblings(self) -> list:
|
|
127
|
+
if len(self.children) and hasattr(self.children[0], "op"):
|
|
128
|
+
return self.children[0].commas_to_list()
|
|
129
|
+
else:
|
|
130
|
+
self.matcher.csvpath.error(
|
|
131
|
+
"Cannot get siblings. children[0] is not an Equality"
|
|
132
|
+
)
|
|
133
|
+
return None
|
|
134
|
+
|
|
125
135
|
def default_match(self) -> bool:
|
|
126
136
|
return self.matcher._AND
|
|
@@ -76,7 +76,7 @@ class Config:
|
|
|
76
76
|
def config_path(self) -> str:
|
|
77
77
|
return self._configpath
|
|
78
78
|
|
|
79
|
-
def _get(self, section: str, name: str
|
|
79
|
+
def _get(self, section: str, name: str):
|
|
80
80
|
if self._config is None:
|
|
81
81
|
raise ConfigurationException("No config object available")
|
|
82
82
|
try:
|
|
@@ -89,10 +89,9 @@ class Config:
|
|
|
89
89
|
ret = s
|
|
90
90
|
return ret
|
|
91
91
|
except KeyError:
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
)
|
|
92
|
+
raise ConfigurationException(
|
|
93
|
+
f"Check config at {self.config_path} for [{section}][{name}]"
|
|
94
|
+
)
|
|
96
95
|
|
|
97
96
|
def _create_default_config(self) -> None:
|
|
98
97
|
if not path.exists("config"):
|
|
@@ -137,12 +136,12 @@ path =
|
|
|
137
136
|
|
|
138
137
|
def _assure_cache_path(self) -> None:
|
|
139
138
|
dirpath = self.cache_dir_path
|
|
140
|
-
if dirpath is None:
|
|
141
|
-
dirpath == "cache"
|
|
142
|
-
self._config.add_section("cache")
|
|
143
|
-
self._config.set("cache", "path", dirpath)
|
|
144
139
|
if dirpath and not path.exists(dirpath):
|
|
145
140
|
os.makedirs(dirpath)
|
|
141
|
+
elif not dirpath:
|
|
142
|
+
raise ConfigurationException(
|
|
143
|
+
"No cache path available. Check config.ini [cache][path]."
|
|
144
|
+
)
|
|
146
145
|
|
|
147
146
|
def _assure_config_file_path(self) -> None:
|
|
148
147
|
if not self._configpath or not os.path.isfile(self._configpath):
|
|
@@ -265,11 +264,13 @@ path =
|
|
|
265
264
|
|
|
266
265
|
@property
|
|
267
266
|
def cache_dir_path(self) -> str:
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
267
|
+
try:
|
|
268
|
+
path = self._get("cache", "path")
|
|
269
|
+
except Exception:
|
|
270
|
+
print("No cache path in config.ini at [cache][path]. Using 'cache'.")
|
|
271
|
+
path = "config"
|
|
272
|
+
self._config.add_section("cache")
|
|
273
|
+
self._config.set("cache", "path", path)
|
|
273
274
|
return path
|
|
274
275
|
|
|
275
276
|
@property
|
|
@@ -20,7 +20,7 @@ One way to run it looks like this, using dict objects to identify the csvpaths a
|
|
|
20
20
|
|
|
21
21
|
```python
|
|
22
22
|
paths = CsvPaths()
|
|
23
|
-
paths.
|
|
23
|
+
paths.file_manager.set_named_files(nf)
|
|
24
24
|
paths.paths_manager.set_named_paths(np)
|
|
25
25
|
lines = paths.collect_paths(pathsname="sample", filename="survey")
|
|
26
26
|
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
# Has matches
|
|
3
|
+
|
|
4
|
+
`has_matches()` returns `True` when there have been previous matches. It is a convenience function, since you can achieve the same result with `count()` and other functions; although not quite as simply.
|
|
5
|
+
|
|
6
|
+
## Examples
|
|
7
|
+
|
|
8
|
+
$people.csv[*][
|
|
9
|
+
~ Apply three rules to check if a CSV file is invalid ~
|
|
10
|
+
missing(headers())
|
|
11
|
+
too_long(#lastname, 30)
|
|
12
|
+
not.nocontrib( header_name(0, "firstname") ) -> fail()
|
|
13
|
+
has_matches.nocontrib() -> fail()
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
This csvpath fails a file if any of the other match components match on any line.
|
|
17
|
+
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
|
|
2
|
+
# How to create a function
|
|
3
|
+
|
|
4
|
+
You can easily create your own function, register it for use, and use it in your csvpaths.
|
|
5
|
+
|
|
6
|
+
Functions are descendants of the Function class. Most of the built-ins extend one of:
|
|
7
|
+
- ValueProducer - for functions that mainly generate information
|
|
8
|
+
- MatchDecider - for functions that mainly do a true/false response to information
|
|
9
|
+
- SideEffect - for functions that don't add or consider information in the current line, but rather have some side effect such as printing, setting validity, advancing lines, etc.
|
|
10
|
+
|
|
11
|
+
These three classes are only indicators. You can extend Function directly.
|
|
12
|
+
|
|
13
|
+
from csvpath.matching.functions.function import Function
|
|
14
|
+
class MyFunction(Function):
|
|
15
|
+
...
|
|
16
|
+
|
|
17
|
+
Function implementations override three methods:
|
|
18
|
+
|
|
19
|
+
- `_produce_value(self, skip=[])` - produces the value of the function
|
|
20
|
+
- `_decide_match(self, skip=[])` - determines if the function contributes to a row matching the csvpath
|
|
21
|
+
- `check_valid(self)` - raises an exception if the function is configured incorrectly
|
|
22
|
+
|
|
23
|
+
The first two methods may be called multiple times per row due to checking qualifier constraints, principally `onmatch`, or for other reasons. When a function checks to see if the other csvpath components all match it passes itself in the skip list. The skip list is a list of match components that should not perform their usual calculations if they find themselves in the list. If your function finds itself in the skip list it should immediately return. The return value should be:
|
|
24
|
+
|
|
25
|
+
- `self.value` for `_produce_value`
|
|
26
|
+
- `self.default_match()` for `matches`
|
|
27
|
+
|
|
28
|
+
Usually you want to cache the result of calculating `to_value` and `matches`. Two variables are provided for caching. It is important to set them to a non-None value in order to prevent your function running multiple times.
|
|
29
|
+
|
|
30
|
+
- self.value
|
|
31
|
+
- self.match
|
|
32
|
+
|
|
33
|
+
## Qualifiers
|
|
34
|
+
|
|
35
|
+
Qualifiers are available to your function. They are accessed using the methods in the Qualified class. Qualified is an ancestor of Function. The most relevant capabilities are:
|
|
36
|
+
|
|
37
|
+
- first_non_term_qualifier()
|
|
38
|
+
- qualifiers
|
|
39
|
+
|
|
40
|
+
The former will get you a non-built-in qualifier. The `qualifiers` property gives you access to all qualifiers.
|
|
41
|
+
|
|
42
|
+
All match components support the `onmatch` qualifier. All components support the `nocontrib` when they are on the left-hand side of a when/do (`->`) operation.
|
|
43
|
+
|
|
44
|
+
## Arguments Validation
|
|
45
|
+
|
|
46
|
+
Validation is an important step that happens before any rows are considered. It allows for structural csvpath problems to be discovered before you start processing files. The validity checks only address the number of children and the type of children. You cannot check types or values ofdata provided by child match components because the match components are not setup yet and there is no data at the time validation happens.
|
|
47
|
+
|
|
48
|
+
The most common validations are methods available on the `Validation` class. `Validation` is an ancestor class of Function.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
## Example
|
|
52
|
+
|
|
53
|
+
A very simple function might look like:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
class MyFunction(Function):
|
|
57
|
+
def _produce_value(self, skip=[]) -> None:
|
|
58
|
+
v = self.calculate_stuff()
|
|
59
|
+
self.value = v
|
|
60
|
+
|
|
61
|
+
def _decide_match(self, skip=[]) -> None:
|
|
62
|
+
m = self.calculate_stuff()
|
|
63
|
+
self.match = result
|
|
64
|
+
|
|
65
|
+
def check_valid(self) -> None:
|
|
66
|
+
self.validate_zero_args()
|
|
67
|
+
# you must call check_valid so that your
|
|
68
|
+
# function's children are validated.
|
|
69
|
+
super().check_valid()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
When your function's match depends on its value, or its value depends on its match, it needs to call the appropriate method:
|
|
73
|
+
- To get the value, call self.to_value(skip=skip)
|
|
74
|
+
- To check the match, call self.matches(skip=skip)
|
|
75
|
+
|
|
76
|
+
When your function needs its arguments you can call:
|
|
77
|
+
- self._child_one()
|
|
78
|
+
- self._value_one(skip=skip)
|
|
79
|
+
- self._child_two()
|
|
80
|
+
- self._value_two(skip=skip)
|
|
81
|
+
- self._siblings()
|
|
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 a named argument "skip".
|
|
84
|
+
|
|
85
|
+
## Registering
|
|
86
|
+
|
|
87
|
+
To register your function for use, add it to the FunctionFactory like this:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from csvpath.matching.functions.function_factory import FunctionFactory
|
|
91
|
+
FunctionFactory.add_function(name='iamafunction', function=my_function_instance)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
To use your function do something like:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
"$test[*][ @t = iamafunction() ]"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Behind the scenes an instance of your function will be retrieved with:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
f = FunctionFactory.get_function(matcher=None, name="iamafunction")
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The name you set on FunctionFactory must match the name passed in when a function is requested.
|
|
107
|
+
|
|
@@ -17,7 +17,7 @@ Let's set up the Python to run the simplest import test:
|
|
|
17
17
|
|
|
18
18
|
```python
|
|
19
19
|
cs = CsvPaths()
|
|
20
|
-
cs.
|
|
20
|
+
cs.file_manager.add_named_files_from_dir("./csvs")
|
|
21
21
|
cs.paths_manager.add_named_paths_from_dir("./csvpaths")
|
|
22
22
|
cs.fast_forward_by_line(filename="food", pathsname="import")
|
|
23
23
|
vars = cs.results_manager.get_variables("import")
|
|
@@ -25,7 +25,7 @@ To set up a canonicalization match component takes a bit more effort, but not to
|
|
|
25
25
|
|
|
26
26
|
```python
|
|
27
27
|
paths = CsvPaths()
|
|
28
|
-
paths.
|
|
28
|
+
paths.file_manager.add_named_file(
|
|
29
29
|
name="lookups", path="tests/test_resources/named_files/lookup_names.csv"
|
|
30
30
|
)
|
|
31
31
|
paths.paths_manager.add_named_paths_from_file(
|
|
@@ -85,6 +85,7 @@ There are lots more simple examples on the individual function pages.
|
|
|
85
85
|
<tr><td> count_lines() </td><td> count the lines of data to this point in the file. </td></tr>
|
|
86
86
|
<tr><td> count_scans() </td><td> count lines we checked for match </td></tr>
|
|
87
87
|
<tr><td> <a href='https://github.com/dk107dk/csvpath/blob/main/docs/functions/has_dups.md'>count_dups(header, ...)</a> </td><td> Returns the number of duplicate lines. </td></tr>
|
|
88
|
+
<tr><td> <a href='https://github.com/dk107dk/csvpath/blob/main/docs/functions/has_matches.md'>has_matches(header, ...)</a> </td><td> Matches when any other match component matched anywhere in the file. </td></tr>
|
|
88
89
|
<tr><td> <a href='https://github.com/dk107dk/csvpath/blob/main/docs/functions/line_number.md'>line_number()</a> </td><td> Gives the physical line number. </td></tr>
|
|
89
90
|
<tr><td> <a href='https://github.com/dk107dk/csvpath/blob/main/docs/functions/increment.md'>increment(value, n)</a> </td><td> Increments a variable by n each time seen. </td></tr>
|
|
90
91
|
<tr><td> <a href='https://github.com/dk107dk/csvpath/blob/main/docs/functions/every.md'>every(value, number)</a> </td><td> Matches every Nth time a value is seen. </td></tr>
|
|
@@ -60,7 +60,7 @@ A named path can reference a named file. To extend our example with named files:
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
paths = CsvPaths()
|
|
63
|
-
paths.
|
|
63
|
+
paths.file_manager.set_named_files(nf)
|
|
64
64
|
paths.paths_manager.set_named_paths(np)
|
|
65
65
|
|
|
66
66
|
path = paths.csvpath()
|
|
@@ -105,7 +105,7 @@ We can apply them breadth-first using this code:
|
|
|
105
105
|
|
|
106
106
|
```python
|
|
107
107
|
cs = CsvPaths()
|
|
108
|
-
cs.
|
|
108
|
+
cs.file_manager.set_named_files(FILES)
|
|
109
109
|
cs.paths_manager.add_named_paths_from_dir(NAMED_PATHS_DIR)
|
|
110
110
|
for line in cs.next_by_line(filename="food", pathsname="many"):
|
|
111
111
|
valid = cs.results_manager.is_valid("many")
|
|
@@ -40,7 +40,7 @@ This reference points to the `total` variable resulting from the most recent Csv
|
|
|
40
40
|
|
|
41
41
|
```python
|
|
42
42
|
cs = CsvPaths()
|
|
43
|
-
cs.
|
|
43
|
+
cs.file_manager.add_named_files_from_dir(NAMED_FILES_DIR)
|
|
44
44
|
cs.paths_manager.add_named_paths_from_dir(NAMED_PATHS_DIR)
|
|
45
45
|
cs.fast_forward_paths(filename="orders", pathsname="shipping-validations")
|
|
46
46
|
#
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
# How to create a function
|
|
3
|
-
|
|
4
|
-
You can easily create your own function, register it for use, and use it in your csvpaths.
|
|
5
|
-
|
|
6
|
-
Functions extend the Function class using:
|
|
7
|
-
|
|
8
|
-
from csvpath.matching.functions.function import Function
|
|
9
|
-
class MyFunction(Function):
|
|
10
|
-
...
|
|
11
|
-
|
|
12
|
-
Function implementations override three methods:
|
|
13
|
-
|
|
14
|
-
- `to_value(self, skip=[])` - produces the value of the function
|
|
15
|
-
- `matches(self, skip=[])` - determines if the function contributes to a row matching the csvpath
|
|
16
|
-
- `check_valid(self)` - raises an exception if the function is configured incorrectly
|
|
17
|
-
|
|
18
|
-
The first two methods may be called multiple times per row due to checking qualifier constraints, principally `onmatch`, or for other reasons. When a function checks to see if the other csvpath components all match it passes itself in the skip list. The skip list is a list of match components that should not perform their usual calculations if they find themselves in the list. If your function finds itself in the skip list it should return:
|
|
19
|
-
|
|
20
|
-
- `self.value` for `to_value`
|
|
21
|
-
- `True` for `matches` - this makes sure your function isn't asking itself if it matches
|
|
22
|
-
|
|
23
|
-
Usually you want to cache the result of calculating `to_value` and `matches`. Two variables are provided for caching:
|
|
24
|
-
|
|
25
|
-
- self.value
|
|
26
|
-
- self.match
|
|
27
|
-
|
|
28
|
-
Validation is an important step that happens before any rows are considered. It allows for structural csvpath problems to be discovered before you start processing files. The most common validations are available on the Validation class within Function's class hierarchy.
|
|
29
|
-
|
|
30
|
-
Your function must inherit from Function. It may implement `__init__` and take a `Matcher` object and a string name.
|
|
31
|
-
|
|
32
|
-
## Example
|
|
33
|
-
|
|
34
|
-
A very simple function might look like:
|
|
35
|
-
|
|
36
|
-
```python
|
|
37
|
-
class MyFunction(Function):
|
|
38
|
-
def to_value(self, skip=[]):
|
|
39
|
-
if self in skip:
|
|
40
|
-
return self._noop_value()
|
|
41
|
-
|
|
42
|
-
if self.value is None:
|
|
43
|
-
#
|
|
44
|
-
self.calculate_stuff()
|
|
45
|
-
#
|
|
46
|
-
return self.value
|
|
47
|
-
|
|
48
|
-
def matches(self, skip=[]):
|
|
49
|
-
if self in skip:
|
|
50
|
-
return self._noop_match()
|
|
51
|
-
if self.match is None:
|
|
52
|
-
#
|
|
53
|
-
self.calculate_stuff()
|
|
54
|
-
#
|
|
55
|
-
return self.match
|
|
56
|
-
|
|
57
|
-
def check_valid(self) -> None:
|
|
58
|
-
self.validate_zero_args()
|
|
59
|
-
super().check_valid()
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
In the common case the match depends on the value. In some cases, however, the value depends on the match. When the value is dependent and your function finds itself in the skip list return a call to `self.match()`; otherwise, call `self._noop_value()`. In either case when the match finds `self` in the skip list it should return `self._noop_match()`.
|
|
63
|
-
|
|
64
|
-
## Registering
|
|
65
|
-
|
|
66
|
-
To register your function for use, add it to the FunctionFactory like this:
|
|
67
|
-
|
|
68
|
-
```python
|
|
69
|
-
FunctionFactory.add_function(name='iamafunction', function=my_function_instance)
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
To use your function do something like:
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
"$test[*][ @t = iamafunction() ]"
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Behind the scenes an instance of your function will be retrieved with:
|
|
79
|
-
|
|
80
|
-
```python
|
|
81
|
-
f = FunctionFactory.get_function(matcher=None, name="iamafunction")
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
The name you set on FunctionFactory must match the name passed in when a function is requested.
|
|
85
|
-
|
|
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.471 → csvpath-0.0.472}/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
|
{csvpath-0.0.471 → csvpath-0.0.472}/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
|