scripts: Reverted csv read/writing to pass notes through

On second thought, let's keep the more complicated results contained in
the json format. No reason to create complexity we don't need.

Note this also rips note parsing out of csv.py's collect_csv. Now all
scripts should ignore note fields in csv files, but accept note fields
in json files.

The impl is still in the history if we want to revert this in the
future.
This commit is contained in:
Christopher Haster
2026-03-05 10:19:14 -06:00
parent ecc72e3dba
commit 63d047484a
9 changed files with 44 additions and 163 deletions
+5 -18
View File
@@ -937,10 +937,10 @@ def read_csv(path, Result, *,
with openio(path, 'r') as f: with openio(path, 'r') as f:
# csv or json? assume json starts with [ # csv or json? assume json starts with [
json = (f.buffer.peek(1)[:1] == b'[') is_json = (f.buffer.peek(1)[:1] == b'[')
# read csv? # read csv?
if not json: if not is_json:
results = [] results = []
reader = csv.DictReader(f, restval='') reader = csv.DictReader(f, restval='')
for r in reader: for r in reader:
@@ -955,13 +955,7 @@ def read_csv(path, Result, *,
and r[k].strip()} and r[k].strip()}
| {k: r[prefix+k] for k in fields | {k: r[prefix+k] for k in fields
if prefix+k in r if prefix+k in r
and r[prefix+k].strip()} and r[prefix+k].strip()})))
| ({Result._notes: set(n.strip()
for n in r[Result._notes].split(',')
if n.strip())}
if hasattr(Result, '_notes')
and Result._notes in r
else {}))))
except TypeError: except TypeError:
pass pass
return results return results
@@ -1027,9 +1021,7 @@ def write_csv(path, Result, results, *,
writer = csv.DictWriter(f, list( writer = csv.DictWriter(f, list(
co.OrderedDict.fromkeys(it.chain( co.OrderedDict.fromkeys(it.chain(
by, by,
(prefix+k for k in fields), (prefix+k for k in fields))).keys()))
[Result._notes] if hasattr(Result, '_notes')
else [])).keys()))
writer.writeheader() writer.writeheader()
for r in results: for r in results:
# note this allows by/fields to overlap # note this allows by/fields to overlap
@@ -1039,12 +1031,7 @@ def write_csv(path, Result, results, *,
if getattr(r, k) is not None} if getattr(r, k) is not None}
| {prefix+k: getattr(r, k).__csv__() | {prefix+k: getattr(r, k).__csv__()
for k in fields for k in fields
if getattr(r, k) is not None} if getattr(r, k) is not None})
| ({Result._notes: ','.join(
getattr(r, Result._notes))}
if hasattr(Result, '_notes')
and getattr(r, Result._notes)
else {}))
# write json? # write json?
else: else:
+5 -18
View File
@@ -806,10 +806,10 @@ def read_csv(path, Result, *,
with openio(path, 'r') as f: with openio(path, 'r') as f:
# csv or json? assume json starts with [ # csv or json? assume json starts with [
json = (f.buffer.peek(1)[:1] == b'[') is_json = (f.buffer.peek(1)[:1] == b'[')
# read csv? # read csv?
if not json: if not is_json:
results = [] results = []
reader = csv.DictReader(f, restval='') reader = csv.DictReader(f, restval='')
for r in reader: for r in reader:
@@ -824,13 +824,7 @@ def read_csv(path, Result, *,
and r[k].strip()} and r[k].strip()}
| {k: r[prefix+k] for k in fields | {k: r[prefix+k] for k in fields
if prefix+k in r if prefix+k in r
and r[prefix+k].strip()} and r[prefix+k].strip()})))
| ({Result._notes: set(n.strip()
for n in r[Result._notes].split(',')
if n.strip())}
if hasattr(Result, '_notes')
and Result._notes in r
else {}))))
except TypeError: except TypeError:
pass pass
return results return results
@@ -896,9 +890,7 @@ def write_csv(path, Result, results, *,
writer = csv.DictWriter(f, list( writer = csv.DictWriter(f, list(
co.OrderedDict.fromkeys(it.chain( co.OrderedDict.fromkeys(it.chain(
by, by,
(prefix+k for k in fields), (prefix+k for k in fields))).keys()))
[Result._notes] if hasattr(Result, '_notes')
else [])).keys()))
writer.writeheader() writer.writeheader()
for r in results: for r in results:
# note this allows by/fields to overlap # note this allows by/fields to overlap
@@ -908,12 +900,7 @@ def write_csv(path, Result, results, *,
if getattr(r, k) is not None} if getattr(r, k) is not None}
| {prefix+k: getattr(r, k).__csv__() | {prefix+k: getattr(r, k).__csv__()
for k in fields for k in fields
if getattr(r, k) is not None} if getattr(r, k) is not None})
| ({Result._notes: ','.join(
getattr(r, Result._notes))}
if hasattr(Result, '_notes')
and getattr(r, Result._notes)
else {}))
# write json? # write json?
else: else:
+4 -19
View File
@@ -1894,9 +1894,7 @@ def collect_csv(csv_paths, *,
and v.strip()} and v.strip()}
# special handling for notes field # special handling for notes field
if notes is not None and notes in r: if notes is not None and notes in r:
r_[notes] = set(n.strip() r_[notes] = set(r[notes].split(','))
for n in r[notes].split(',')
if n.strip())
results.append(r_) results.append(r_)
# read json? # read json?
@@ -2634,13 +2632,7 @@ def read_csv(path, Result, *,
and r[k].strip()} and r[k].strip()}
| {k: r[prefix+k] for k in fields | {k: r[prefix+k] for k in fields
if prefix+k in r if prefix+k in r
and r[prefix+k].strip()} and r[prefix+k].strip()})))
| ({Result._notes: set(n.strip()
for n in r[Result._notes].split(',')
if n.strip())}
if hasattr(Result, '_notes')
and Result._notes in r
else {}))))
except TypeError: except TypeError:
pass pass
return results return results
@@ -2706,9 +2698,7 @@ def write_csv(path, Result, results, *,
writer = csv.DictWriter(f, list( writer = csv.DictWriter(f, list(
co.OrderedDict.fromkeys(it.chain( co.OrderedDict.fromkeys(it.chain(
by, by,
(prefix+k for k in fields), (prefix+k for k in fields))).keys()))
[Result._notes] if hasattr(Result, '_notes')
else [])).keys()))
writer.writeheader() writer.writeheader()
for r in results: for r in results:
# note this allows by/fields to overlap # note this allows by/fields to overlap
@@ -2718,12 +2708,7 @@ def write_csv(path, Result, results, *,
if getattr(r, k) is not None} if getattr(r, k) is not None}
| {prefix+k: getattr(r, k).__csv__() | {prefix+k: getattr(r, k).__csv__()
for k in fields for k in fields
if getattr(r, k) is not None} if getattr(r, k) is not None})
| ({Result._notes: ','.join(
getattr(r, Result._notes))}
if hasattr(Result, '_notes')
and getattr(r, Result._notes)
else {}))
# write json? # write json?
else: else:
+5 -18
View File
@@ -1196,10 +1196,10 @@ def read_csv(path, Result, *,
with openio(path, 'r') as f: with openio(path, 'r') as f:
# csv or json? assume json starts with [ # csv or json? assume json starts with [
json = (f.buffer.peek(1)[:1] == b'[') is_json = (f.buffer.peek(1)[:1] == b'[')
# read csv? # read csv?
if not json: if not is_json:
results = [] results = []
reader = csv.DictReader(f, restval='') reader = csv.DictReader(f, restval='')
for r in reader: for r in reader:
@@ -1214,13 +1214,7 @@ def read_csv(path, Result, *,
and r[k].strip()} and r[k].strip()}
| {k: r[prefix+k] for k in fields | {k: r[prefix+k] for k in fields
if prefix+k in r if prefix+k in r
and r[prefix+k].strip()} and r[prefix+k].strip()})))
| ({Result._notes: set(n.strip()
for n in r[Result._notes].split(',')
if n.strip())}
if hasattr(Result, '_notes')
and Result._notes in r
else {}))))
except TypeError: except TypeError:
pass pass
return results return results
@@ -1286,9 +1280,7 @@ def write_csv(path, Result, results, *,
writer = csv.DictWriter(f, list( writer = csv.DictWriter(f, list(
co.OrderedDict.fromkeys(it.chain( co.OrderedDict.fromkeys(it.chain(
by, by,
(prefix+k for k in fields), (prefix+k for k in fields))).keys()))
[Result._notes] if hasattr(Result, '_notes')
else [])).keys()))
writer.writeheader() writer.writeheader()
for r in results: for r in results:
# note this allows by/fields to overlap # note this allows by/fields to overlap
@@ -1298,12 +1290,7 @@ def write_csv(path, Result, results, *,
if getattr(r, k) is not None} if getattr(r, k) is not None}
| {prefix+k: getattr(r, k).__csv__() | {prefix+k: getattr(r, k).__csv__()
for k in fields for k in fields
if getattr(r, k) is not None} if getattr(r, k) is not None})
| ({Result._notes: ','.join(
getattr(r, Result._notes))}
if hasattr(Result, '_notes')
and getattr(r, Result._notes)
else {}))
# write json? # write json?
else: else:
+5 -18
View File
@@ -937,10 +937,10 @@ def read_csv(path, Result, *,
with openio(path, 'r') as f: with openio(path, 'r') as f:
# csv or json? assume json starts with [ # csv or json? assume json starts with [
json = (f.buffer.peek(1)[:1] == b'[') is_json = (f.buffer.peek(1)[:1] == b'[')
# read csv? # read csv?
if not json: if not is_json:
results = [] results = []
reader = csv.DictReader(f, restval='') reader = csv.DictReader(f, restval='')
for r in reader: for r in reader:
@@ -955,13 +955,7 @@ def read_csv(path, Result, *,
and r[k].strip()} and r[k].strip()}
| {k: r[prefix+k] for k in fields | {k: r[prefix+k] for k in fields
if prefix+k in r if prefix+k in r
and r[prefix+k].strip()} and r[prefix+k].strip()})))
| ({Result._notes: set(n.strip()
for n in r[Result._notes].split(',')
if n.strip())}
if hasattr(Result, '_notes')
and Result._notes in r
else {}))))
except TypeError: except TypeError:
pass pass
return results return results
@@ -1027,9 +1021,7 @@ def write_csv(path, Result, results, *,
writer = csv.DictWriter(f, list( writer = csv.DictWriter(f, list(
co.OrderedDict.fromkeys(it.chain( co.OrderedDict.fromkeys(it.chain(
by, by,
(prefix+k for k in fields), (prefix+k for k in fields))).keys()))
[Result._notes] if hasattr(Result, '_notes')
else [])).keys()))
writer.writeheader() writer.writeheader()
for r in results: for r in results:
# note this allows by/fields to overlap # note this allows by/fields to overlap
@@ -1039,12 +1031,7 @@ def write_csv(path, Result, results, *,
if getattr(r, k) is not None} if getattr(r, k) is not None}
| {prefix+k: getattr(r, k).__csv__() | {prefix+k: getattr(r, k).__csv__()
for k in fields for k in fields
if getattr(r, k) is not None} if getattr(r, k) is not None})
| ({Result._notes: ','.join(
getattr(r, Result._notes))}
if hasattr(Result, '_notes')
and getattr(r, Result._notes)
else {}))
# write json? # write json?
else: else:
+5 -18
View File
@@ -1295,10 +1295,10 @@ def read_csv(path, Result, *,
with openio(path, 'r') as f: with openio(path, 'r') as f:
# csv or json? assume json starts with [ # csv or json? assume json starts with [
json = (f.buffer.peek(1)[:1] == b'[') is_json = (f.buffer.peek(1)[:1] == b'[')
# read csv? # read csv?
if not json: if not is_json:
results = [] results = []
reader = csv.DictReader(f, restval='') reader = csv.DictReader(f, restval='')
for r in reader: for r in reader:
@@ -1313,13 +1313,7 @@ def read_csv(path, Result, *,
and r[k].strip()} and r[k].strip()}
| {k: r[prefix+k] for k in fields | {k: r[prefix+k] for k in fields
if prefix+k in r if prefix+k in r
and r[prefix+k].strip()} and r[prefix+k].strip()})))
| ({Result._notes: set(n.strip()
for n in r[Result._notes].split(',')
if n.strip())}
if hasattr(Result, '_notes')
and Result._notes in r
else {}))))
except TypeError: except TypeError:
pass pass
return results return results
@@ -1385,9 +1379,7 @@ def write_csv(path, Result, results, *,
writer = csv.DictWriter(f, list( writer = csv.DictWriter(f, list(
co.OrderedDict.fromkeys(it.chain( co.OrderedDict.fromkeys(it.chain(
by, by,
(prefix+k for k in fields), (prefix+k for k in fields))).keys()))
[Result._notes] if hasattr(Result, '_notes')
else [])).keys()))
writer.writeheader() writer.writeheader()
for r in results: for r in results:
# note this allows by/fields to overlap # note this allows by/fields to overlap
@@ -1397,12 +1389,7 @@ def write_csv(path, Result, results, *,
if getattr(r, k) is not None} if getattr(r, k) is not None}
| {prefix+k: getattr(r, k).__csv__() | {prefix+k: getattr(r, k).__csv__()
for k in fields for k in fields
if getattr(r, k) is not None} if getattr(r, k) is not None})
| ({Result._notes: ','.join(
getattr(r, Result._notes))}
if hasattr(Result, '_notes')
and getattr(r, Result._notes)
else {}))
# write json? # write json?
else: else:
+5 -18
View File
@@ -1269,10 +1269,10 @@ def read_csv(path, Result, *,
with openio(path, 'r') as f: with openio(path, 'r') as f:
# csv or json? assume json starts with [ # csv or json? assume json starts with [
json = (f.buffer.peek(1)[:1] == b'[') is_json = (f.buffer.peek(1)[:1] == b'[')
# read csv? # read csv?
if not json: if not is_json:
results = [] results = []
reader = csv.DictReader(f, restval='') reader = csv.DictReader(f, restval='')
for r in reader: for r in reader:
@@ -1287,13 +1287,7 @@ def read_csv(path, Result, *,
and r[k].strip()} and r[k].strip()}
| {k: r[prefix+k] for k in fields | {k: r[prefix+k] for k in fields
if prefix+k in r if prefix+k in r
and r[prefix+k].strip()} and r[prefix+k].strip()})))
| ({Result._notes: set(n.strip()
for n in r[Result._notes].split(',')
if n.strip())}
if hasattr(Result, '_notes')
and Result._notes in r
else {}))))
except TypeError: except TypeError:
pass pass
return results return results
@@ -1359,9 +1353,7 @@ def write_csv(path, Result, results, *,
writer = csv.DictWriter(f, list( writer = csv.DictWriter(f, list(
co.OrderedDict.fromkeys(it.chain( co.OrderedDict.fromkeys(it.chain(
by, by,
(prefix+k for k in fields), (prefix+k for k in fields))).keys()))
[Result._notes] if hasattr(Result, '_notes')
else [])).keys()))
writer.writeheader() writer.writeheader()
for r in results: for r in results:
# note this allows by/fields to overlap # note this allows by/fields to overlap
@@ -1371,12 +1363,7 @@ def write_csv(path, Result, results, *,
if getattr(r, k) is not None} if getattr(r, k) is not None}
| {prefix+k: getattr(r, k).__csv__() | {prefix+k: getattr(r, k).__csv__()
for k in fields for k in fields
if getattr(r, k) is not None} if getattr(r, k) is not None})
| ({Result._notes: ','.join(
getattr(r, Result._notes))}
if hasattr(Result, '_notes')
and getattr(r, Result._notes)
else {}))
# write json? # write json?
else: else:
+5 -18
View File
@@ -937,10 +937,10 @@ def read_csv(path, Result, *,
with openio(path, 'r') as f: with openio(path, 'r') as f:
# csv or json? assume json starts with [ # csv or json? assume json starts with [
json = (f.buffer.peek(1)[:1] == b'[') is_json = (f.buffer.peek(1)[:1] == b'[')
# read csv? # read csv?
if not json: if not is_json:
results = [] results = []
reader = csv.DictReader(f, restval='') reader = csv.DictReader(f, restval='')
for r in reader: for r in reader:
@@ -955,13 +955,7 @@ def read_csv(path, Result, *,
and r[k].strip()} and r[k].strip()}
| {k: r[prefix+k] for k in fields | {k: r[prefix+k] for k in fields
if prefix+k in r if prefix+k in r
and r[prefix+k].strip()} and r[prefix+k].strip()})))
| ({Result._notes: set(n.strip()
for n in r[Result._notes].split(',')
if n.strip())}
if hasattr(Result, '_notes')
and Result._notes in r
else {}))))
except TypeError: except TypeError:
pass pass
return results return results
@@ -1027,9 +1021,7 @@ def write_csv(path, Result, results, *,
writer = csv.DictWriter(f, list( writer = csv.DictWriter(f, list(
co.OrderedDict.fromkeys(it.chain( co.OrderedDict.fromkeys(it.chain(
by, by,
(prefix+k for k in fields), (prefix+k for k in fields))).keys()))
[Result._notes] if hasattr(Result, '_notes')
else [])).keys()))
writer.writeheader() writer.writeheader()
for r in results: for r in results:
# note this allows by/fields to overlap # note this allows by/fields to overlap
@@ -1039,12 +1031,7 @@ def write_csv(path, Result, results, *,
if getattr(r, k) is not None} if getattr(r, k) is not None}
| {prefix+k: getattr(r, k).__csv__() | {prefix+k: getattr(r, k).__csv__()
for k in fields for k in fields
if getattr(r, k) is not None} if getattr(r, k) is not None})
| ({Result._notes: ','.join(
getattr(r, Result._notes))}
if hasattr(Result, '_notes')
and getattr(r, Result._notes)
else {}))
# write json? # write json?
else: else:
+5 -18
View File
@@ -1085,10 +1085,10 @@ def read_csv(path, Result, *,
with openio(path, 'r') as f: with openio(path, 'r') as f:
# csv or json? assume json starts with [ # csv or json? assume json starts with [
json = (f.buffer.peek(1)[:1] == b'[') is_json = (f.buffer.peek(1)[:1] == b'[')
# read csv? # read csv?
if not json: if not is_json:
results = [] results = []
reader = csv.DictReader(f, restval='') reader = csv.DictReader(f, restval='')
for r in reader: for r in reader:
@@ -1103,13 +1103,7 @@ def read_csv(path, Result, *,
and r[k].strip()} and r[k].strip()}
| {k: r[prefix+k] for k in fields | {k: r[prefix+k] for k in fields
if prefix+k in r if prefix+k in r
and r[prefix+k].strip()} and r[prefix+k].strip()})))
| ({Result._notes: set(n.strip()
for n in r[Result._notes].split(',')
if n.strip())}
if hasattr(Result, '_notes')
and Result._notes in r
else {}))))
except TypeError: except TypeError:
pass pass
return results return results
@@ -1175,9 +1169,7 @@ def write_csv(path, Result, results, *,
writer = csv.DictWriter(f, list( writer = csv.DictWriter(f, list(
co.OrderedDict.fromkeys(it.chain( co.OrderedDict.fromkeys(it.chain(
by, by,
(prefix+k for k in fields), (prefix+k for k in fields))).keys()))
[Result._notes] if hasattr(Result, '_notes')
else [])).keys()))
writer.writeheader() writer.writeheader()
for r in results: for r in results:
# note this allows by/fields to overlap # note this allows by/fields to overlap
@@ -1187,12 +1179,7 @@ def write_csv(path, Result, results, *,
if getattr(r, k) is not None} if getattr(r, k) is not None}
| {prefix+k: getattr(r, k).__csv__() | {prefix+k: getattr(r, k).__csv__()
for k in fields for k in fields
if getattr(r, k) is not None} if getattr(r, k) is not None})
| ({Result._notes: ','.join(
getattr(r, Result._notes))}
if hasattr(Result, '_notes')
and getattr(r, Result._notes)
else {}))
# write json? # write json?
else: else: