-
-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Line numbers #647
base: main
Are you sure you want to change the base?
Line numbers #647
Changes from 28 commits
a57ae4a
4b23d8d
2e584ac
b7f22de
21659d2
f68e74a
2c26bfa
e0ee3f4
8b31a59
6d8bce9
3150b2f
3143595
9919bc4
3b80801
8152f0c
6ec8730
149b1ba
16996bb
0522ce8
6f62fb8
ba2dd90
2dea597
74b23d0
8575f3f
a087833
7bfac7c
06fc513
5fd6ca1
41d406d
27c7314
f4e098b
8263fdb
add86c6
625a3a5
6f544e9
4178c78
74e3247
c9d35a2
752dbab
5d198ee
160f559
bdd5c04
cc76eb9
f85ed3c
3d61e55
63da121
ba8be89
d84a8bd
be53207
5b10422
93406dd
154af86
3afd4b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,7 @@ | |
|
||
from rdflib import Graph | ||
from rdflib.plugins.parsers.notation3 import BadSyntax | ||
from ruamel.yaml.comments import CommentedMap | ||
from ruamel.yaml.comments import CommentedMap, CommentedSeq | ||
|
||
from schema_salad.exceptions import SchemaSaladException, ValidationException | ||
from schema_salad.fetcher import DefaultFetcher, Fetcher, MemoryCachingFetcher | ||
|
@@ -43,6 +43,9 @@ | |
IdxType = MutableMapping[str, Tuple[Any, "LoadingOptions"]] | ||
|
||
|
||
doc_line_info = CommentedMap() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of |
||
|
||
|
||
class LoadingOptions: | ||
idx: IdxType | ||
fileuri: Optional[str] | ||
|
@@ -203,8 +206,12 @@ def fromDoc( | |
|
||
@abstractmethod | ||
def save( | ||
self, top: bool = False, base_url: str = "", relative_uris: bool = True | ||
) -> Dict[str, Any]: | ||
self, | ||
top: bool = False, | ||
base_url: str = "", | ||
relative_uris: bool = True, | ||
keys: Optional[List[Any]] = None, | ||
) -> CommentedMap: | ||
"""Convert this object to a JSON/YAML friendly dictionary.""" | ||
|
||
|
||
|
@@ -238,26 +245,154 @@ def load_field(val, fieldtype, baseuri, loadingOptions): | |
] | ||
|
||
|
||
def add_kv( | ||
old_doc: CommentedMap, | ||
new_doc: CommentedMap, | ||
line_numbers: Dict[Any, Dict[str, int]], | ||
key: str, | ||
val: Any, | ||
max_len: int, | ||
cols: Dict[int, int], | ||
) -> int: | ||
"""Add key value pair into Commented Map. | ||
|
||
Function to add key value pair into new CommentedMap given old CommentedMap, line_numbers for each key/val pair in the old CommentedMap, | ||
key/val pair to insert, max_line of the old CommentedMap, and max col value taken for each line. | ||
""" | ||
if key in line_numbers: # If the key to insert is in the original CommentedMap | ||
new_doc.lc.add_kv_line_col(key, old_doc.lc.data[key]) | ||
elif isinstance(val, (int, float, bool, str)): # If the value is hashable | ||
if val in line_numbers: # If the value is in the original CommentedMap | ||
line = line_numbers[val]["line"] | ||
if line in cols: | ||
col = max(line_numbers[val]["col"], cols[line]) | ||
else: | ||
col = line_numbers[val]["col"] | ||
new_doc.lc.add_kv_line_col(key, [line, col, line, col + len(key) + 2]) | ||
cols[line] = col + len("id") + 2 | ||
else: # If neither the key or value is in the original CommentedMap (or value is not hashable) | ||
new_doc.lc.add_kv_line_col(key, [max_len, 0, max_len, len(key) + 2]) | ||
max_len += 1 | ||
else: # If neither the key or value is in the original CommentedMap (or value is not hashable) | ||
new_doc.lc.add_kv_line_col(key, [max_len, 0, max_len, len(key) + 2]) | ||
max_len += 1 | ||
return max_len | ||
|
||
|
||
def get_line_numbers(doc: CommentedMap) -> Dict[Any, Dict[str, int]]: | ||
"""Get line numbers for kv pairs in CommentedMap. | ||
|
||
For each key/value pair in a CommentedMap, save the line/col info into a dictionary, | ||
only save value info if value is hashable. | ||
""" | ||
line_numbers: Dict[Any, Dict[str, int]] = {} | ||
if isinstance(doc, dict) or doc is None: | ||
return {} | ||
for key, value in doc.lc.data.items(): | ||
line_numbers[key] = {} | ||
|
||
line_numbers[key]["line"] = doc.lc.data[key][0] | ||
line_numbers[key]["col"] = doc.lc.data[key][1] | ||
if isinstance(value, (int, float, bool, str)): | ||
line_numbers[value] = {} | ||
line_numbers[value]["line"] = doc.lc.data[key][2] | ||
line_numbers[value]["col"] = doc.lc.data[key][3] | ||
return line_numbers | ||
|
||
|
||
def get_max_line_num(doc: CommentedMap) -> int: | ||
"""Get the max line number for a CommentedMap. | ||
|
||
Iterate through the the key with the highest line number until you reach a non-CommentedMap value or empty CommentedMap. | ||
""" | ||
max_line = 0 | ||
max_key = "" | ||
cur = doc | ||
while isinstance(cur, CommentedMap) and len(cur) > 0: | ||
for key in cur.lc.data.keys(): | ||
if cur.lc.data[key][2] >= max_line: | ||
max_line = cur.lc.data[key][2] | ||
max_key = key | ||
cur = cur[max_key] | ||
return max_line + 1 | ||
|
||
|
||
def save( | ||
val: Any, | ||
top: bool = True, | ||
base_url: str = "", | ||
relative_uris: bool = True, | ||
keys: Optional[List[Any]] = None, | ||
) -> save_type: | ||
"""Save a val of any type. | ||
|
||
Recursively calls save method from class if val is of type Saveable. Otherwise, saves val to CommentedMap or CommentedSeq | ||
""" | ||
if keys is None: | ||
keys = [] | ||
doc = doc_line_info | ||
for key in keys: | ||
if isinstance(doc, CommentedMap): | ||
doc = doc.get(key) | ||
elif isinstance(doc, (CommentedSeq, list)) and isinstance(key, int): | ||
if key < len(doc): | ||
doc = doc[key] | ||
else: | ||
doc = None | ||
else: | ||
doc = None | ||
break | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need some discussion about what's going on here. It looks like you're using "keys" to find a path through the original document, to find the leaf node that has the line number info we want. What happens when you have a field with |
||
|
||
if isinstance(val, Saveable): | ||
return val.save(top=top, base_url=base_url, relative_uris=relative_uris) | ||
return val.save( | ||
top=top, base_url=base_url, relative_uris=relative_uris, keys=keys | ||
) | ||
if isinstance(val, MutableSequence): | ||
return [ | ||
save(v, top=False, base_url=base_url, relative_uris=relative_uris) | ||
for v in val | ||
] | ||
r = CommentedSeq() | ||
r.lc.data = {} | ||
for i in range(0, len(val)): | ||
new_keys = keys | ||
if doc: | ||
if i in doc: | ||
r.lc.data[i] = doc.lc.data[i] | ||
new_keys.append(i) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. append is a destructive modification, so appending to |
||
r.append( | ||
save( | ||
val[i], | ||
top=False, | ||
base_url=base_url, | ||
relative_uris=relative_uris, | ||
keys=new_keys, | ||
) | ||
) | ||
return r | ||
# return [ | ||
# save(v, top=False, base_url=base_url, relative_uris=relative_uris) | ||
# for v in val | ||
# ] | ||
if isinstance(val, MutableMapping): | ||
newdict = {} | ||
newdict = CommentedMap() | ||
new_keys = keys | ||
for key in val: | ||
if doc: | ||
if key in doc: | ||
newdict.lc.add_kv_line_col(key, doc.lc.data[key]) | ||
new_keys.append(key) | ||
|
||
newdict[key] = save( | ||
val[key], top=False, base_url=base_url, relative_uris=relative_uris | ||
val[key], | ||
top=False, | ||
base_url=base_url, | ||
relative_uris=relative_uris, | ||
keys=new_keys, | ||
) | ||
return newdict | ||
# newdict = {} | ||
# for key in val: | ||
# newdict[key] = save( | ||
# val[key], top=False, base_url=base_url, relative_uris=relative_uris | ||
# ) | ||
# return newdict | ||
tetron marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if val is None or isinstance(val, (int, float, bool, str)): | ||
return val | ||
raise Exception("Not Saveable: %s" % type(val)) | ||
|
@@ -697,7 +832,7 @@ def load(self, doc, baseuri, loadingOptions, docRoot=None): | |
|
||
def _document_load( | ||
loader: _Loader, | ||
doc: Union[str, MutableMapping[str, Any], MutableSequence[Any]], | ||
doc: Union[CommentedMap, str, MutableMapping[str, Any], MutableSequence[Any]], | ||
baseuri: str, | ||
loadingOptions: LoadingOptions, | ||
addl_metadata_fields: Optional[MutableSequence[str]] = None, | ||
|
@@ -729,11 +864,22 @@ def _document_load( | |
addl_metadata=addl_metadata, | ||
) | ||
|
||
doc = { | ||
k: v | ||
for k, v in doc.items() | ||
if k not in ("$namespaces", "$schemas", "$base") | ||
} | ||
# doc = { | ||
# k: v | ||
# for k, v in doc.items() | ||
# if k not in ("$namespaces", "$schemas", "$base") | ||
# } | ||
tetron marked this conversation as resolved.
Show resolved
Hide resolved
|
||
doc = copy.copy(doc) | ||
if "$namespaces" in doc: | ||
doc.pop("$namespaces") | ||
if "$schemas" in doc: | ||
doc.pop("$schemas") | ||
if "$base" in doc: | ||
doc.pop("$base") | ||
tetron marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if isinstance(doc, CommentedMap): | ||
global doc_line_info | ||
doc_line_info = doc | ||
|
||
if "$graph" in doc: | ||
loadingOptions.idx[baseuri] = ( | ||
|
@@ -750,7 +896,6 @@ def _document_load( | |
loadingOptions.idx[docuri] = loadingOptions.idx[baseuri] | ||
|
||
return loadingOptions.idx[baseuri] | ||
|
||
if isinstance(doc, MutableSequence): | ||
loadingOptions.idx[baseuri] = ( | ||
loader.load(doc, baseuri, loadingOptions), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/usr/bin/env cwl-runner | ||
class: Workflow | ||
cwlVersion: v1.0 | ||
|
||
requirements: | ||
- class: ScatterFeatureRequirement | ||
- class: MultipleInputFeatureRequirement | ||
|
||
inputs: | ||
file1: File[] | ||
file2: File[] | ||
|
||
outputs: | ||
count_output: | ||
type: int | ||
outputSource: step1/output | ||
|
||
steps: | ||
step1: | ||
run: wc3-tool_v1_0.cwl | ||
scatter: file1 | ||
in: | ||
file1: | ||
source: [file1, file2] | ||
linkMerge: merge_nested | ||
out: [output] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/usr/bin/env cwl-runner | ||
class: Workflow | ||
cwlVersion: v1.1 | ||
|
||
requirements: | ||
- class: ScatterFeatureRequirement | ||
- class: MultipleInputFeatureRequirement | ||
|
||
inputs: | ||
file1: File[] | ||
file2: File[] | ||
|
||
outputs: | ||
count_output: | ||
type: int | ||
outputSource: step1/output | ||
|
||
steps: | ||
step1: | ||
run: wc3-tool_v1_1.cwl | ||
scatter: file1 | ||
in: | ||
file1: | ||
source: [file1, file2] | ||
linkMerge: merge_nested | ||
out: [output] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you have
r
,key
andval
together already, I would consider moving the assignment ofr["{fieldname}"] = saved_val
intoadd_kv()
so theadd_kv()
method is responsible for setting both the value and metadata of the entry at the same time.