diff --git a/src/uproot/_awkward_forth.py b/src/uproot/_awkward_forth.py deleted file mode 100644 index b1ad6985e..000000000 --- a/src/uproot/_awkward_forth.py +++ /dev/null @@ -1,362 +0,0 @@ -# BSD 3-Clause License; see https://github.com/scikit-hep/uproot5/blob/main/LICENSE - -""" -This module defines utilities for adding components to the forth reader. -""" -from __future__ import annotations - -import numpy as np - -symbol_dict = { - np.dtype("bool"): "?", - np.dtype(">u1"): "B", - np.dtype(">u2"): "H", - np.dtype(">u4"): "I", - np.dtype(">u8"): "Q", - np.dtype(">i1"): "b", - np.dtype(">i2"): "h", - np.dtype(">i4"): "i", - np.dtype(">i8"): "q", - np.dtype(">f4"): "f", - np.dtype(">f8"): "d", -} - - -class ForthGenerator: - """ - This class is passed through the Forth code generation, collecting Forth snippets and concatenating them at the end. - """ - - def __init__(self, aform=None, count_obj=0): - self.dummy_form = False - self.top_dummy = None - self.dummy_aform = None - self.aform = aform - self.top_form = None - self.prev_form = None - self.awkward_model = {"name": "TOP", "content": {}} - self.top_node = self.awkward_model - self.ref_list = [] - self.forth_code = {} - self.forth_keys = {} - self.final_code = [] - self.final_header = [] - self.final_init = [] - self.form_keys = [] - self.count_obj = count_obj - - def traverse_aform(self): - self.aform = self.aform.content - - def replace_form_and_model(self, form, model): - temp_node = self.awkward_model - temp_prev_form = self.prev_form - temp_node_top = self.top_node - self.awkward_model = model - self.top_node = self.awkward_model - temp_form = self.aform - temp_form_top = self.top_form - self.top_form = None - self.aform = form - return temp_node, temp_node_top, temp_form, temp_form_top, temp_prev_form - - def get_code_recursive(self, node): - pre, post, init, header = self.tree_walk(node) - return pre, post, init, header - - def tree_walk(self, node): - if "content" in node.keys(): - if node["content"] is None: - return ( - "".join(node["pre_code"]), - "".join(node["post_code"]), - node["init_code"], - node["header_code"], - ) - else: - pre, post, init, header = self.tree_walk(node["content"]) - pre2 = "".join(node["pre_code"]) - pre2 = pre2 + pre - post2 = "".join(node["post_code"]) - post2 = post2 + post - init = node["init_code"] + init - header = node["header_code"] + header - return pre2 + post2, "", init, header - else: - return "", "", "", "" - - def should_add_form(self): - if "content" in self.awkward_model.keys(): - if self.awkward_model["content"] is None: - return False - else: - if len(self.awkward_model["content"].keys()) == 0: - return True - return self.awkward_model["content"]["name"] == "dynamic" - - def get_temp_form_top(self): - return self.top_dummy - - def add_form(self, aform, conlen=0, traverse=1): - if self.aform is None: - self.aform = aform - self.top_form = self.aform - if traverse == 2: - self.aform = self.aform["content"] - else: - if "content" in self.aform.keys(): - if self.aform["content"] == "NULL": - self.aform["content"] = aform - self.prev_form = self.aform - if traverse == 2: - self.aform = self.aform["content"]["content"] - self.prev_form = self.prev_form["content"] - else: - self.aform = self.aform["content"] - else: - raise AssertionError("Form representation is corrupted.") - elif "contents" in self.aform.keys(): - if self.aform["class"] == "RecordArray": - if self.prev_form is not None: - self.prev_form["content"] = aform - self.aform = aform - else: - self.top_form = aform - self.aform = aform - elif len(self.aform["contents"]) == conlen: - pass - else: - return False - - def set_dummy_none(self, temp_top, temp_form, temp_flag): - self.top_dummy = temp_top - self.dummy_aform = temp_form - self.dummy_form = temp_flag - - def get_keys(self, num_keys): - if num_keys == 1: - key = self.count_obj - self.count_obj += 1 - return key - elif num_keys > 1: - out = [] - for _i in range(num_keys): - out.append(self.count_obj) - self.count_obj += 1 - return out - else: - raise AssertionError("Number of keys cannot be less than 1") - - def add_form_key(self, key): - self.form_keys.append(key) - - def go_to(self, aform): - self.awkward_model = aform - - def become(self, aform): - self.awkward_model = aform - - def check_model(self): - return bool(self.awkward_model) - - def get_current_node(self): - self.ref_list.append(self.top_node) - return len(self.ref_list) - 1 - - def get_ref(self, index): - return self.ref_list[index] - - def enable_adding(self): - if ( - "content" in self.awkward_model.keys() - and self.awkward_model["content"] is None - ): - self.awkward_model["content"] = {} - - def add_node_whole(self, new_node, ref_latest): - if "content" in self.awkward_model.keys(): - self.awkward_model["content"] = new_node - else: - self.awkward_model["contents"].append(new_node) - self.awkward_model = ref_latest - - def add_node(self, name, code_attrs, dtype, num_child, content): - if isinstance(self.awkward_model, dict): - if ( - not bool(self.awkward_model["content"]) - and self.awkward_model["content"] is not None - ): - temp_obj = { - "name": name, - "type": dtype, - "pre_code": code_attrs["precode"], - "post_code": code_attrs["postcode"], - "init_code": code_attrs["initcode"], - "header_code": code_attrs["headercode"], - "num_child": num_child, - "content": content, - } - self.awkward_model["content"] = temp_obj - self.awkward_model = self.awkward_model["content"] - return temp_obj - else: - if self.awkward_model["content"] is not None: - if self.awkward_model["content"]["name"] == "dynamic": - temp_obj = { - "name": name, - "type": dtype, - "pre_code": code_attrs["precode"], - "post_code": code_attrs["postcode"], - "init_code": code_attrs["initcode"], - "header_code": code_attrs["headercode"], - "num_child": num_child, - "content": content, - } - self.awkward_model["content"] = temp_obj - self.awkward_model = self.awkward_model["content"] - return temp_obj - else: - temp_node = self.awkward_model - self.awkward_model = self.awkward_model["content"] - return temp_node - else: - temp_node = self.awkward_model - self.awkward_model = self.awkward_model["content"] - return temp_node - if isinstance(self.awkward_model, list): - for elem in self.awkward_model: - if name in elem.values(): - return elem - self.awkward_model.append( - { - "name": name, - "type": dtype, - "pre_code": code_attrs["precode"], - "post_code": code_attrs["postcode"], - "init_code": code_attrs["initcode"], - "header_code": code_attrs["headercode"], - "num_child": num_child, - "content": content, - } - ) - temp_node = self.awkward_model[-1] - self.awkward_model = self.awkward_model[-1]["content"] - return temp_node - - def register_pre(self, ref): - key = str(ref) + "pre" - self.forth_sequence.append(key) - - def add_meta(self, ref, form_key, header, init): - if self.forth_code[id(ref)] is None: - self.forth_code[id(ref)] = {} - for elem in form_key: - self.form_keys.append(elem) - self.forth_code[id(ref)]["forth_header"] = header - self.forth_code[id(ref)]["forth_init"] = init - - def register_post(self, ref): - key = str(ref) + "post" - self.forth_sequence.append(key) - - def add_forth_code(self, ref, forth_exec_pre, forth_exec_post): - if self.forth_code[ref] is None: - self.forth_code[ref] = {} - self.forth_code[ref][str(ref) + "pre"] = forth_exec_pre - self.forth_code[ref][str(ref) + "post"] = forth_exec_post - - def add_to_final(self, code): - if not isinstance(code, list): - raise AssertionError("Something went wrong with Forth code generation.") - self.final_code.extend(code) - - def add_to_header(self, code): - self.final_header.append(code) - - def add_to_init(self, code): - self.final_init.append(code) - - -def forth_stash(context): - """ - Returns a ForthLevelStash object if ForthGeneration is to be done, else None. - """ - if hasattr(context.get("forth"), "gen"): - return ForthLevelStash(context["forth"].gen) - else: - return None - - -class ForthLevelStash: - """ - Helper class to stash code at one level of Forth code generation. Keeps the code generation clean and maintains order for the code snippets. - """ - - def __init__(self, context): - self._pre_code = [] - self._post_code = [] - self._header = "" - self._init = "" - self._form_key = [] - self._gen_obj = context - - def is_forth(self): - return self.forth_present - - def get_gen_obj(self): - return self._gen_obj - - def add_to_pre(self, code): - self._pre_code.append(code) - - def add_to_post(self, code): - self._post_code.append(code) - - def get_attrs(self): - return { - "precode": self._pre_code, - "postcode": self._post_code, - "initcode": self._init, - "headercode": self._header, - } - - def add_to_header(self, code): - self._header += code - - def add_to_init(self, code): - self._init += code - - -def convert_dtype(format): - """Takes datatype codes from classses and returns the full datatype name. - - Args: - format (string): The datatype in the dynamic class - - Returns: - string: The datatype in words. - """ - if format == "?": - return "bool" - elif format == "B": - return "uint8" - elif format == "H": - return "uint16" - elif format == "I": - return "uint32" - elif format == "Q": - return "uint64" - elif format == "b": - return "int8" - elif format == "h": - return "int16" - elif format == "i": - return "int32" - elif format == "q": - return "int64" - elif format == "f": - return "float32" - elif format == "d": - return "float64" - else: - raise AssertionError(f"unexpected format type: {format!r}") diff --git a/src/uproot/_awkwardforth.py b/src/uproot/_awkwardforth.py new file mode 100644 index 000000000..3f578ce30 --- /dev/null +++ b/src/uproot/_awkwardforth.py @@ -0,0 +1,302 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/uproot5/blob/main/LICENSE + +""" +This module defines utilities for adding components to the forth reader. +""" +from __future__ import annotations + +import json + +import numpy as np + +dtype_to_struct = { + np.dtype("bool"): "?", + np.dtype(">u1"): "B", + np.dtype(">u2"): "H", + np.dtype(">u4"): "I", + np.dtype(">u8"): "Q", + np.dtype(">i1"): "b", + np.dtype(">i2"): "h", + np.dtype(">i4"): "i", + np.dtype(">i8"): "q", + np.dtype(">f4"): "f", + np.dtype(">f8"): "d", +} + +struct_to_dtype_name = { + "?": "bool", + "B": "uint8", + "H": "uint16", + "I": "uint32", + "Q": "uint64", + "b": "int8", + "h": "int16", + "i": "int32", + "q": "int64", + "f": "float32", + "d": "float64", +} + + +class SpecialPathItem: + def __init__(self, name): + self.name = name + + def __repr__(self): + return f"SpecialPathItem({self.name!r})" + + def __eq__(self, other): + return isinstance(other, SpecialPathItem) and self.name == other.name + + def __hash__(self): + return hash((SpecialPathItem, self.name)) + + +def add_to_path(forth_obj, context, field): + if forth_obj is not None: + context = dict(context) + context["path"] = context["path"] + (field,) + return context + + +def get_first_key_number(context, extra_fields=()): + return abs(hash(context["path"] + extra_fields)) + + +class ForthGenerator: + def __init__(self, interp): + self._interp = interp + self._active_node = self._top_node = Node("TOP") + self._stack_of_active_nodes = [] + self._final_code = [] + self._final_header = [] + self._final_init = [] + + @property + def model(self): + return self._top_node + + @property + def active_node(self): + return self._active_node + + @property + def final_code(self): + return self._final_code + + @property + def final_header(self): + return self._final_header + + @property + def final_init(self): + return self._final_init + + def add_node(self, new_node, current_node=None, parent_node_name=None): + if current_node is None: + current_node = self._top_node + if parent_node_name is None: + parent_node_name = self._active_node.name + + if ( + parent_node_name == current_node.name + ) and parent_node_name != new_node.name: + for child_node in current_node.children: + if child_node.name == new_node.name: + return + current_node.children.append(new_node) + else: + for child_node in current_node.children: + self.add_node(new_node, child_node, parent_node_name) + + def reset_active_node(self): + self._active_node = self._top_node + self._stack_of_active_nodes = [] + + def set_active_node(self, model): + self._active_node = model + + def push_active_node(self, model): + self._stack_of_active_nodes.append(self._active_node) + self._active_node = model + + def pop_active_node(self): + self._active_node = self._stack_of_active_nodes.pop() + + def _debug_forth(self): + self._interp._debug_forth(self) + + +def get_forth_obj(context): + """ + Returns a the Forth Generator object if ForthGeneration is to be done, else None. + """ + if hasattr(context.get("forth"), "gen"): + return context["forth"].gen + else: + return None + + +class Node: + def __init__( + self, + name, + pre_code=None, + post_code=None, + init_code=None, + header_code=None, + form_details=None, + field_name=None, + children=None, + ): + self._name = name + self._pre_code = [] if pre_code is None else pre_code + self._post_code = [] if post_code is None else post_code + self._init_code = [] if init_code is None else init_code + self._header_code = [] if header_code is None else header_code + self._form_details = {} if form_details is None else form_details + self._field_name = field_name + self._children = [] if children is None else children + + def __str__(self, indent="") -> str: + children = (",\n" + indent).join( + x.__str__(indent + " ") for x in self._children + ) + if len(self._children) != 0: + children = "\n" + indent + " " + children + "\n" + indent + return f"""Node({self._name!r}, +{indent} pre={''.join(self._pre_code)!r}, +{indent} post={''.join(self._post_code)!r}, +{indent} init={''.join(self._init_code)!r}, +{indent} header={''.join(self._header_code)!r}, +{indent} form_details={json.dumps(self._form_details)}, +{indent} field_name={self._field_name!r}, +{indent} children=[{children}])""" + + @property + def name(self): + return self._name + + @name.setter + def name(self, new_name): + self._name = new_name + + @property + def pre_code(self): + return self._pre_code + + @property + def post_code(self): + return self._post_code + + @property + def header_code(self): + return self._header_code + + @property + def init_code(self): + return self._init_code + + @property + def form_details(self): + return self._form_details + + @form_details.setter + def form_details(self, form_details): + self._form_details = form_details + + @property + def field_name(self): + return self._field_name + + @field_name.setter + def field_name(self, new_name): + self._field_name = new_name + + @property + def children(self): + return self._children + + def derive_form(self): + if self._name.endswith(":prebuilt"): + return self._form_details + elif self._form_details.get("class") == "NumpyArray": + assert len(self._children) == 0 + return self._form_details + + elif self._form_details.get("class") in ("ListOffsetArray", "RegularArray"): + out = dict(self._form_details) + + if ( + self._form_details.get("parameters", {}).get("__array__") + in ("string", "bytestring") + and self._form_details.get("content", {}).get("class") == "NumpyArray" + ): + return out + + elif len(self._children) == 0: + if out.get("content", {}).get("class") != "NumpyArray": + out["content"] = "NULL" + return out + + elif ( + len(self._children) == 2 + and self._form_details.get("content", {}).get("class") == "RecordArray" + and self._form_details["content"].get("parameters", {}).get("__array__") + == "sorted_map" + ): + out["content"] = dict(out["content"]) + out["content"]["fields"] = None + out["content"]["contents"] = [] + for child in self._children: + out["content"]["contents"].append(child.derive_form()) + return out + + assert len(self._children) == 1 + returnme = out + while out.get("content", {}).get("class") in ( + "ListOffsetArray", + "RegularArray", + ): + out = out["content"] + out["content"] = self._children[0].derive_form() + return returnme + + elif ( + self._name == "TOP" + or self._name.startswith("dispatch-by-version ") + or self._name.startswith("wrong-instance-version ") + or self._name.startswith("start-of-model ") + ): + assert len(self._children) == 1 + return self._children[0].derive_form() + + else: + out = dict(self._form_details) + out["class"] = "RecordArray" + out["fields"] = [] + out["contents"] = [] + for child in self.children: + if child.name.startswith("base-class "): + assert len(child.children) == 1 + descendant = child.children[0] + if descendant.name.startswith("dispatch-by-version "): + assert len(descendant.children) == 1 + descendant = descendant.children[0] + assert descendant.name.startswith("start-of-model ") + assert len(descendant.children) == 1 + base_form = descendant.children[0].derive_form() + out["fields"].extend(base_form["fields"]) + out["contents"].extend(base_form["contents"]) + else: + descendant = child + while descendant.field_name is None: + assert descendant.form_details.get("class") in ( + "ListOffsetArray", + "RegularArray", + ) + assert len(descendant.children) == 1 + descendant = descendant.children[0] + out["fields"].append(descendant.field_name) + out["contents"].append(child.derive_form()) + return out diff --git a/src/uproot/behaviors/TBranch.py b/src/uproot/behaviors/TBranch.py index 3523eaa2d..7fb3e3c45 100644 --- a/src/uproot/behaviors/TBranch.py +++ b/src/uproot/behaviors/TBranch.py @@ -3079,7 +3079,6 @@ def chunk_to_basket(chunk, branch, basket_num): else: notifications.put(basket) - # all threads (if multithreaded), per branch, share a thread-local context for Forth forth_context = {x: threading.local() for x in branchid_interpretation} def basket_to_array(basket): diff --git a/src/uproot/containers.py b/src/uproot/containers.py index fecc5055e..7fcfcfe9d 100644 --- a/src/uproot/containers.py +++ b/src/uproot/containers.py @@ -8,7 +8,6 @@ """ from __future__ import annotations -import json import struct import types from collections.abc import KeysView, Mapping, Sequence, Set, ValuesView @@ -16,7 +15,7 @@ import numpy import uproot -import uproot._awkward_forth +import uproot._awkwardforth _stl_container_size = struct.Struct(">I") _stl_object_type = numpy.dtype(object) @@ -48,71 +47,65 @@ def _content_cache_key(content): def _read_nested( model, length, chunk, cursor, context, file, selffile, parent, header=True ): - forth_stash = uproot._awkward_forth.forth_stash(context) - - if forth_stash is not None: - forth_obj = forth_stash.get_gen_obj() + forth_obj = uproot._awkwardforth.get_forth_obj(context) if isinstance(model, numpy.dtype): - symbol = uproot._awkward_forth.symbol_dict.get(model) + symbol = uproot._awkwardforth.dtype_to_struct.get(model) + + if forth_obj is not None and symbol is None: + raise uproot.interpretation.objects.CannotBeForth() + + if forth_obj is not None: + key = uproot._awkwardforth.get_first_key_number(context) + forth_stash = uproot._awkwardforth.Node( + f"node{key}", + form_details={ + "class": "NumpyArray", + "primitive": uproot._awkwardforth.struct_to_dtype_name[symbol], + "form_key": f"node{key}", + }, + ) - if symbol is None and forth_stash is not None: - raise TypeError("Cannot be awkward") - if forth_stash is not None: - key = forth_obj.get_keys(1) - node_key = f"node{key}" - form_key = f"node{key}-data" - forth_stash.add_to_header( - f"output node{key}-data {uproot._awkward_forth.convert_dtype(symbol)}\n" + forth_stash.header_code.append( + f"output node{key}-data {uproot._awkwardforth.struct_to_dtype_name[symbol]}\n" ) - forth_stash.add_to_pre(f"stream #!{symbol}-> node{key}-data\n") - if ( - forth_obj.should_add_form() - and forth_obj.awkward_model["name"] != node_key - ): - forth_obj.add_form_key(form_key) - forth_obj.add_form( - { - "class": "NumpyArray", - "primitive": f"{uproot._awkward_forth.convert_dtype(symbol)}", - "form_key": f"node{key}", - } - ) - if forth_obj.awkward_model["name"] == node_key: - temp = forth_obj.awkward_model - else: - temp = forth_obj.add_node( - f"node{key}", - forth_stash.get_attrs(), - "i64", - 1, - None, - ) - forth_obj.go_to(temp) + forth_stash.pre_code.append(f"stream #!{symbol}-> node{key}-data\n") + + forth_obj.add_node(forth_stash) + return cursor.array(chunk, length, model, context) else: values = numpy.empty(length, dtype=_stl_object_type) - if isinstance(model, AsContainer): - if forth_stash is not None: - temp_count = context["forth"].gen.count_obj - for i in range(length): - if forth_stash is not None: - context["forth"].gen.count_obj = temp_count + + if forth_obj is not None: + # These two attributes in ForthGenerator need to be the same each iteration, but are changed in .read() + original_model = forth_obj.active_node + + for i in range(length): + if forth_obj is not None: + forth_obj.set_active_node(original_model) + + if isinstance(model, AsContainer): values[i] = model.read( - chunk, cursor, context, file, selffile, parent, header=header + chunk, + cursor, + context, + file, + selffile, + parent, + header=header, ) - else: - if forth_stash is not None: - temp_count = context["forth"].gen.count_obj - for i in range(length): - if forth_stash is not None: - if "temp_ref" in context.keys(): - context["forth"].gen.go_to(context["temp_ref"]) - context["forth"].gen.count_obj = temp_count - values[i] = model.read(chunk, cursor, context, file, selffile, parent) - if forth_stash is not None and "temp_ref" in context.keys(): - del context["temp_ref"] + else: + values[i] = model.read( + chunk, + cursor, + context, + file, + selffile, + parent, + ) + return values @@ -340,8 +333,9 @@ def awkward_form(self, file, context): return uproot._util.awkward_form(self._model, file, context) def read(self, chunk, cursor, context, file, selffile, parent, header=True): - # AwkwardForth testing: test_0637's tests aren't expected to enter here - context["cancel_forth"] = True + # AwkwardForth testing K: test_0637's tests aren't expected to enter here + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() classname = cursor.string(chunk, context) cursor.skip(1) cls = file.class_named(classname) @@ -465,16 +459,33 @@ def awkward_form(self, file, context): ) def read(self, chunk, cursor, context, file, selffile, parent, header=True): - # AwkwardForth testing: test_0637's 00,03,25,27,30,33,35,36,38,39,45,47,51,56,57,58,60,61,63,65,68,70,71,72,73,74,75,78,79 + # AwkwardForth testing L: test_0637's 00,03,25,27,30,33,35,36,38,39,45,47,51,56,57,58,60,61,63,65,68,70,71,72,73,74,75,78,79 + forth_obj = uproot._awkwardforth.get_forth_obj(context) + if forth_obj: + context = uproot._awkwardforth.add_to_path( + forth_obj, context, uproot._awkwardforth.SpecialPathItem("string") + ) - forth_stash = uproot._awkward_forth.forth_stash(context) + offsets_num = uproot._awkwardforth.get_first_key_number(context) + data_num = offsets_num + 1 + + forth_stash = uproot._awkwardforth.Node( + f"node{offsets_num}", + form_details={ + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "NumpyArray", + "primitive": "uint8", + "inner_shape": [], + "parameters": {"__array__": "char"}, + "form_key": f"node{data_num}", + }, + "parameters": {"__array__": "string"}, + "form_key": f"node{offsets_num}", + }, + ) - if forth_stash is not None: - # raise NotImplementedError - forth_obj = forth_stash.get_gen_obj() - keys = forth_obj.get_keys(2) - offsets_num = keys[0] - data_num = keys[1] if self._header and header: start_cursor = cursor.copy() ( @@ -482,22 +493,22 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): instance_version, is_memberwise, ) = uproot.deserialization.numbytes_version(chunk, cursor, context) - if forth_stash is not None: - temp_jump = cursor._index - start_cursor._index - if temp_jump != 0: - forth_stash.add_to_pre(f"{temp_jump} stream skip\n") + if forth_obj is not None: + cursor_jump = cursor._index - start_cursor._index + if cursor_jump != 0: + forth_stash.pre_code.append(f"{cursor_jump} stream skip\n") if self._length_bytes == "1-5": out = cursor.string(chunk, context) - if forth_stash is not None: - forth_stash.add_to_pre( + if forth_obj is not None: + forth_stash.pre_code.append( f"stream !B-> stack dup 255 = if drop stream !I-> stack then dup node{offsets_num}-offsets +<- stack stream #!B-> node{data_num}-data\n" ) elif self._length_bytes == "4": length = cursor.field(chunk, _stl_container_size, context) out = cursor.string_with_length(chunk, context, length) - if forth_stash is not None: - forth_stash.add_to_pre( + if forth_obj is not None: + forth_stash.pre_code.append( f"stream !I-> stack dup node{offsets_num}-offsets +<- stack stream #B-> node{data_num}-data\n" ) else: @@ -514,29 +525,13 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): file.file_path, ) - if forth_stash is not None: - if forth_obj.should_add_form(): - temp_aform = f'{{"class": "ListOffsetArray", "offsets": "i64", "content": {{"class": "NumpyArray", "primitive": "uint8", "inner_shape": [], "parameters": {{"__array__": "char"}}, "form_key": "node{data_num}"}}, "parameters": {{"__array__": "string"}}, "form_key": "node{offsets_num}"}}' - forth_obj.add_form(json.loads(temp_aform)) - - form_keys = [ - f"node{data_num}-data", - f"node{offsets_num}-offsets", - ] - for elem in form_keys: - forth_obj.add_form_key(elem) - forth_stash.add_to_header( + if forth_obj is not None: + forth_stash.header_code.append( f"output node{offsets_num}-offsets int64\noutput node{data_num}-data uint8\n" ) - forth_stash.add_to_init(f"0 node{offsets_num}-offsets <- stack\n") - temp_form = forth_obj.add_node( - f"node{offsets_num}", - forth_stash.get_attrs(), - "i64", - 0, - None, - ) - forth_obj.go_to(temp_form) + forth_stash.init_code.append(f"0 node{offsets_num}-offsets <- stack\n") + forth_obj.add_node(forth_stash) + return out def __eq__(self, other): @@ -605,7 +600,7 @@ def awkward_form(self, file, context): raise uproot.interpretation.objects.CannotBeAwkward("arbitrary pointer") def read(self, chunk, cursor, context, file, selffile, parent, header=True): - # AwkwardForth testing: test_0637's 29,45,46,49,50 (Awkward Form discovered at read-time) + # AwkwardForth testing M: test_0637's 29,45,46,49,50 (Awkward Form discovered at read-time) return uproot.deserialization.read_object_any( chunk, cursor, context, file, selffile, parent @@ -692,13 +687,39 @@ def awkward_form(self, file, context): return awkward.forms.ListOffsetForm(context["index_format"], values_form) def read(self, chunk, cursor, context, file, selffile, parent, header=True): - # AwkwardForth testing: test_0637's 01,02,23,24,25,26,27,28,30,51,52 + # AwkwardForth testing N: test_0637's 01,02,23,24,25,26,27,28,30,51,52 + forth_obj = uproot._awkwardforth.get_forth_obj(context) - forth_stash = uproot._awkward_forth.forth_stash(context) + if forth_obj is not None: + context = uproot._awkwardforth.add_to_path( + forth_obj, context, uproot._awkwardforth.SpecialPathItem("array") + ) - if forth_stash is not None: - forth_obj = forth_stash.get_gen_obj() - offsets_num = forth_obj.get_keys(1) + offsets_num = uproot._awkwardforth.get_first_key_number(context) + + if len(self.inner_shape) > 0: + temp_form = { + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "RegularArray", + "size": self.inner_shape[0], + }, + "parameters": {}, + "form_key": f"node{offsets_num}", + } + else: + temp_form = { + "class": "ListOffsetArray", + "offsets": "i64", + "parameters": {}, + "form_key": f"node{offsets_num}", + } + + forth_stash = uproot._awkwardforth.Node( + f"node{offsets_num}", + form_details=temp_form, + ) if self._header and header: start_cursor = cursor.copy() @@ -707,16 +728,17 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): instance_version, is_memberwise, ) = uproot.deserialization.numbytes_version(chunk, cursor, context) - if forth_stash is not None: - temp_jump = cursor._index - start_cursor._index - if temp_jump != 0: - forth_stash.add_to_pre(f"{temp_jump} stream skip\n") if is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} in file {selffile.file_path}""" ) + if forth_obj is not None: + temp_jump = cursor._index - start_cursor._index + if temp_jump != 0: + forth_stash.pre_code.append(f"{temp_jump} stream skip\n") + if isinstance(self._values, numpy.dtype): remainder = chunk.get( cursor.index, cursor.index + num_bytes, cursor, context @@ -724,59 +746,46 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): return remainder.view(self._values).reshape(-1, *self.inner_shape) else: - if forth_stash is not None: - forth_stash.add_to_header( + if forth_obj is not None: + forth_stash.header_code.append( f"output node{offsets_num}-offsets int64\n" ) - node_key = f"node{offsets_num}" - form_key = f"node{offsets_num}-offsets" - forth_stash.add_to_init(f"0 node{offsets_num}-offsets <- stack\n") - forth_stash.add_to_pre( + forth_stash.init_code.append( + f"0 node{offsets_num}-offsets <- stack\n" + ) + forth_stash.pre_code.append( "0 bytestops I-> stack \nbegin\ndup stream pos <>\nwhile\nswap 1 + swap\n" ) if len(self.inner_shape) > 0: - forth_stash.add_to_post( + forth_stash.post_code.append( f"repeat\nswap {self.inner_shape[0]} / node{offsets_num}-offsets +<- stack drop\n" ) else: - forth_stash.add_to_post( + forth_stash.post_code.append( f"repeat\nswap node{offsets_num}-offsets +<- stack drop\n" ) - if ( - forth_obj.should_add_form() - and forth_obj.awkward_model["name"] != node_key - ): - forth_obj.add_form_key(form_key) - if len(self.inner_shape) > 0: - temp_aform = f'{{ "class":"ListOffsetArray", "offsets":"i64", "content": {{"class": "RegularArray", "content": "NULL", "size": {self.inner_shape[0]}}}, "parameters": {{}}, "form_key": "node{offsets_num}"}}' - forth_obj.add_form(json.loads(temp_aform), traverse=2) - else: - temp_aform = f'{{ "class":"ListOffsetArray", "offsets":"i64", "content": "NULL", "parameters": {{}}, "form_key": "node{offsets_num}"}}' - forth_obj.add_form(json.loads(temp_aform)) - if forth_obj.awkward_model["name"] == node_key: - temp = forth_obj.awkward_model - else: - temp = forth_obj.add_node( - f"node{offsets_num}", - forth_stash.get_attrs(), - "i64", - 1, - {}, - ) + forth_obj.add_node(forth_stash) out = [] - if forth_stash is not None: - temp_count = forth_obj.count_obj while cursor.displacement(start_cursor) < num_bytes: - if forth_stash is not None: - forth_obj.count_obj = temp_count + if forth_obj is not None: + forth_obj.push_active_node(forth_stash) out.append( self._values.read( - chunk, cursor, context, file, selffile, parent + chunk, + cursor, + uproot._awkwardforth.add_to_path( + forth_obj, + context, + uproot._awkwardforth.SpecialPathItem("item"), + ), + file, + selffile, + parent, ) ) - if forth_stash is not None: - forth_obj.go_to(temp["content"]) + if forth_obj is not None: + forth_obj.pop_active_node() if self._header and header: uproot.deserialization.numbytes_check( @@ -792,8 +801,8 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): else: if self._speedbump: - if forth_stash is not None: - forth_stash.add_to_pre("1 stream skip\n") + if forth_obj is not None: + forth_stash.pre_code.append("1 stream skip\n") cursor.skip(1) if isinstance(self._values, numpy.dtype): @@ -801,269 +810,126 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): return remainder.view(self._values).reshape(-1, *self.inner_shape) else: - if forth_stash is not None: - forth_stash.add_to_header( + if forth_obj is not None: + forth_stash.header_code.append( f"output node{offsets_num}-offsets int64\n" ) - node_key = f"node{offsets_num}" - form_key = f"node{offsets_num}-offsets" - forth_stash.add_to_init(f"0 node{offsets_num}-offsets <- stack\n") - forth_stash.add_to_pre( + forth_stash.init_code.append( + f"0 node{offsets_num}-offsets <- stack\n" + ) + forth_stash.pre_code.append( "0 bytestops I-> stack \nbegin\ndup stream pos <>\nwhile\nswap 1 + swap\n" ) if len(self.inner_shape) > 0: - forth_stash.add_to_post( + forth_stash.post_code.append( f"repeat\nswap {self.inner_shape[0]} / node{offsets_num}-offsets +<- stack drop\n" ) else: - forth_stash.add_to_post( + forth_stash.post_code.append( f"repeat\nswap node{offsets_num}-offsets +<- stack drop\n" ) - if ( - forth_obj.should_add_form() - and forth_obj.awkward_model["name"] != node_key - ): - forth_obj.add_form_key(form_key) - if len(self.inner_shape) > 0: - temp_aform = f'{{ "class":"ListOffsetArray", "offsets":"i64", "content": {{"class": "RegularArray", "content": "NULL", "size": {self.inner_shape[0]}}}, "parameters": {{}}, "form_key": "node{offsets_num}"}}' - forth_obj.add_form(json.loads(temp_aform), traverse=2) - else: - temp_aform = f'{{ "class":"ListOffsetArray", "offsets":"i64", "content": "NULL", "parameters": {{}}, "form_key": "node{offsets_num}"}}' - forth_obj.add_form(json.loads(temp_aform)) - if forth_obj.awkward_model["name"] == node_key: - temp = forth_obj.awkward_model - else: - temp = forth_obj.add_node( - f"node{offsets_num}", - forth_stash.get_attrs(), - "i64", - 1, - {}, - ) + forth_obj.add_node(forth_stash) out = [] - if forth_stash is not None: - temp_count = forth_obj.count_obj while cursor.index < chunk.stop: - if forth_stash is not None: - forth_obj.count_obj = temp_count + if forth_obj is not None: + forth_obj.push_active_node(forth_stash) out.append( self._values.read( - chunk, cursor, context, file, selffile, parent + chunk, + cursor, + uproot._awkwardforth.add_to_path( + forth_obj, + context, + uproot._awkwardforth.SpecialPathItem("item"), + ), + file, + selffile, + parent, ) ) - if forth_stash is not None: - forth_obj.go_to(temp) + if forth_obj is not None: + forth_obj.pop_active_node() - # if forth_stash is not None: - # forth_obj.go_to(temp) return uproot._util.objectarray1d(out).reshape(-1, *self.inner_shape) -class AsRVec(AsContainer): +class AsVectorLike(AsContainer): """ Args: header (bool): Sets the :ref:`uproot.containers.AsContainer.header`. values (:doc:`uproot.model.Model` or :doc:`uproot.containers.Container`): Data type for data nested in the container. - A :doc:`uproot.containers.AsContainer` for ``ROOT::VecOps::RVec``. + Superclass of :doc:`uproot.containers.AsRVec`, :doc:`uproot.containers.AsVector`, + and :doc:`uproot.containers.AsSet`, which have the same ROOT serialization, but + represent different runtime classes. The purpose of this superclass is just to + consolidate implementations. """ def __init__(self, header, values): self.header = header if isinstance(values, AsContainer): - self._values = values + self._items = values elif isinstance(values, type) and issubclass( values, (uproot.model.Model, uproot.model.DispatchByVersion) ): - self._values = values + self._items = values else: - self._values = numpy.dtype(values) + self._items = numpy.dtype(values) def __hash__(self): - return hash((AsRVec, self._header, self._values)) - - @property - def values(self): - """ - Data type for data nested in the container. - """ - return self._values + return hash((type(self), self._header, self._items)) def __repr__(self): - if isinstance(self._values, type): - values = self._values.__name__ + if isinstance(self._items, type): + values = self._items.__name__ else: - values = repr(self._values) - return f"AsRVec({self._header}, {values})" + values = repr(self._items) + return f"{type(self).__name__}({self._header}, {values})" @property def cache_key(self): - return f"AsRVec({self._header},{_content_cache_key(self._values)})" + return ( + f"{type(self).__name__}({self._header},{_content_cache_key(self._items)})" + ) - @property - def typename(self): - return f"RVec<{_content_typename(self._values)}>" + _form_parameters = {} def awkward_form(self, file, context): awkward = uproot.extras.awkward() return awkward.forms.ListOffsetForm( context["index_format"], - uproot._util.awkward_form(self._values, file, context), + uproot._util.awkward_form(self._items, file, context), + parameters=self._form_parameters, ) def read(self, chunk, cursor, context, file, selffile, parent, header=True): - # AwkwardForth testing: test_0637's (none! untested! but it's just like AsVector) - context["cancel_forth"] = True - if self._header and header: - start_cursor = cursor.copy() - ( - num_bytes, - instance_version, - is_memberwise, - ) = uproot.deserialization.numbytes_version(chunk, cursor, context) - else: - is_memberwise = False - - # Note: self._values can also be a NumPy dtype, and not necessarily a class - # (e.g. type(self._values) == type) - _value_typename = _content_typename(self._values) - if is_memberwise: - if not issubclass(self._values, uproot.model.DispatchByVersion): - raise NotImplementedError( - """streamerless memberwise serialization of class {}({}) - in file {}""".format( - type(self).__name__, _value_typename, selffile.file_path - ) - ) - - # uninterpreted header - cursor.skip(6) - - length = cursor.field(chunk, _stl_container_size, context) - - # no known class version number (maybe in that header? unclear...) - model = self._values.new_class(file, "max") - - values = numpy.empty(length, dtype=_stl_object_type) - - # only do anything if we have anything to read... - if length > 0: - for i in range(length): - values[i] = model.read( - chunk, - cursor, - dict(context, reading=False), - file, - selffile, - parent, - ) - - # memberwise reading! - for member_index in range(len(values[0].member_names)): - for i in range(length): - values[i].read_member_n( - chunk, cursor, context, file, member_index - ) - else: - length = cursor.field(chunk, _stl_container_size, context) + # AwkwardForth testing P: test_0637's 00,03,04,06,07,08,09,10,11,12,13,14,15,16,17,23,24,26,27,28,31,33,36,38,41,42,43,44,45,46,49,50,55,56,57,58,59,60,61,62,63,67,68,72,73,76,77,80 + # AwkwardForth testing Q: test_0637's 62,63,64,65,69,70,74,75,77 + # AwkwardForth testing O: test_0637's (none for RVec) - values = _read_nested( - self._values, length, chunk, cursor, context, file, selffile, parent - ) + forth_obj = uproot._awkwardforth.get_forth_obj(context) - out = ROOTRVec(values) - if self._header and header: - uproot.deserialization.numbytes_check( - chunk, - start_cursor, - cursor, - num_bytes, - self.typename, + if forth_obj is not None: + context = uproot._awkwardforth.add_to_path( + forth_obj, context, - file.file_path, + uproot._awkwardforth.SpecialPathItem(self._specialpathitem_name), ) - return out - - def __eq__(self, other): - if not isinstance(other, AsRVec): - return False - - if self.header != other.header: - return False - - if isinstance(self.values, numpy.dtype) and isinstance( - other.values, numpy.dtype - ): - return self.values == other.values - elif not isinstance(self.values, numpy.dtype) and not isinstance( - other.values, numpy.dtype - ): - return self.values == other.values - else: - return False - - -class AsVector(AsContainer): - """ - Args: - header (bool): Sets the :ref:`uproot.containers.AsContainer.header`. - values (:doc:`uproot.model.Model` or :doc:`uproot.containers.Container`): Data - type for data nested in the container. - - A :doc:`uproot.containers.AsContainer` for ``std::vector``. - """ - - def __init__(self, header, values): - self.header = header - if isinstance(values, AsContainer): - self._values = values - elif isinstance(values, type) and issubclass( - values, (uproot.model.Model, uproot.model.DispatchByVersion) - ): - self._values = values - else: - self._values = numpy.dtype(values) - - def __hash__(self): - return hash((AsVector, self._header, self._values)) - - @property - def values(self): - """ - Data type for data nested in the container. - """ - return self._values - - def __repr__(self): - if isinstance(self._values, type): - values = self._values.__name__ - else: - values = repr(self._values) - return f"AsVector({self._header}, {values})" - - @property - def cache_key(self): - return f"AsVector({self._header},{_content_cache_key(self._values)})" - - @property - def typename(self): - return f"std::vector<{_content_typename(self._values)}>" - - def awkward_form(self, file, context): - awkward = uproot.extras.awkward() - return awkward.forms.ListOffsetForm( - context["index_format"], - uproot._util.awkward_form(self._values, file, context), - ) + key = uproot._awkwardforth.get_first_key_number(context) - def read(self, chunk, cursor, context, file, selffile, parent, header=True): - # AwkwardForth testing: test_0637's 00,03,04,06,07,08,09,10,11,12,13,14,15,16,17,23,24,26,27,28,31,33,36,38,41,42,43,44,45,46,49,50,55,56,57,58,59,60,61,62,63,67,68,72,73,76,77,80 - forth_stash = uproot._awkward_forth.forth_stash(context) - if forth_stash is not None: - forth_obj = forth_stash.get_gen_obj() + node_key = f"node{key}" + forth_stash = uproot._awkwardforth.Node( + node_key, + form_details={ + "class": "ListOffsetArray", + "offsets": "i64", + "parameters": self._form_parameters, + "form_key": node_key, + }, + ) if self._header and header: start_cursor = cursor.copy() @@ -1072,21 +938,22 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): instance_version, is_memberwise, ) = uproot.deserialization.numbytes_version(chunk, cursor, context) - if forth_stash is not None: - temp_jump = cursor._index - start_cursor._index - if temp_jump != 0: - forth_stash.add_to_pre(f"{temp_jump} stream skip\n") + if forth_obj is not None: + forth_stash.pre_code.append( + f"{cursor._index - start_cursor._index} stream skip\n" + ) else: is_memberwise = False - # Note: self._values can also be a NumPy dtype, and not necessarily a class - # (e.g. type(self._values) == type) - _value_typename = _content_typename(self._values) + # Note: self._items can also be a NumPy dtype, and not necessarily a class + # (e.g. type(self._items) == type) + _value_typename = _content_typename(self._items) if is_memberwise: - if forth_stash is not None: - context["cancel_forth"] = True - # let's hard-code in logic for std::pair for now + if forth_obj is not None: + raise uproot.interpretation.objects.CannotBeForth() + + # FIXME: let's hard-code in logic for std::pair for now if not _value_typename.startswith("pair"): raise NotImplementedError( """memberwise serialization of {}({}) @@ -1095,7 +962,7 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): ) ) - if not issubclass(self._values, uproot.model.DispatchByVersion): + if not issubclass(self._items, uproot.model.DispatchByVersion): raise NotImplementedError( """streamerless memberwise serialization of class {}({}) in file {}""".format( @@ -1109,7 +976,7 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): length = cursor.field(chunk, _stl_container_size, context) # no known class version number (maybe in that header? unclear...) - model = self._values.new_class(file, "max") + model = self._items.new_class(file, "max") values = numpy.empty(length, dtype=_stl_object_type) @@ -1133,49 +1000,37 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): ) else: length = cursor.field(chunk, _stl_container_size, context) - - if forth_stash is not None: - key = forth_obj.get_keys(1) - node_key = f"node{key}" - form_key = f"node{key}-offsets" - forth_stash.add_to_header(f"output node{key}-offsets int64\n") - forth_stash.add_to_init(f"0 node{key}-offsets <- stack\n") - forth_stash.add_to_pre( + if forth_obj is not None: + forth_stash.header_code.append(f"output node{key}-offsets int64\n") + forth_stash.init_code.append(f"0 node{key}-offsets <- stack\n") + forth_stash.pre_code.append( f"stream !I-> stack\n dup node{key}-offsets +<- stack\n" ) - # forth_stash.add_to_post("loop\n") - if ( - forth_obj.should_add_form() - and forth_obj.awkward_model["name"] != node_key - ): - forth_obj.add_form_key(form_key) - temp_aform = f'{{ "class":"ListOffsetArray", "offsets":"i64", "content": "NULL", "parameters": {{}}, "form_key": "node{key}"}}' - forth_obj.add_form(json.loads(temp_aform)) - if not isinstance(self._values, numpy.dtype): - forth_stash.add_to_pre("0 do\n") - forth_stash.add_to_post("loop\n") - - if forth_obj.awkward_model["name"] == node_key: - temp = forth_obj.awkward_model - else: - temp = forth_obj.add_node( - node_key, - forth_stash.get_attrs(), - "i64", - 1, - {}, - ) - context["temp_ref"] = temp + if not isinstance(self._items, numpy.dtype): + forth_stash.pre_code.append("0 do\n") + forth_stash.post_code.append("loop\n") + + forth_obj.add_node(forth_stash) + forth_obj.push_active_node(forth_stash) values = _read_nested( - self._values, length, chunk, cursor, context, file, selffile, parent + self._items, + length, + chunk, + cursor, + uproot._awkwardforth.add_to_path( + forth_obj, context, uproot._awkwardforth.SpecialPathItem("item") + ), + file, + selffile, + parent, ) - if forth_stash is not None and not context["cancel_forth"]: - forth_obj.go_to(temp) + if forth_obj is not None: + forth_obj.pop_active_node() - out = STLVector(values) + out = self._container_type(values) if self._header and header: uproot.deserialization.numbytes_check( @@ -1191,169 +1046,111 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): return out def __eq__(self, other): - if not isinstance(other, AsVector): + if not isinstance(other, type(self)): return False if self.header != other.header: return False - if isinstance(self.values, numpy.dtype) and isinstance( - other.values, numpy.dtype + if isinstance(self._items, numpy.dtype) and isinstance( + other._items, numpy.dtype ): - return self.values == other.values - elif not isinstance(self.values, numpy.dtype) and not isinstance( - other.values, numpy.dtype + return self._items == other._items + elif not isinstance(self._items, numpy.dtype) and not isinstance( + other._items, numpy.dtype ): - return self.values == other.values + return self._items == other._items else: return False -class AsSet(AsContainer): +class AsRVec(AsVectorLike): """ Args: header (bool): Sets the :ref:`uproot.containers.AsContainer.header`. - keys (:doc:`uproot.model.Model` or :doc:`uproot.containers.Container`): Data + values (:doc:`uproot.model.Model` or :doc:`uproot.containers.Container`): Data type for data nested in the container. - A :doc:`uproot.containers.AsContainer` for ``std::set``. + A :doc:`uproot.containers.AsContainer` for ``ROOT::VecOps::RVec``. """ - def __init__(self, header, keys): - self.header = header - if isinstance(keys, AsContainer): - self._keys = keys - elif isinstance(keys, type) and issubclass( - keys, (uproot.model.Model, uproot.model.DispatchByVersion) - ): - self._keys = keys - else: - self._keys = numpy.dtype(keys) + _specialpathitem_name = "RVec" - def __hash__(self): - return hash((AsSet, self._header, self._keys)) + @property + def typename(self): + return f"RVec<{_content_typename(self.values)}>" @property - def keys(self): + def values(self): """ Data type for data nested in the container. """ - return self._keys - - def __repr__(self): - keys = self._keys.__name__ if isinstance(self._keys, type) else repr(self._keys) - return f"AsSet({self._header}, {keys})" + return self._items @property - def cache_key(self): - return f"AsSet({self._header},{_content_cache_key(self._keys)})" + def _container_type(self): + return ROOTRVec + + +class AsVector(AsVectorLike): + """ + Args: + header (bool): Sets the :ref:`uproot.containers.AsContainer.header`. + values (:doc:`uproot.model.Model` or :doc:`uproot.containers.Container`): Data + type for data nested in the container. + + A :doc:`uproot.containers.AsContainer` for ``std::vector``. + """ + + _specialpathitem_name = "vector" @property def typename(self): - return f"std::set<{_content_typename(self._keys)}>" - - def awkward_form(self, file, context): - awkward = uproot.extras.awkward() - return awkward.forms.ListOffsetForm( - context["index_format"], - uproot._util.awkward_form(self._keys, file, context), - parameters={"__array__": "set"}, - ) + return f"std::vector<{_content_typename(self.values)}>" - def read(self, chunk, cursor, context, file, selffile, parent, header=True): - # AwkwardForth testing: test_0637's 62,63,64,65,69,70,74,75,77 + @property + def values(self): + """ + Data type for data nested in the container. + """ + return self._items - forth_stash = uproot._awkward_forth.forth_stash(context) + @property + def _container_type(self): + return STLVector - if forth_stash is not None: - forth_obj = forth_stash.get_gen_obj() - if self._header and header: - start_cursor = cursor.copy() - ( - num_bytes, - instance_version, - is_memberwise, - ) = uproot.deserialization.numbytes_version(chunk, cursor, context) - if forth_stash is not None: - temp_jump = cursor._index - start_cursor._index - if temp_jump != 0: - forth_stash.add_to_pre(f"{temp_jump} stream skip\n") - else: - is_memberwise = False +class AsSet(AsVectorLike): + """ + Args: + header (bool): Sets the :ref:`uproot.containers.AsContainer.header`. + keys (:doc:`uproot.model.Model` or :doc:`uproot.containers.Container`): Data + type for data nested in the container. - if is_memberwise: - raise NotImplementedError( - f"""memberwise serialization of {type(self).__name__} -in file {selffile.file_path}""" - ) + A :doc:`uproot.containers.AsContainer` for ``std::set``. + """ - length = cursor.field(chunk, _stl_container_size, context) - if forth_stash is not None: - key = forth_obj.get_keys(1) - node_key = f"node{key}" - form_key = f"node{key}-offsets" - forth_stash.add_to_header(f"output node{key}-offsets int64\n") - forth_stash.add_to_init(f"0 node{key}-offsets <- stack\n") - forth_stash.add_to_pre( - f"stream !I-> stack\ndup node{key}-offsets +<- stack\n" - ) - # forth_stash.add_to_post("loop\n") - if ( - forth_obj.should_add_form() - and forth_obj.awkward_model["name"] != node_key - ): - forth_obj.add_form_key(form_key) - temp_aform = f'{{ "class":"ListOffsetArray", "offsets":"i64", "content": "NULL", "parameters": {{"__array__": "set"}}, "form_key": "node{key}"}}' - forth_obj.add_form(json.loads(temp_aform)) - if not isinstance(self._keys, numpy.dtype): - forth_stash.add_to_pre("0 do\n") - forth_stash.add_to_post("loop\n") - if forth_obj.awkward_model["name"] == node_key: - temp = forth_obj.awkward_model - else: - temp = forth_obj.add_node( - f"node{key}", - forth_stash.get_attrs(), - "i64", - 1, - {}, - ) - keys = _read_nested( - self._keys, length, chunk, cursor, context, file, selffile, parent - ) - if forth_stash is not None: - forth_obj.go_to(temp) - out = STLSet(keys) + def __init__(self, header, keys): + super().__init__(header, keys) - if self._header and header: - uproot.deserialization.numbytes_check( - chunk, - start_cursor, - cursor, - num_bytes, - self.typename, - context, - file.file_path, - ) + _specialpathitem_name = "set" - return out + @property + def typename(self): + return f"std::set<{_content_typename(self.keys)}>" - def __eq__(self, other): - if not isinstance(other, AsSet): - return False + @property + def keys(self): + """ + Data type for data nested in the container. + """ + return self._items - if self.header != other.header: - return False + _form_parameters = {"__array__": "set"} - if isinstance(self.keys, numpy.dtype) and isinstance(other.keys, numpy.dtype): - return self.keys == other.keys - elif not isinstance(self.keys, numpy.dtype) and not isinstance( - other.keys, numpy.dtype - ): - return self.keys == other.keys - else: - return False + @property + def _container_type(self): + return STLSet def _has_nested_header(obj): @@ -1450,11 +1247,28 @@ def awkward_form(self, file, context): ) def read(self, chunk, cursor, context, file, selffile, parent, header=True): - # AwkwardForth testing: test_0637's 00,33,35,39,47,48,66,67,68,69,70,71,72,73,74,75,76,77,78,79 - forth_stash = uproot._awkward_forth.forth_stash(context) + # AwkwardForth testing R: test_0637's 00,33,35,39,47,48,66,67,68,69,70,71,72,73,74,75,76,77,78,79 + forth_obj = uproot._awkwardforth.get_forth_obj(context) + if forth_obj is not None: + context = uproot._awkwardforth.add_to_path( + forth_obj, context, uproot._awkwardforth.SpecialPathItem("map") + ) + + key = uproot._awkwardforth.get_first_key_number(context) + + forth_stash = uproot._awkwardforth.Node( + f"node{key}", + form_details={ + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "RecordArray", + "parameters": {"__array__": "sorted_map"}, + }, + "form_key": f"node{key}", + }, + ) - if forth_stash is not None: - forth_obj = forth_stash.get_gen_obj() if self._header and header: start_cursor = cursor.copy() ( @@ -1468,115 +1282,80 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): if is_memberwise: if self._header and header: cursor.skip(6) - if forth_stash is not None: - temp_jump = cursor._index - start_cursor._index - forth_stash.add_to_pre(f"{temp_jump} stream skip\n") + if forth_obj is not None: + forth_stash.pre_code.append( + f"{cursor._index-start_cursor._index} stream skip\n" + ) + length = cursor.field(chunk, _stl_container_size, context) - if forth_stash is not None: - key = forth_obj.get_keys(1) - form_key = f"node{key}-offsets" - forth_stash.add_to_header(f"output node{key}-offsets int64\n") - forth_stash.add_to_init(f"0 node{key}-offsets <- stack\n") - forth_stash.add_to_pre( + if forth_obj is not None: + forth_stash.header_code.append(f"output node{key}-offsets int64\n") + forth_stash.init_code.append(f"0 node{key}-offsets <- stack\n") + forth_stash.pre_code.append( f"stream !I-> stack\n dup node{key}-offsets +<- stack\n" ) if _has_nested_header(self._keys) and header: - if forth_stash is not None: - forth_stash.add_to_pre("6 stream skip\n") cursor.skip(6) - if forth_stash is not None: + if forth_obj is not None: + forth_stash.pre_code.append("6 stream skip\n") + if forth_obj is not None: if not isinstance(self._keys, numpy.dtype): - forth_stash.add_to_pre("dup 0 do\n") + forth_stash.pre_code.append("dup 0 do\n") else: - forth_stash.add_to_pre("dup\n") - if forth_stash is not None: - temp = {"name": "TOP", "content": {}} - ( - temp_node, - temp_node_top, - temp_form, - temp_form_top, - temp_prev_form, - ) = forth_obj.replace_form_and_model(None, temp) - context["temp_ref"] = temp + forth_stash.pre_code.append("dup\n") + forth_obj.add_node(forth_stash) + forth_obj.set_active_node(forth_stash) + keys = _read_nested( self._keys, length, chunk, cursor, - context, + uproot._awkwardforth.add_to_path( + forth_obj, context, uproot._awkwardforth.SpecialPathItem("keys") + ), file, selffile, parent, header=False, ) - if forth_stash is not None: - temp = {"name": "TOP", "content": {}} - keys_form = forth_obj.top_form - keys_model = forth_obj.top_node - ( - temp_node1, - temp_node_top1, - temp_form1, - temp_form_top1, - temp_prev_form1, - ) = forth_obj.replace_form_and_model(None, temp) - context["temp_ref"] = temp - if forth_stash is not None and not isinstance(self._keys, numpy.dtype): - keys_model["content"]["post_code"].append("loop\n") + if ( + forth_obj is not None + and not isinstance(self._keys, numpy.dtype) + and len(forth_stash.children) > 0 + ): + forth_stash.children[0].post_code.append("loop\n") if _has_nested_header(self._values) and header: cursor.skip(6) - if forth_stash is not None: - keys_model["content"]["post_code"].append("6 stream skip\n") - if forth_stash is not None and not isinstance(self._values, numpy.dtype): - keys_model["content"]["post_code"].append("0 do\n") + if forth_obj is not None and len(forth_stash.children) > 0: + forth_stash.children[0].post_code.append("6 stream skip\n") + if ( + forth_obj is not None + and not isinstance(self._values, numpy.dtype) + and len(forth_stash.children) > 0 + ): + forth_stash.children[0].post_code.append("0 do\n") + values = _read_nested( self._values, length, chunk, cursor, - context, + uproot._awkwardforth.add_to_path( + forth_obj, context, uproot._awkwardforth.SpecialPathItem("values") + ), file, selffile, parent, header=False, ) - if forth_stash is not None: - values_form = forth_obj.top_form - values_model = forth_obj.top_node - if not isinstance(self._values, numpy.dtype): - values_model["content"]["post_code"].append("loop \n") - forth_obj.awkward_model = temp_node - forth_obj.top_node = temp_node_top - forth_obj.aform = temp_form - forth_obj.top_form = temp_form_top - forth_obj.prev_form = temp_prev_form - aform = { - "class": "ListOffsetArray", - "offsets": "i64", - "content": { - "class": "RecordArray", - "contents": [keys_form, values_form], - "parameters": {"__array__": "sorted_map"}, - }, - "form_key": f"node{key}", - } - if ( - forth_obj.should_add_form() - and forth_obj.awkward_model["name"] != "nodeMap" - ): - forth_obj.add_form_key(form_key) - forth_obj.add_form(aform) - if forth_obj.awkward_model["name"] == "nodeMap": - temp = forth_obj.awkward_model - else: - temp = forth_obj.add_node( - "nodeMap", - forth_stash.get_attrs(), - "i64", - 1, - [keys_model["content"], values_model["content"]], - ) + if ( + forth_obj is not None + and not isinstance(self._values, numpy.dtype) + and len(forth_stash.children) > 1 + ): + forth_stash.children[1].post_code.append("loop\n") + out = STLMap(keys, values) if self._header and header: @@ -1593,11 +1372,8 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): return out else: - if forth_stash is not None: - raise NotImplementedError( - f"""non-memberwise serialization of {type(self).__name__} -in file {selffile.file_path}""" - ) + if forth_obj is not None: + raise uproot.interpretation.objects.CannotBeForth() length = cursor.field(chunk, _stl_container_size, context) keys, values = [], [] for _ in range(length): diff --git a/src/uproot/deserialization.py b/src/uproot/deserialization.py index 6629facf6..ccf0c5863 100644 --- a/src/uproot/deserialization.py +++ b/src/uproot/deserialization.py @@ -67,6 +67,11 @@ def c(name, version=None): return cls new_scope["c"] = c + new_scope["af"] = uproot._awkwardforth + new_scope["DeserializationError"] = uproot.deserialization.DeserializationError + new_scope["CannotBeStrided"] = uproot.interpretation.objects.CannotBeStrided + new_scope["CannotBeForth"] = uproot.interpretation.objects.CannotBeForth + new_scope["CannotBeAwkward"] = uproot.interpretation.objects.CannotBeAwkward try: _actually_compile(class_code, new_scope) diff --git a/src/uproot/interpretation/library.py b/src/uproot/interpretation/library.py index 4fed69919..e6a1fc943 100644 --- a/src/uproot/interpretation/library.py +++ b/src/uproot/interpretation/library.py @@ -841,8 +841,14 @@ def finalize(self, array, branch, interpretation, entry_start, entry_stop, optio isinstance(array, numpy.ndarray) and array.dtype.names is None and len(array.shape) == 1 + and array.dtype != numpy.dtype(object) ): return pandas.Series(array, index=index) + + try: + interpretation.awkward_form(None) + except uproot.interpretation.objects.CannotBeAwkward: + pass else: array = _libraries[Awkward.name].finalize( array, branch, interpretation, entry_start, entry_stop, options @@ -853,6 +859,7 @@ def finalize(self, array, branch, interpretation, entry_start, entry_stop, optio array = array.to_numpy() else: array = uproot.extras.awkward_pandas().AwkwardExtensionArray(array) + return pandas.Series(array, index=index) def group(self, arrays, expression_context, how): diff --git a/src/uproot/interpretation/objects.py b/src/uproot/interpretation/objects.py index c73b910e5..b8964d33d 100644 --- a/src/uproot/interpretation/objects.py +++ b/src/uproot/interpretation/objects.py @@ -21,12 +21,13 @@ from __future__ import annotations import contextlib +import json import threading import numpy import uproot -import uproot._awkward_forth +import uproot._awkwardforth class AsObjects(uproot.interpretation.Interpretation): @@ -49,11 +50,10 @@ class AsObjects(uproot.interpretation.Interpretation): def __init__(self, model, branch=None): self._model = model self._branch = branch + self._form = None self._forth = True - self._forth_lock = threading.Lock() - self._forth_form_keys = None self._complete_forth_code = None - self._form = None + self._forth_lock = threading.Lock() @property def model(self): @@ -108,10 +108,7 @@ def awkward_form( context = self._make_context( context, index_format, header, tobject_header, breadcrumbs ) - if isinstance(self._model, type): - return self._model.awkward_form(self._branch.file, context) - else: - return self._model.awkward_form(self._branch.file, context) + return self._model.awkward_form(self._branch.file, context) def basket_array( self, @@ -155,6 +152,7 @@ def basket_array( library, options, ) + else: output = ObjectArray( self._model, branch, context, byte_offsets, data, cursor_offset @@ -203,22 +201,54 @@ def basket_array_forth( if not hasattr(context["forth"], "vm"): # context["forth"] is a threading.local() context["forth"].vm = None - context["forth"].gen = uproot._awkward_forth.ForthGenerator() + context["forth"].gen = uproot._awkwardforth.ForthGenerator(self) + else: + context["forth"].gen = None if self._complete_forth_code is None: + # all threads have to wait until complete_forth_code is ready with self._forth_lock: - # all threads have to wait until complete_forth_code is ready - - if self._complete_forth_code is None: - # another thread didn't make it while this thread waited - # this thread tries to make it now - output = self._discover_forth( - data, byte_offsets, branch, context, cursor_offset + # another thread might have concluded that this can't be Forth + if not self._forth: + return self.basket_array( + data, + byte_offsets, + basket, + branch, + context, + cursor_offset, + library, + options, ) + # another thread might have already found the complete Forth code + elif self._complete_forth_code is None: + context = dict(context) + context["path"] = () + + # this thread tries to do it! + try: + output = self._discover_forth( + data, byte_offsets, branch, context, cursor_offset + ) + except CannotBeForth: + self._forth = False + context["forth"].gen = None + context["forth"].vm = None + return self.basket_array( + data, + byte_offsets, + basket, + branch, + context, + cursor_offset, + library, + options, + ) + + # Forth discovery was unsuccessful; return Python-derived + # output and maybe another basket will succeed if output is not None: - # Forth discovery was unsuccessful; return Python-derived - # output and maybe another basket will be more fruitful self.hook_after_basket_array( data=data, byte_offsets=byte_offsets, @@ -249,9 +279,7 @@ def basket_array_forth( ) from err # get data using Forth - byte_start = byte_offsets[0] - byte_stop = byte_offsets[-1] - temp_data = data[byte_start:byte_stop] + temp_data = data[byte_offsets[0] : byte_offsets[-1]] context["forth"].vm.begin( { "stream": numpy.array(temp_data), @@ -279,7 +307,25 @@ def basket_array_forth( return output + def _assemble_forth(self, forth_obj, node, only_base=False): + if only_base != node.name.startswith("base-class "): + return + + forth_obj.final_header.extend(node.header_code) + forth_obj.final_init.extend(node.init_code) + + if node.name.startswith("read-members "): + for child in node.children: + self._assemble_forth(forth_obj, child, only_base=True) + forth_obj.final_code.extend(node.pre_code) + for child in node.children: + self._assemble_forth(forth_obj, child) + + forth_obj.final_code.extend(node.post_code) + def _any_NULL(self, form): + # Recursion through form. + # If NULL is found anywhere, return False as Forth is not fully discovered. if form == "NULL": return True else: @@ -297,44 +343,62 @@ def _any_NULL(self, form): return True return False + def _debug_forth(self, forth_obj): + self._assemble_forth(forth_obj, forth_obj.model.children[0]) + expected_form = self._model.awkward_form( + self._branch.file, + { + "index_format": "i64", + "header": False, + "tobject_header": False, + "breadcrumbs": (), + }, + ) + + raise Exception( + f"""EXPECTED FORM: +{expected_form} + +DISCOVERED FORM: +{json.dumps(forth_obj.model.derive_form(), indent=4)} + +FORTH CODE: +input stream + input byteoffsets + input bytestops + {"".join(forth_obj.final_header)} + {"".join(forth_obj.final_init)} + 0 do + byteoffsets I-> stack + stream seek + {"".join(forth_obj.final_code)} + loop + """ + ) + def _discover_forth(self, data, byte_offsets, branch, context, cursor_offset): output = numpy.empty(len(byte_offsets) - 1, dtype=numpy.dtype(object)) - context["cancel_forth"] = False for i in range(len(byte_offsets) - 1): - byte_start = byte_offsets[i] - byte_stop = byte_offsets[i + 1] - temp_data = data[byte_start:byte_stop] - chunk = uproot.source.chunk.Chunk.wrap(branch.file.source, temp_data) + chunk = uproot.source.chunk.Chunk.wrap( + branch.file.source, data[byte_offsets[i] : byte_offsets[i + 1]] + ) cursor = uproot.source.cursor.Cursor( - 0, origin=-(byte_start + cursor_offset) + 0, origin=-(byte_offsets[i] + cursor_offset) ) - if "forth" in context.keys(): - context["forth"].gen.count_obj = 0 - + context["forth"].gen.reset_active_node() output[i] = self._model.read( - chunk, - cursor, - context, - branch.file, - branch.file.detached, - branch, + chunk, cursor, context, branch.file, branch.file.detached, branch ) - if context["cancel_forth"] and "forth" in context.keys(): - del context["forth"] - - if "forth" in context.keys(): - context["forth"].gen.awkward_model = context["forth"].gen.top_node - - discovered_form = context["forth"].gen.top_form - if not self._any_NULL(discovered_form): - context["forth"].prereaddone = True - self._assemble_forth( - context["forth"].gen, context["forth"].gen.top_node["content"] - ) - self._complete_forth_code = f"""input stream + derived_form = context["forth"].gen.model.derive_form() + if not self._any_NULL(derived_form): + context["forth"].prereaddone = True + self._assemble_forth( + context["forth"].gen, context["forth"].gen.model.children[0] + ) + self._complete_forth_code = f"""input stream input byteoffsets input bytestops {"".join(context["forth"].gen.final_header)} @@ -345,26 +409,12 @@ def _discover_forth(self, data, byte_offsets, branch, context, cursor_offset): {"".join(context["forth"].gen.final_code)} loop """ - self._forth_form_keys = tuple(context["forth"].gen.form_keys) - self._form = discovered_form - return None # we should re-read all the data with Forth - - return output # Forth-generation was unsuccessful: this is Python output - - def _assemble_forth(self, forth_obj, awkward_model): - forth_obj.add_to_header(awkward_model["header_code"]) - forth_obj.add_to_init(awkward_model["init_code"]) - forth_obj.add_to_final(awkward_model["pre_code"]) - if "content" in awkward_model.keys(): - temp_content = awkward_model["content"] - if isinstance(temp_content, list): - for elem in temp_content: - self._assemble_forth(forth_obj, elem) - elif isinstance(temp_content, dict): - self._assemble_forth(forth_obj, awkward_model["content"]) - else: - pass - forth_obj.add_to_final(awkward_model["post_code"]) + self._form = derived_form + + return None # we should re-read all the data with Forth + + # Python output when Forth-Generation not successful + return output def final_array( self, @@ -777,6 +827,14 @@ class CannotBeStrided(Exception): """ +class CannotBeForth(Exception): + """ + Exception used to stop recursion over + :ref:`uproot.model.Model.read` as soon as a + non-conforming type is found. + """ + + class CannotBeAwkward(Exception): """ Exception used to stop recursion over diff --git a/src/uproot/model.py b/src/uproot/model.py index fbfa80516..d92e7b289 100644 --- a/src/uproot/model.py +++ b/src/uproot/model.py @@ -787,16 +787,18 @@ def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None): context["breadcrumbs"] = (*old_breadcrumbs, self) self.hook_before_read(chunk=chunk, cursor=cursor, context=context, file=file) - forth_stash = uproot._awkward_forth.forth_stash(context) - if forth_stash is not None: - forth_obj = context["forth"].gen - + forth_obj = uproot._awkwardforth.get_forth_obj(context) + if forth_obj is not None: + forth_stash = uproot._awkwardforth.Node( + name=f"wrong-instance-version {uproot._awkwardforth.get_first_key_number(context)}", + form_details={"offsets": "i64"}, + ) if context.get("reading", True): temp_index = cursor._index self.read_numbytes_version(chunk, cursor, context) length = cursor._index - temp_index - if length != 0 and forth_stash is not None: - forth_stash.add_to_pre(f"{length} stream skip\n") + if length != 0 and forth_obj is not None: + forth_stash.pre_code.append(f"{length} stream skip\n") if ( issubclass(cls, VersionedModel) and self._instance_version != classname_version(cls.__name__) @@ -806,16 +808,11 @@ def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None): if classname_version(correct_cls.__name__) != classname_version( cls.__name__ ): - if forth_stash is not None: - forth_obj.add_node( - "pass", - forth_stash.get_attrs(), - "i64", - 1, - {}, - ) cursor.move_to(self._cursor.index) context["breadcrumbs"] = old_breadcrumbs + if forth_obj is not None: + forth_obj.add_node(forth_stash) + forth_obj.push_active_node(forth_stash) temp_var = correct_cls.read( chunk, cursor, @@ -825,37 +822,37 @@ def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None): parent, concrete=concrete, ) - # if forth_stash is not None: - # forth_obj.go_to(temp) + if forth_obj is not None: + forth_obj.pop_active_node() + return temp_var if context.get("in_TBranch", False): - # AwkwardForth testing: test_0637's 01,02,05,08,09,11,12,13,15,16,29,35,38,39,44,45,46,47,49,50,52,56 + # AwkwardForth testing A: test_0637's 01,02,05,08,09,11,12,13,15,16,29,35,38,39,44,45,46,47,49,50,52,56 if self._num_bytes is None and self._instance_version != self.class_version: self._instance_version = None cursor = self._cursor - if forth_stash is not None and not context["cancel_forth"]: + if forth_obj is not None: forth_stash._pre_code.pop(-1) elif self._instance_version == 0: - if forth_stash is not None: - forth_stash.add_to_pre("4 stream skip\n") + if forth_obj is not None: + forth_stash.pre_code.append("4 stream skip\n") cursor.skip(4) if context.get("reading", True): self.hook_before_read_members( chunk=chunk, cursor=cursor, context=context, file=file ) - if forth_stash is not None: - forth_obj.add_node( - "model828", - forth_stash.get_attrs(), - "i64", - 1, - {}, - ) - + if forth_obj is not None: + key = uproot._awkwardforth.get_first_key_number(context) + forth_stash.name = f"start-of-model {key}" + forth_obj.add_node(forth_stash) + forth_obj.push_active_node(forth_stash) self.read_members(chunk, cursor, context, file) + if forth_obj is not None: + forth_obj.pop_active_node() + self.hook_after_read_members( chunk=chunk, cursor=cursor, context=context, file=file ) @@ -1307,10 +1304,6 @@ def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None): """ import uproot.deserialization - forth_stash = uproot._awkward_forth.forth_stash(context) - - if forth_stash is not None: - forth_obj = forth_stash.get_gen_obj() # Ignores context["reading"], because otherwise, there would be nothing to do. start_index = cursor._index ( @@ -1320,17 +1313,18 @@ def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None): ) = uproot.deserialization.numbytes_version(chunk, cursor, context, move=False) versioned_cls = cls.class_of_version(version) - bytes_skipped = cursor._index - start_index - if forth_stash is not None: - # raise NotImplementedError - forth_stash.add_to_pre(f"{bytes_skipped} stream skip \n") - forth_obj.add_node( - "Model1319", - forth_stash.get_attrs(), - "i64", - 1, - {}, + + forth_obj = uproot._awkwardforth.get_forth_obj(context) + if forth_obj is not None: + forth_stash = uproot._awkwardforth.Node( + f"dispatch-by-version {uproot._awkwardforth.get_first_key_number(context)}", + form_details={"offsets": "i64"}, ) + bytes_skipped = cursor._index - start_index + forth_stash.pre_code.append(f"{bytes_skipped} stream skip \n") + + forth_obj.add_node(forth_stash) + forth_obj.push_active_node(forth_stash) if versioned_cls is not None: pass @@ -1352,7 +1346,6 @@ def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None): ) # versioned_cls.read starts with numbytes_version again because move=False (above) - # if forth_stash is not None: temp_var = cls.postprocess( versioned_cls.read( chunk, cursor, context, file, selffile, parent, concrete=concrete @@ -1362,10 +1355,10 @@ def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None): context, file, ) - # if forth_stash is not None: - # if "no_go_to" not in context.keys(): - # raise NotImplementedError - # forth_obj.go_to(temp_node) + + if forth_obj is not None: + forth_obj.pop_active_node() + return temp_var @classmethod diff --git a/src/uproot/models/RNTuple.py b/src/uproot/models/RNTuple.py index cd0f2dfda..53b64e29f 100644 --- a/src/uproot/models/RNTuple.py +++ b/src/uproot/models/RNTuple.py @@ -58,6 +58,8 @@ def keys(self): return self._keys def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/models/TArray.py b/src/uproot/models/TArray.py index 5c4e227fd..d45cfe29f 100644 --- a/src/uproot/models/TArray.py +++ b/src/uproot/models/TArray.py @@ -26,7 +26,8 @@ def read_numbytes_version(self, chunk, cursor, context): pass def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/models/TAtt.py b/src/uproot/models/TAtt.py index 04a92425b..4d8e3459f 100644 --- a/src/uproot/models/TAtt.py +++ b/src/uproot/models/TAtt.py @@ -20,7 +20,8 @@ class Model_TAttLine_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -85,6 +86,8 @@ class Model_TAttLine_v2(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -179,6 +182,8 @@ class Model_TAttFill_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -237,6 +242,8 @@ class Model_TAttFill_v2(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -323,6 +330,8 @@ class Model_TAttMarker_v2(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -413,6 +422,8 @@ class Model_TAttAxis_v4(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -632,6 +643,8 @@ class Model_TAtt3D_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/models/TBasket.py b/src/uproot/models/TBasket.py index e65e5284b..0a0fb02f6 100644 --- a/src/uproot/models/TBasket.py +++ b/src/uproot/models/TBasket.py @@ -214,7 +214,8 @@ def read_numbytes_version(self, chunk, cursor, context): pass def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() assert isinstance(self._parent, uproot.behaviors.TBranch.TBranch) self._basket_num = context.get("basket_num") diff --git a/src/uproot/models/TBranch.py b/src/uproot/models/TBranch.py index fca8d71f9..9f7466ebf 100644 --- a/src/uproot/models/TBranch.py +++ b/src/uproot/models/TBranch.py @@ -42,7 +42,8 @@ class Model_TBranch_v10(uproot.behaviors.TBranch.TBranch, uproot.model.Versioned behaviors = (uproot.behaviors.TBranch.TBranch,) def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -170,6 +171,8 @@ class Model_TBranch_v11(uproot.behaviors.TBranch.TBranch, uproot.model.Versioned behaviors = (uproot.behaviors.TBranch.TBranch,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -299,6 +302,8 @@ class Model_TBranch_v12(uproot.behaviors.TBranch.TBranch, uproot.model.Versioned behaviors = (uproot.behaviors.TBranch.TBranch,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -429,6 +434,8 @@ class Model_TBranch_v13(uproot.behaviors.TBranch.TBranch, uproot.model.Versioned behaviors = (uproot.behaviors.TBranch.TBranch,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -588,6 +595,8 @@ class Model_TBranchElement_v8( behaviors = (uproot.behaviors.TBranch.TBranch,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -660,6 +669,8 @@ class Model_TBranchElement_v9( behaviors = (uproot.behaviors.TBranch.TBranch,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -732,6 +743,8 @@ class Model_TBranchElement_v10( behaviors = (uproot.behaviors.TBranch.TBranch,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -813,6 +826,8 @@ class Model_TBranchObject_v1( behaviors = (uproot.behaviors.TBranch.TBranch,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/models/TClonesArray.py b/src/uproot/models/TClonesArray.py index b77939ae7..9ed579b37 100644 --- a/src/uproot/models/TClonesArray.py +++ b/src/uproot/models/TClonesArray.py @@ -18,7 +18,8 @@ class Model_TClonesArray(uproot.model.VersionedModel, Sequence): """ def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( "memberwise serialization of {}\nin file {}".format( diff --git a/src/uproot/models/TDatime.py b/src/uproot/models/TDatime.py index 1bd7cfc93..dd0461572 100644 --- a/src/uproot/models/TDatime.py +++ b/src/uproot/models/TDatime.py @@ -10,7 +10,6 @@ import numpy import uproot -import uproot._awkward_forth import uproot.behaviors.TDatime _tdatime_format1 = struct.Struct(">I") @@ -25,17 +24,12 @@ def read_numbytes_version(self, chunk, cursor, context): pass def read_members(self, chunk, cursor, context, file): - forth_stash = uproot._awkward_forth.forth_stash(context) - if forth_stash is not None: - forth_obj = forth_stash.get_gen_obj() - key = forth_obj.get_keys(1) - form_key = f"node{key}-data" - forth_stash.add_to_header(f"output node{key}-data int32\n") - forth_stash.add_to_pre(f"stream !I-> node{key}-data\n") - form_key = f"node{key}-data" - if forth_obj.should_add_form(): - forth_obj.add_form_key(form_key) - temp_aform = { + forth_obj = uproot._awkwardforth.get_forth_obj(context) + if forth_obj is not None: + key = uproot._awkwardforth.get_first_key_number(context) + forth_stash = uproot._awkwardforth.Node( + f"node{key} TDatime :prebuilt", + form_details={ "class": "RecordArray", "contents": { "fDatime": { @@ -45,16 +39,12 @@ def read_members(self, chunk, cursor, context, file): } }, "parameters": {"__record__": "TDatime"}, - } - forth_obj.add_form(temp_aform) - temp_form = forth_obj.add_node( - f"node{key}", - forth_stash.get_attrs(), - "i64", - 0, - None, + }, ) - forth_obj.go_to(temp_form) + forth_stash.header_code.append(f"output node{key}-data int32\n") + forth_stash.pre_code.append(f"stream !I-> node{key}-data\n") + forth_obj.add_node(forth_stash) + forth_obj.set_active_node(forth_stash) self._members["fDatime"] = cursor.field(chunk, _tdatime_format1, context) @classmethod diff --git a/src/uproot/models/TGraph.py b/src/uproot/models/TGraph.py index 5b5d489f0..24b288031 100644 --- a/src/uproot/models/TGraph.py +++ b/src/uproot/models/TGraph.py @@ -35,7 +35,8 @@ class Model_TGraph_v4(uproot.behaviors.TGraph.TGraph, uproot.model.VersionedMode behaviors = (uproot.behaviors.TGraph.TGraph,) def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( "memberwise serialization of {}\nin file {}".format( @@ -362,6 +363,8 @@ class Model_TGraphErrors_v3( behaviors = (uproot.behaviors.TGraphErrors.TGraphErrors,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( "memberwise serialization of {}\nin file {}".format( @@ -542,6 +545,8 @@ class Model_TGraphAsymmErrors_v3( behaviors = (uproot.behaviors.TGraphAsymmErrors.TGraphAsymmErrors,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( "memberwise serialization of {}\nin file {}".format( diff --git a/src/uproot/models/TH.py b/src/uproot/models/TH.py index 39d682b74..ab5683ba9 100644 --- a/src/uproot/models/TH.py +++ b/src/uproot/models/TH.py @@ -150,7 +150,8 @@ class Model_TAxis_v10(uproot.behaviors.TAxis.TAxis, uproot.model.VersionedModel) """ def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -455,6 +456,8 @@ class Model_TH1_v8(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -1028,6 +1031,8 @@ class Model_TH2_v5(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -1190,6 +1195,8 @@ class Model_TH3_v6(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -1422,6 +1429,8 @@ class Model_TH1C_v3(uproot.behaviors.TH1.TH1, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -1583,6 +1592,8 @@ class Model_TH1D_v3(uproot.behaviors.TH1.TH1, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -1739,6 +1750,8 @@ class Model_TH1F_v3(uproot.behaviors.TH1.TH1, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -1895,6 +1908,8 @@ class Model_TH1I_v3(uproot.behaviors.TH1.TH1, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -2056,6 +2071,8 @@ class Model_TH1S_v3(uproot.behaviors.TH1.TH1, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -2217,6 +2234,8 @@ class Model_TH2C_v4(uproot.behaviors.TH2.TH2, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -2379,6 +2398,8 @@ class Model_TH2D_v4(uproot.behaviors.TH2.TH2, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -2536,6 +2557,8 @@ class Model_TH2F_v4(uproot.behaviors.TH2.TH2, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -2698,6 +2721,8 @@ class Model_TH2I_v4(uproot.behaviors.TH2.TH2, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -2860,6 +2885,8 @@ class Model_TH2S_v4(uproot.behaviors.TH2.TH2, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -3022,6 +3049,8 @@ class Model_TH3C_v4(uproot.behaviors.TH3.TH3, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -3185,6 +3214,8 @@ class Model_TH3D_v4(uproot.behaviors.TH3.TH3, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -3343,6 +3374,8 @@ class Model_TH3F_v4(uproot.behaviors.TH3.TH3, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -3506,6 +3539,8 @@ class Model_TH3I_v4(uproot.behaviors.TH3.TH3, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -3669,6 +3704,8 @@ class Model_TH3S_v4(uproot.behaviors.TH3.TH3, uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -3834,6 +3871,8 @@ class Model_TProfile_v7( """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -4072,6 +4111,8 @@ class Model_TProfile2D_v8( """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -4312,6 +4353,8 @@ class Model_TProfile3D_v8( """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/models/THashList.py b/src/uproot/models/THashList.py index dd12dff54..4f1a7c94c 100644 --- a/src/uproot/models/THashList.py +++ b/src/uproot/models/THashList.py @@ -17,7 +17,8 @@ def read_numbytes_version(self, chunk, cursor, context): pass def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/models/TLeaf.py b/src/uproot/models/TLeaf.py index dbf31df0c..38ba0648e 100644 --- a/src/uproot/models/TLeaf.py +++ b/src/uproot/models/TLeaf.py @@ -25,7 +25,8 @@ class Model_TLeaf_v2(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -91,6 +92,8 @@ class Model_TLeafO_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -148,6 +151,8 @@ class Model_TLeafB_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -205,6 +210,8 @@ class Model_TLeafS_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -262,6 +269,8 @@ class Model_TLeafI_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -319,6 +328,8 @@ class Model_TLeafG_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -364,6 +375,8 @@ class Model_TLeafL_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -421,6 +434,8 @@ class Model_TLeafF_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -478,6 +493,8 @@ class Model_TLeafD_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -535,6 +552,8 @@ class Model_TLeafC_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -590,6 +609,8 @@ class Model_TLeafF16_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -630,6 +651,8 @@ class Model_TLeafD32_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -673,6 +696,8 @@ class Model_TLeafElement_v1(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/models/TList.py b/src/uproot/models/TList.py index 906769125..20cc013cf 100644 --- a/src/uproot/models/TList.py +++ b/src/uproot/models/TList.py @@ -19,7 +19,8 @@ class Model_TList(uproot.model.Model, Sequence): """ def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/models/TMatrixT.py b/src/uproot/models/TMatrixT.py index 80a2666a8..91b0a0252 100644 --- a/src/uproot/models/TMatrixT.py +++ b/src/uproot/models/TMatrixT.py @@ -22,7 +22,8 @@ class Model_TMatrixTSym_3c_double_3e__v5(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( "memberwise serialization of {}\nin file {}".format( diff --git a/src/uproot/models/TNamed.py b/src/uproot/models/TNamed.py index a85f4a393..96b303ef9 100644 --- a/src/uproot/models/TNamed.py +++ b/src/uproot/models/TNamed.py @@ -16,7 +16,8 @@ class Model_TNamed(uproot.model.Model): """ def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/models/TObjArray.py b/src/uproot/models/TObjArray.py index 41fc770ee..9c1b128dd 100644 --- a/src/uproot/models/TObjArray.py +++ b/src/uproot/models/TObjArray.py @@ -28,7 +28,8 @@ class Model_TObjArray(uproot.model.Model, Sequence): """ def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -110,6 +111,8 @@ class Model_TObjArrayOfTBaskets(Model_TObjArray): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/models/TObjString.py b/src/uproot/models/TObjString.py index 70444c32d..58f6f2de8 100644 --- a/src/uproot/models/TObjString.py +++ b/src/uproot/models/TObjString.py @@ -27,7 +27,8 @@ class Model_TObjString(uproot.model.Model, str): writable = True def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/models/TObject.py b/src/uproot/models/TObject.py index db4cfaf72..fa3ca8888 100644 --- a/src/uproot/models/TObject.py +++ b/src/uproot/models/TObject.py @@ -5,7 +5,6 @@ """ from __future__ import annotations -import json import struct import numpy @@ -25,11 +24,9 @@ def read_numbytes_version(self, chunk, cursor, context): pass def read_members(self, chunk, cursor, context, file): - forth_stash = uproot._awkward_forth.forth_stash(context) + forth_obj = uproot._awkwardforth.get_forth_obj(context) start_index = cursor._index - if forth_stash is not None: - forth_obj = forth_stash.get_gen_obj() - # raise NotImplementedError + if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -47,19 +44,16 @@ def read_members(self, chunk, cursor, context, file): if self._members["@fBits"] & uproot.const.kIsReferenced: cursor.skip(2) self._members["@fBits"] = int(self._members["@fBits"]) - if forth_stash is not None: + + if forth_obj is not None: + key = uproot._awkwardforth.get_first_key_number(context) skip_length = cursor._index - start_index - forth_stash.add_to_pre(f"{skip_length} stream skip \n") - if forth_obj.should_add_form(): - temp_aform = '{"class": "RecordArray", "contents":[], "parameters": {"__record__": "TObject"}}' - forth_obj.add_form(json.loads(temp_aform)) - forth_obj.add_node( - "TObjext", - forth_stash.get_attrs(), - "i64", - 0, - {}, + forth_stash = uproot._awkwardforth.Node( + f"node{key} TObject", form_details={"offsets": "i64"} ) + forth_stash.pre_code.append(f"{skip_length} stream skip \n") + forth_obj.add_node(forth_stash) + forth_obj.set_active_node(forth_stash) writable = True diff --git a/src/uproot/models/TRef.py b/src/uproot/models/TRef.py index 0e7bd04c7..960046cb4 100644 --- a/src/uproot/models/TRef.py +++ b/src/uproot/models/TRef.py @@ -5,7 +5,6 @@ """ from __future__ import annotations -import json import struct from collections.abc import Sequence @@ -118,55 +117,77 @@ def name(self): return self._members["fName"] def read_members(self, chunk, cursor, context, file): - forth_stash = uproot._awkward_forth.forth_stash(context) - if forth_stash is not None: - forth_obj = forth_stash.get_gen_obj() - # raise NotImplementedError + forth_obj = uproot._awkwardforth.get_forth_obj(context) if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} in file {self.file.file_path}""" ) - if forth_stash is not None: - form_keys = forth_obj.get_keys(6) - - forth_stash.add_to_pre("10 stream skip\n") - forth_stash.add_to_pre( - f"stream !B-> stack dup 255 = if drop stream !I-> stack then dup node{form_keys[1]}-offsets +<- stack stream #!B-> node{form_keys[2]}-data\n" + if forth_obj is not None: + key_number = uproot._awkwardforth.get_first_key_number(context) + keys = [key_number + i for i in range(6)] + forth_stash = uproot._awkwardforth.Node( + f"node{keys[0]} TRef :prebuilt", + form_details={ + "class": "RecordArray", + "contents": { + "fName": { + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "NumpyArray", + "primitive": "uint8", + "inner_shape": [], + "parameters": {"__array__": "char"}, + "form_key": f"node{keys[2]}", + }, + "parameters": {"__array__": "string"}, + "form_key": f"node{keys[1]}", + }, + "fSize": { + "class": "NumpyArray", + "primitive": "int32", + "inner_shape": [], + "parameters": {}, + "form_key": f"node{keys[3]}", + }, + "refs": { + "class": "ListOffsetArray", + "offsets": "i64", + "content": { + "class": "NumpyArray", + "primitive": "int32", + "inner_shape": [], + "parameters": {}, + "form_key": f"node{keys[5]}", + }, + "parameters": {}, + "form_key": f"node{keys[4]}", + }, + }, + "parameters": {"__record__": "TRefArray"}, + "form_key": f"node{keys[0]}", + }, ) - forth_stash.add_to_pre( - f"stream !I-> stack dup node{form_keys[3]}-data <- stack\n" + forth_stash.pre_code.append("10 stream skip\n") + forth_stash.pre_code.append( + f"stream !B-> stack dup 255 = if drop stream !I-> stack then dup node{keys[1]}-offsets +<- stack stream #!B-> node{keys[2]}-data\n" ) - forth_stash.add_to_pre("6 stream skip\n") - forth_stash.add_to_pre( - f"dup node{form_keys[4]}-offsets +<- stack stream #!I-> node{form_keys[5]}-data\n" + forth_stash.pre_code.append( + f"stream !I-> stack dup node{keys[3]}-data <- stack\n" ) - keys = [ - f"node{form_keys[1]}-offsets", - f"node{form_keys[3]}-data", - f"node{form_keys[4]}-offsets", - f"node{form_keys[2]}-data", - f"node{form_keys[5]}-data", - ] - if forth_obj.should_add_form(): - for elem in keys: - forth_obj.add_form_key(elem) - temp_aform = f'{{"class": "RecordArray", "contents": {{"fName": {{"class": "ListOffsetArray", "offsets": "i64", "content": {{"class": "NumpyArray", "primitive": "uint8", "inner_shape": [], "parameters": {{"__array__": "char"}}, "form_key": "node{form_keys[2]}"}}, "parameters": {{"__array__": "string"}}, "form_key": "node{form_keys[1]}"}}, "fSize": {{"class": "NumpyArray", "primitive": "int32", "inner_shape": [], "parameters": {{}}, "form_key": "node{form_keys[3]}"}}, "refs": {{"class": "ListOffsetArray", "offsets": "i64", "content": {{"class": "NumpyArray", "primitive": "int32", "inner_shape": [], "parameters": {{}}, "form_key": "node{form_keys[5]}"}}, "parameters": {{}}, "form_key": "node{form_keys[4]}"}}}}, "parameters": {{"__record__": "TRefArray"}}, "form_key": "node{form_keys[0]}"}}' - forth_obj.add_form(json.loads(temp_aform)) - forth_stash.add_to_header( - f"output node{form_keys[1]}-offsets int64\noutput node{form_keys[2]}-data uint8\noutput node{form_keys[3]}-data int32\noutput node{form_keys[4]}-offsets int64\noutput node{form_keys[5]}-data int32\n" - ) - forth_stash.add_to_init( - f"0 node{form_keys[1]}-offsets <- stack\n0 node{form_keys[4]}-offsets <- stack\n" - ) - forth_obj.add_node( - f"node{form_keys[0]}", - forth_stash.get_attrs(), - "i64", - 1, - None, + forth_stash.pre_code.append("6 stream skip\n") + forth_stash.pre_code.append( + f"dup node{keys[4]}-offsets +<- stack stream #!I-> node{keys[5]}-data\n" ) - + forth_stash.header_code.append( + f"output node{keys[1]}-offsets int64\noutput node{keys[2]}-data uint8\noutput node{keys[3]}-data int32\noutput node{keys[4]}-offsets int64\noutput node{keys[5]}-data int32\n" + ) + forth_stash.init_code.append( + f"0 node{keys[1]}-offsets <- stack\n0 node{keys[4]}-offsets <- stack\n" + ) + forth_obj.add_node(forth_stash) + forth_obj.set_active_node(forth_stash) cursor.skip(10) self._members["fName"] = cursor.string(chunk, context) self._members["fSize"] = cursor.field(chunk, _trefarray_format1, context) diff --git a/src/uproot/models/TString.py b/src/uproot/models/TString.py index aa3024f1d..9a6a0d324 100644 --- a/src/uproot/models/TString.py +++ b/src/uproot/models/TString.py @@ -6,7 +6,7 @@ from __future__ import annotations import uproot -import uproot._awkward_forth +import uproot._awkwardforth class Model_TString(uproot.model.Model, str): @@ -20,23 +20,18 @@ def read_numbytes_version(self, chunk, cursor, context): pass def read_members(self, chunk, cursor, context, file): - forth_stash = uproot._awkward_forth.forth_stash(context) - if forth_stash is not None: - forth_obj = forth_stash.get_gen_obj() - keys = forth_obj.get_keys(2) - offsets_num = keys[0] - data_num = keys[1] if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} in file {self.file.file_path}""" ) - if forth_stash is not None: - forth_stash.add_to_pre( - f" stream !B-> stack dup 255 = if drop stream !I-> stack then dup node{offsets_num}-offsets +<- stack stream #!B-> node{data_num}-data\n" - ) - if forth_obj.should_add_form(): - temp_aform = { + forth_obj = uproot._awkwardforth.get_forth_obj(context) + if forth_obj is not None: + offsets_num = uproot._awkwardforth.get_first_key_number(context) + data_num = offsets_num + 1 + nested_forth_stash = uproot._awkwardforth.Node( + f"node{offsets_num} TString", + form_details={ "class": "ListOffsetArray", "offsets": "i64", "content": { @@ -48,27 +43,19 @@ def read_members(self, chunk, cursor, context, file): }, "parameters": {"__array__": "string"}, "form_key": f"node{offsets_num}", - } - forth_obj.add_form(temp_aform) - - form_keys = [ - f"node{data_num}-data", - f"node{offsets_num}-offsets", - ] - for elem in form_keys: - forth_obj.add_form_key(elem) - forth_stash.add_to_header( + }, + ) + nested_forth_stash.pre_code.append( + f" stream !B-> stack dup 255 = if drop stream !I-> stack then dup node{offsets_num}-offsets +<- stack stream #!B-> node{data_num}-data\n" + ) + nested_forth_stash.header_code.append( f"output node{offsets_num}-offsets int64\noutput node{data_num}-data uint8\n" ) - forth_stash.add_to_init(f"0 node{offsets_num}-offsets <- stack\n") - temp_form = forth_obj.add_node( - f"node{offsets_num}", - forth_stash.get_attrs(), - "i64", - 0, - None, + nested_forth_stash.init_code.append( + f"0 node{offsets_num}-offsets <- stack\n" ) - forth_obj.go_to(temp_form) + forth_obj.add_node(nested_forth_stash) + self._data = cursor.string(chunk, context) def postprocess(self, chunk, cursor, context, file): diff --git a/src/uproot/models/TTable.py b/src/uproot/models/TTable.py index f3723cfec..229a22456 100644 --- a/src/uproot/models/TTable.py +++ b/src/uproot/models/TTable.py @@ -25,7 +25,8 @@ class Model_TDataSet(uproot.model.Model): """ def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -130,6 +131,8 @@ class Model_TTableDescriptor_v4(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -188,6 +191,8 @@ class Model_TTable_v4(uproot.model.VersionedModel): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/models/TTree.py b/src/uproot/models/TTree.py index 75e08188b..90342cf6c 100644 --- a/src/uproot/models/TTree.py +++ b/src/uproot/models/TTree.py @@ -46,7 +46,8 @@ class Model_TTree_v16(uproot.behaviors.TTree.TTree, uproot.model.VersionedModel) behaviors = (uproot.behaviors.TTree.TTree,) def read_members(self, chunk, cursor, context, file): - context["cancel_forth"] = True + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -197,6 +198,8 @@ class Model_TTree_v17(uproot.behaviors.TTree.TTree, uproot.model.VersionedModel) behaviors = (uproot.behaviors.TTree.TTree,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -348,6 +351,8 @@ class Model_TTree_v18(uproot.behaviors.TTree.TTree, uproot.model.VersionedModel) behaviors = (uproot.behaviors.TTree.TTree,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -505,6 +510,8 @@ class Model_TTree_v19(uproot.behaviors.TTree.TTree, uproot.model.VersionedModel) behaviors = (uproot.behaviors.TTree.TTree,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -678,6 +685,8 @@ class Model_TTree_v20(uproot.behaviors.TTree.TTree, uproot.model.VersionedModel) behaviors = (uproot.behaviors.TTree.TTree,) def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -883,6 +892,8 @@ class Model_ROOT_3a3a_TIOFeatures(uproot.model.Model): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} @@ -905,6 +916,8 @@ class Model_TTree_NumEntries(uproot.model.Model): """ def read_members(self, chunk, cursor, context, file): + if uproot._awkwardforth.get_forth_obj(context) is not None: + raise uproot.interpretation.objects.CannotBeForth() if self.is_memberwise: raise NotImplementedError( f"""memberwise serialization of {type(self).__name__} diff --git a/src/uproot/streamers.py b/src/uproot/streamers.py index 56c522fe5..3cc27905f 100644 --- a/src/uproot/streamers.py +++ b/src/uproot/streamers.py @@ -13,7 +13,7 @@ import numpy import uproot -import uproot._awkward_forth +import uproot._awkwardforth as af COUNT_NAMES = [] @@ -210,19 +210,18 @@ def class_code(self): COUNT_NAMES.append(element.member("fCountName")) read_members = [ " def read_members(self, chunk, cursor, context, file):", - " import uproot._awkward_forth", " if self.is_memberwise:", " raise NotImplementedError(", ' f"memberwise serialization of {type(self).__name__}\\nin file {self.file.file_path}"', " )", + " forth_obj = af.get_forth_obj(context)", + " if forth_obj is not None:", + " key_number = af.get_first_key_number(context)", + " forth_stash = af.Node(f'read-members {key_number}')", + " key_number += 1", + " forth_obj.add_node(forth_stash)", + " forth_obj.set_active_node(forth_stash)", ] - read_members.append( - """ - forth_stash = uproot._awkward_forth.forth_stash(context) - if forth_stash is not None: - forth_obj = forth_stash.get_gen_obj() - content = {}""" - ) read_member_n = [ " def read_member_n(self, chunk, cursor, context, file, member_index):" ] @@ -230,7 +229,7 @@ def class_code(self): " @classmethod", " def strided_interpretation(cls, file, header=False, tobject_header=True, breadcrumbs=(), original=None):", " if cls in breadcrumbs:", - " raise uproot.interpretation.objects.CannotBeStrided('classes that can contain members of the same type cannot be strided because the depth of instances is unbounded')", + " raise CannotBeStrided('classes that can contain members of the same type cannot be strided because the depth of instances is unbounded')", " breadcrumbs = breadcrumbs + (cls,)", " members = [(None, None)]", " if header:", @@ -242,7 +241,7 @@ def class_code(self): " def awkward_form(cls, file, context):", " from awkward.forms import NumpyForm, ListOffsetForm, RegularForm, RecordForm", " if cls in context['breadcrumbs']:", - " raise uproot.interpretation.objects.CannotBeAwkward('classes that can contain members of the same type cannot be Awkward Arrays because the depth of instances is unbounded')", + " raise CannotBeAwkward('classes that can contain members of the same type cannot be Awkward Arrays because the depth of instances is unbounded')", " context = context.copy()", " context['breadcrumbs'] = context['breadcrumbs'] + (cls,)", " contents = {}", @@ -258,6 +257,7 @@ def class_code(self): base_names_versions = [] member_names = [] class_flags = {} + for i in range(len(self._members["fElements"])): self._members["fElements"][i].class_code( self, @@ -276,17 +276,14 @@ def class_code(self): member_names, class_flags, ) + read_members.extend( [ - " if forth_stash is not None:", - " if forth_obj.should_add_form():", - f" forth_obj.add_form({{'class': 'RecordArray', 'contents': content, 'parameters': {{'__record__': {self.name!r}}}}}, len(content))", - " temp = forth_obj.add_node('dynamic', forth_stash.get_attrs(), \"i64\", 0, None)", + " if forth_obj is not None:", + f" forth_stash.form_details = {{'class': 'RecordArray', 'parameters': {{'__record__': {self.name!r}}}}}", ] ) - if len(read_members) == 1: - # untested as of PR #629 - read_members.append(" pass") + if len(read_member_n) == 1: read_member_n.append(" pass") @@ -333,9 +330,7 @@ def class_code(self): # std::pair cannot be strided if self.name.startswith("pair<"): strided_interpretation = strided_interpretation[:2] - strided_interpretation.append( - " raise uproot.interpretation.objects.CannotBeStrided('std::pair')" - ) + strided_interpretation.append(" raise CannotBeStrided('std::pair')") classname = uproot.model.classname_encode(self.name, self.class_version) return "\n".join( @@ -415,7 +410,6 @@ def read_members(self, chunk, cursor, context, file): concrete=self.concrete, ) ) - context["cancel_forth"] = True self._bases[0]._members["fName"] = _canonical_typename( self._bases[0]._members["fName"] ) @@ -535,7 +529,6 @@ def read_members(self, chunk, cursor, context, file): concrete=self.concrete, ) ) - context["cancel_forth"] = True ( self._members["fType"], self._members["fSize"], @@ -637,21 +630,20 @@ def class_code( # untested as of PR #629 read_members.extend( [ - ' context["cancel_forth"] = True', - f" raise uproot.deserialization.DeserializationError('not implemented: class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}', chunk, cursor, context, file.file_path)", + f" raise DeserializationError('not implemented: class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}', chunk, cursor, context, file.file_path)", ] ) read_member_n.append( - f" raise uproot.deserialization.DeserializationError('not implemented: class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}', chunk, cursor, context, file.file_path)" + f" raise DeserializationError('not implemented: class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}', chunk, cursor, context, file.file_path)" ) strided_interpretation.append( - f" raise uproot.interpretation.objects.CannotBeStrided('not implemented: class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}')" + f" raise CannotBeStrided('not implemented: class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}')" ) awkward_form.append( - f" raise uproot.interpretation.objects.CannotBeAwkward('not implemented: class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}')" + f" raise CannotBeAwkward('not implemented: class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}')" ) @@ -708,34 +700,20 @@ def class_code( ): read_member_n.append(f" if member_index == {i}:") - # AwkwardForth testing: test_0637's 01,02,08,09,11,12,13,15,16,29,38,45,46,49,50 + # AwkwardForth testing B: test_0637's 01,02,08,09,11,12,13,15,16,29,38,45,46,49,50 read_members.extend( [ - " if forth_stash is not None:", - " temp_node, temp_node_top, temp_form, temp_form_top, temp_prev_form = forth_obj.replace_form_and_model(None, {'name': 'TOP', 'content': {}})", - f" self._bases.append(c({self.name!r}, {self.base_version!r}).read(chunk, cursor, context, file, self._file, self._parent, concrete=self.concrete))", - " if forth_stash is not None and not context['cancel_forth']:", - " temp_prev_form1 = forth_obj.prev_form", - " temp_form1 = forth_obj.top_form", - " temp_model1 = forth_obj.top_node", - " temp_model_ref = forth_obj.awkward_model", - " forth_obj.awkward_model = temp_node", - " forth_obj.top_node = temp_node_top", - " forth_obj.aform = temp_form", - " forth_obj.prev_form = temp_prev_form", - " forth_obj.top_form = temp_form_top", - " temp_model1 = temp_model1['content']", - " forth_obj.add_node_whole(temp_model1, temp_model_ref)", - " content.update(temp_form1['contents'])", - " forth_obj.enable_adding()", + " if forth_obj is not None:", + " key = key_number ; key_number += 1", + " nested_forth_stash = af.Node(f'base-class {key}')", + " forth_obj.add_node(nested_forth_stash)", + " forth_obj.push_active_node(nested_forth_stash)", + f" self._bases.append(c({self.name!r}, {self.base_version!r}).read(chunk, cursor, af.add_to_path(forth_obj, context, af.SpecialPathItem(f'base-class {{len(self._bases)}}')), file, self._file, self._parent, concrete=self.concrete))", + " if forth_obj is not None:", + " forth_obj.pop_active_node()", ] ) - ### FIXME: what is this commented-out code for? - # read_members.append( - # " if forth_stash is not None:\n temp_form = forth_obj.get_temp_form_top()\n content.update(temp_form['contents'])\n forth_obj.set_dummy_none(temp_top_dummy, temp_dummy, temp_top_flag)\n" - # ) - read_member_n.append( f" self._bases.append(c({self.name!r}, {self.base_version!r}).read(chunk, cursor, context, file, self._file, self._parent, concrete=self.concrete))" ) @@ -836,6 +814,8 @@ def class_code( # untested as of PR #629 read_members.extend( [ + " if forth_obj is not None:", + " raise CannotBeForth()", " if context.get('speedbump', True):", " if cursor.bytes(chunk, 1, context)[0] == 2:", " tmp = numpy.dtype('>i8')", @@ -850,34 +830,29 @@ def class_code( ) else: - # AwkwardForth testing: test_0637's 29,44,56 + # AwkwardForth testing C: test_0637's 29,44,56 read_members.extend( [ " if context.get('speedbump', True):", " cursor.skip(1)", - " if forth_stash is not None:", - " forth_stash.add_to_pre('1 stream skip \\n')", - " if forth_stash is not None:", - " key = forth_obj.get_keys(1)", - " key2 = forth_obj.get_keys(1)", - ' form_key = f"node{key}-data"', - ' form_key2 = f"node{key2}-offsets"', - f' forth_stash.add_to_header(f"output node{{key}}-data {{uproot._awkward_forth.convert_dtype(uproot._awkward_forth.symbol_dict[self._dtype{len(dtypes)}])}}\\n")', - ' forth_stash.add_to_header(f"output node{key2}-offsets int64\\n")', - ' forth_stash.add_to_init(f"0 node{key2}-offsets <- stack\\n")', - f' content[{self.name!r}] = {{"class": "ListOffsetArray", "offsets": "i64", "content": {{ "class": "NumpyArray", "primitive": f"{{uproot._awkward_forth.convert_dtype(uproot._awkward_forth.symbol_dict[self._dtype{len(dtypes)}])}}", "inner_shape": [], "parameters": {{}}, "form_key": f"node{{key}}"}}, "form_key": f"node{{key2}}"}}', - f' forth_stash.add_to_pre(f" var_{self.count_name} @ dup node{{key2}}-offsets +<- stack \\n stream #!{{uproot._awkward_forth.symbol_dict[self._dtype{len(dtypes)}]}}-> node{{key}}-data\\n")', - " if forth_obj.should_add_form():", - " forth_obj.add_form_key(form_key)", - " forth_obj.add_form_key(form_key2)", + " if forth_obj is not None:", + " key = key_number ; key_number += 1", + " key2 = key_number ; key_number += 1", + f' nested_forth_stash = af.Node(f"node{{key}}", field_name={self.name!r}, form_details={{"class": "ListOffsetArray", "offsets": "i64", "content": {{ "class": "NumpyArray", "primitive": f"{{af.struct_to_dtype_name[af.dtype_to_struct[self._dtype{len(dtypes)}]]}}", "inner_shape": [], "parameters": {{}}, "form_key": f"node{{key}}"}}, "form_key": f"node{{key2}}"}})', + " if context.get('speedbump', True):", + " nested_forth_stash.pre_code.append('1 stream skip \\n')", + f' nested_forth_stash.header_code.append(f"output node{{key}}-data {{af.struct_to_dtype_name[af.dtype_to_struct[self._dtype{len(dtypes)}]]}}\\n")', + ' nested_forth_stash.header_code.append(f"output node{key2}-offsets int64\\n")', + ' nested_forth_stash.init_code.append(f"0 node{key2}-offsets <- stack\\n")', + f' nested_forth_stash.pre_code.append(f" var_{self.count_name} @ dup node{{key2}}-offsets +<- stack \\n stream #!{{af.dtype_to_struct[self._dtype{len(dtypes)}]}}-> node{{key}}-data\\n")', + " forth_obj.add_node(nested_forth_stash)", ] ) + read_member_n.extend( [ " if context.get('speedbump', True):", " cursor.skip(1)", - " if forth_stash is not None:", - " forth_stash.add_to_pre('1 stream skip \\n')", ] ) @@ -889,7 +864,7 @@ def class_code( ) strided_interpretation.append( - f" raise uproot.interpretation.objects.CannotBeStrided('class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}')" + f" raise CannotBeStrided('class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}')" ) awkward_form.append( @@ -954,7 +929,8 @@ def class_code( # untested as of PR #629 read_members.extend( [ - ' context["cancel_forth"] = True', + " if forth_obj is not None:", + " raise CannotBeForth()", f" self._members[{self.name!r}] = cursor.double32(chunk, context)", ] ) @@ -966,7 +942,8 @@ def class_code( # untested as of PR #629 read_members.extend( [ - ' context["cancel_forth"] = True', + " if forth_obj is not None:", + " raise CannotBeForth()", f" self._members[{self.name!r}] = cursor.float16(chunk, 12, context)", ] ) @@ -993,50 +970,44 @@ def class_code( or elements[i + 1].array_length != 0 ): if len(fields[-1]) == 1: - # AwkwardForth testing: test_0637's 01,02,29,38,44,56 + # AwkwardForth testing D: test_0637's 01,02,29,38,44,56 read_members.extend( [ - " if forth_stash is not None:", - " key = forth_obj.get_keys(1)", + " if forth_obj is not None:", + " key = key_number ; key_number += 1", ' form_key = f"node{key}-data"', - f' forth_stash.add_to_header(f"output node{{key}}-data {uproot._awkward_forth.convert_dtype(formats[-1][0])}\\n")', - f' content[{fields[-1][0]!r}] = {{ "class": "NumpyArray", "primitive": "{uproot._awkward_forth.convert_dtype(formats[-1][0])}", "inner_shape": [], "parameters": {{}}, "form_key": f"node{{key}}"}}', + f' nested_forth_stash = af.Node(f"node{{key}}", field_name={fields[-1][0]!r}, form_details={{ "class": "NumpyArray", "primitive": "{af.struct_to_dtype_name[formats[-1][0]]}", "inner_shape": [], "parameters": {{}}, "form_key": f"node{{key}}"}})', + f' nested_forth_stash.header_code.append(f"output node{{key}}-data {af.struct_to_dtype_name[formats[-1][0]]}\\n")', + " forth_obj.add_node(nested_forth_stash)", ] ) if fields[-1][0] in COUNT_NAMES: read_members.extend( [ - f' forth_stash.add_to_init(f"variable var_{fields[-1][0]}\\n")', - f' forth_stash.add_to_pre(f"stream !{formats[-1][0]}-> stack dup var_{fields[-1][0]} ! node{{key}}-data <- stack\\n")', + f' nested_forth_stash.init_code.append(f"variable var_{fields[-1][0]}\\n")', + f' nested_forth_stash.pre_code.append(f"stream !{formats[-1][0]}-> stack dup var_{fields[-1][0]} ! node{{key}}-data <- stack\\n")', ] ) else: read_members.append( - f' forth_stash.add_to_pre(f"stream !{formats[-1][0]}-> node{{key}}-data\\n")' + f' nested_forth_stash.pre_code.append(f"stream !{formats[-1][0]}-> node{{key}}-data\\n")' ) - - read_members.extend( - [ - " if forth_obj.should_add_form():", - " forth_obj.add_form_key(form_key)", - f" self._members[{fields[-1][0]!r}] = cursor.field(chunk, self._format{len(formats) - 1}, context)", - ] + read_members.append( + f" self._members[{fields[-1][0]!r}] = cursor.field(chunk, self._format{len(formats) - 1}, context)", ) else: - read_members.append(" if forth_stash is not None:") + # AwkwardForth testing E: test_0637's 01,02,05,08,09,11,12,13,15,16,29,35,39,45,46,47,49,50,56 + read_members.append(" if forth_obj is not None:") for i in range(len(formats[0])): read_members.extend( [ - " key = forth_obj.get_keys(1)", + " key = key_number ; key_number += 1", ' form_key = f"node{key}-data"', - f' forth_stash.add_to_header(f"output node{{key}}-data {uproot._awkward_forth.convert_dtype(formats[0][i])}\\n")', - ### FIXME: what is this commented-out code? - # ' forth_stash.add_to_init(f"0 node{key}-offsets <- stack\\n")', - f' content[{fields[0][i]!r}] = {{ "class": "NumpyArray", "primitive": "{uproot._awkward_forth.convert_dtype(formats[0][i])}", "inner_shape": [], "parameters": {{}}, "form_key": f"node{{key}}"}}', - f' forth_stash.add_to_pre(f"stream !{formats[0][i]}-> node{{key}}-data\\n")', - " if forth_obj.should_add_form():", - " forth_obj.add_form_key(form_key)", + f' nested_forth_stash = af.Node(f"node{{key}}", field_name={fields[0][i]!r}, form_details={{ "class": "NumpyArray", "primitive": "{af.struct_to_dtype_name[formats[0][i]]}", "inner_shape": [], "parameters": {{}}, "form_key": f"node{{key}}"}})', + f' nested_forth_stash.header_code.append(f"output {{form_key}} {af.struct_to_dtype_name[formats[0][i]]}\\n")', + f' nested_forth_stash.pre_code.append(f"stream !{formats[0][i]}-> {{form_key}}\\n")', + " forth_obj.add_node(nested_forth_stash)", ] ) @@ -1044,8 +1015,6 @@ def class_code( f"self._members[{x!r}]" for x in fields[-1] ) - # AwkwardForth testing: test_0637's 01,02,05,08,09,11,12,13,15,16,29,35,39,45,46,47,49,50,56 - read_members.append( f"\n {assign_members} = cursor.fields(chunk, self._format{len(formats) - 1}, context)" ) @@ -1055,22 +1024,18 @@ def class_code( ) else: - # AwkwardForth testing: test_0637's 44,56 + # AwkwardForth testing F: test_0637's 44,56 read_members.extend( [ - " if forth_stash is not None:", - " key = forth_obj.get_keys(1)", - " key2 = forth_obj.get_keys(1)", - ' form_key = f"node{key}-data"', - ' form_key2 = f"node{key2}-offsets"', - f' forth_stash.add_to_header(f"output node{{key}}-data {{uproot._awkward_forth.convert_dtype(uproot._awkward_forth.symbol_dict[self._dtype{len(dtypes)}])}}\\n")', - ' forth_stash.add_to_header(f"output node{key2}-offsets int64\\n")', - ' forth_stash.add_to_init(f"0 node{key2}-offsets <- stack\\n")', - f' content[{self.name!r}] = {{"class": "RegularArray", "size": {self.array_length}, "content": {{ "class": "NumpyArray", "primitive": f"{{uproot._awkward_forth.convert_dtype(uproot._awkward_forth.symbol_dict[self._dtype{len(dtypes)}])}}", "inner_shape": [], "parameters": {{}}, "form_key": f"node{{key}}"}}, "form_key": f"node{{key2}}"}}', - f' forth_stash.add_to_pre(f"{self.array_length} dup node{{key2}}-offsets +<- stack \\n stream #!{{uproot._awkward_forth.symbol_dict[self._dtype{len(dtypes)}]}}-> node{{key}}-data\\n")\n', - " if forth_obj.should_add_form():", - " forth_obj.add_form_key(form_key)", - " forth_obj.add_form_key(form_key2)", + " if forth_obj is not None:", + " key = key_number ; key_number += 1", + " key2 = key_number ; key_number += 1", + f' nested_forth_stash = af.Node(f"node{{key}}", field_name={self.name!r}, form_details={{"class": "RegularArray", "size": {self.array_length}, "content": {{ "class": "NumpyArray", "primitive": f"{{af.struct_to_dtype_name[af.dtype_to_struct[self._dtype{len(dtypes)}]]}}", "inner_shape": [], "parameters": {{}}, "form_key": f"node{{key}}"}}, "form_key": f"node{{key2}}"}})', + f' nested_forth_stash.header_code.append(f"output node{{key}}-data {{af.struct_to_dtype_name[af.dtype_to_struct[self._dtype{len(dtypes)}]]}}\\n")', + ' nested_forth_stash.header_code.append(f"output node{key2}-offsets int64\\n")', + ' nested_forth_stash.init_code.append(f"0 node{key2}-offsets <- stack\\n")', + f' nested_forth_stash.pre_code.append(f"{self.array_length} dup node{{key2}}-offsets +<- stack \\n stream #!{{af.dtype_to_struct[self._dtype{len(dtypes)}]}}-> node{{key}}-data\\n")', + " forth_obj.add_node(nested_forth_stash)", f" self._members[{self.name!r}] = cursor.array(chunk, {self.array_length}, self._dtype{len(dtypes)}, context)", ] ) @@ -1079,19 +1044,6 @@ def class_code( read_member_n.extend( [ - " if forth_stash is not None:", - " key = forth_obj.get_keys(1)", - " key2 = forth_obj.get_keys(1)", - ' form_key = f"node{key}-data"', - ' form_key2 = f"node{key2}-offsets"', - f' forth_stash.add_to_header(f"output node{{key}}-data {{uproot._awkward_forth.convert_dtype(uproot._awkward_forth.symbol_dict[self._dtype{len(dtypes)}])}}\\n")', - ' forth_stash.add_to_header(f"output node{key2}-offsets int64\\n")', - ' forth_stash.add_to_init(f"0 node{key2}-offsets <- stack\\n")', - f' content[{self.name!r}] = {{"class": "ListOffsetArray", "offsets": "i64", "content": {{ "class": "NumpyArray", "primitive": f"{{uproot._awkward_forth.convert_dtype(uproot._awkward_forth.symbol_dict[self._dtype{len(dtypes)}])}}", "inner_shape": [], "parameters": {{}}, "form_key": f"node{{key}}"}}, "form_key": f"node{{key2}}"}}', - f' forth_stash.add_to_pre(f"{self.array_length} dup node{{key2}}-offsets +<- stack \\n stream #!{{uproot._awkward_forth.symbol_dict[self._dtype{len(dtypes)}]}}-> node{{key}}-data\\n")\n', - " if forth_obj.should_add_form():", - " forth_obj.add_form_key(form_key)", - " forth_obj.add_form_key(form_key2)", f" self._members[{self.name!r}] = cursor.array(chunk, {self.array_length}, self._dtype{len(dtypes)}, context)", ] ) @@ -1102,7 +1054,7 @@ def class_code( ) else: strided_interpretation.append( - f" raise uproot.interpretation.objects.CannotBeStrided('class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}')" + f" raise CannotBeStrided('class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}')" ) if self.array_length == 0: @@ -1248,15 +1200,19 @@ def class_code( # untested as of PR #629 read_members.extend( [ - ' context["cancel_forth"] = True', + " if forth_obj is not None:", + " raise CannotBeForth()", " cursor.skip(6)", f" for tmp in range(self.member({self.count_name!r})):", - f" self._members[{self.name!r}] = c({self.typename.rstrip('*')!r}).read(chunk, cursor, context, file, self._file, self.concrete)", + f" self._members[{self.name!r}] = c({self.typename.rstrip('*')!r}).read(chunk, cursor, af.add_to_path(forth_obj, context, {self.name!r}), file, self._file, self.concrete)", + " if forth_obj is not None:", + " if len(forth_obj.active_node.children) != 0:", + f" forth_obj.active_node.children[-1].field_name = {self.name!r}", ] ) strided_interpretation.append( - f" raise uproot.interpretation.objects.CannotBeStrided('class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}')" + f" raise CannotBeStrided('class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}')" ) awkward_form.extend( @@ -1352,29 +1308,13 @@ def class_code( string_header=True, ) - # AwkwardForth testing: test_0637's 35,38,39,44,45,47,50,56 + # AwkwardForth testing G: test_0637's 35,38,39,44,45,47,50,56 read_members.extend( [ - " if forth_stash is not None:", - " temp_node, temp_node_top, temp_form, temp_form_top, temp_prev_form = forth_obj.replace_form_and_model(None, {'name': 'TOP', 'content': {}})", - f" self._members[{self.name!r}] = self._stl_container{len(containers)}.read(chunk, cursor, context, file, self._file, self.concrete)", - " if forth_stash is not None:", - " temp_prev_form1 = forth_obj.prev_form", - " temp_form1 = forth_obj.top_form", - " temp_model1 = forth_obj.top_node", - " temp_model_ref = forth_obj.awkward_model", - " forth_obj.awkward_model = temp_node", - " forth_obj.prev_form = temp_prev_form", - " forth_obj.top_node = temp_node_top", - " forth_obj.aform = temp_form", - " forth_obj.top_form = temp_form_top", - " temp_model1 = temp_model1['content']", - f" content[{self.name!r}] = temp_form1", - " pre,post,init,header = forth_obj.get_code_recursive(temp_model1)", - " forth_stash.add_to_header(header)", - " forth_stash.add_to_pre(pre)", - " forth_stash.add_to_post(post)", - " forth_stash.add_to_init(init)", + f" self._members[{self.name!r}] = self._stl_container{len(containers)}.read(chunk, cursor, af.add_to_path(forth_obj, context, {self.name!r}), file, self._file, self.concrete)", + " if forth_obj is not None:", + " if len(forth_obj.active_node.children) != 0:", + f" forth_obj.active_node.children[-1].field_name = {self.name!r}", ] ) @@ -1482,12 +1422,15 @@ def class_code( read_member_n.append(f" if member_index == {i}:") if self.fType == uproot.const.kObjectp or self.fType == uproot.const.kAnyp: - # AwkwardForth testing: test_0637's (none! untested!) - + # AwkwardForth testing H: test_0637's (none! untested!) read_members.extend( [ - ' context["cancel_forth"] = True', - f" self._members[{self.name!r}] = c({self.typename.rstrip('*')!r}).read(chunk, cursor, context, file, self._file, self.concrete)", + " if forth_obj is not None:", + " raise CannotBeForth()", + f" self._members[{self.name!r}] = c({self.typename.rstrip('*')!r}).read(chunk, cursor, af.add_to_path(forth_obj, context, {self.name!r}), file, self._file, self.concrete)", + " if forth_obj is not None:", + " if len(forth_obj.active_node.children) != 0:", + f" forth_obj.active_node.children[-1].field_name = {self.name!r}", ] ) @@ -1504,26 +1447,32 @@ def class_code( ) elif self.fType == uproot.const.kObjectP or self.fType == uproot.const.kAnyP: - # AwkwardForth testing: test_0637's (none! untested!) - - read_members.append( - f" self._members[{self.name!r}] = read_object_any(chunk, cursor, context, file, self._file, self)" + # AwkwardForth testing I: test_0637's (none! untested!) + read_members.extend( + [ + " if forth_obj is not None:", + " raise CannotBeForth()", + f" self._members[{self.name!r}] = read_object_any(chunk, cursor, af.add_to_path(forth_obj, context, {self.name!r}), file, self._file, self)", + " if forth_obj is not None:", + " if len(forth_obj.active_node.children) != 0:", + f" forth_obj.active_node.children[-1].field_name = {self.name!r}", + ] ) read_member_n.append( f" self._members[{self.name!r}] = read_object_any(chunk, cursor, context, file, self._file, self)" ) strided_interpretation.append( - f" raise uproot.interpretation.objects.CannotBeStrided('class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}')" + f" raise CannotBeStrided('class members defined by {type(self).__name__} of type {self.typename} in member {self.name} of class {streamerinfo.name}')" ) class_flags["has_read_object_any"] = True else: # untested as of PR #629 read_members.append( - f" raise uproot.deserialization.DeserializationError('not implemented: class members defined by {type(self).__name__} with fType {self.fType}', chunk, cursor, context, file.file_path)" + f" raise DeserializationError('not implemented: class members defined by {type(self).__name__} with fType {self.fType}', chunk, cursor, context, file.file_path)" ) read_member_n.append( - f" raise uproot.deserialization.DeserializationError('not implemented: class members defined by {type(self).__name__} with fType {self.fType}', chunk, cursor, context, file.file_path)" + f" raise DeserializationError('not implemented: class members defined by {type(self).__name__} with fType {self.fType}', chunk, cursor, context, file.file_path)" ) member_names.append(self.name) @@ -1618,29 +1567,13 @@ def class_code( ): read_member_n.append(f" if member_index == {i}:") - # AwkwardForth testing: test_0637's 01,02,29,45,46,49,50,56 + # AwkwardForth testing J: test_0637's 01,02,29,45,46,49,50,56 read_members.extend( [ - " if forth_stash is not None:", - " temp_node, temp_node_top, temp_form, temp_form_top, temp_prev_form = forth_obj.replace_form_and_model(None, {'name': 'TOP', 'content': {}})", - f" self._members[{self.name!r}] = c({self.typename.rstrip('*')!r}).read(chunk, cursor, context, file, self._file, self.concrete)", - " if forth_stash is not None:", - " temp_prev_form1 = forth_obj.prev_form", - " temp_form1 = forth_obj.top_form", - " temp_model1 = forth_obj.top_node", - " temp_model_ref = forth_obj.awkward_model", - " forth_obj.awkward_model = temp_node", - " forth_obj.prev_form = temp_prev_form", - " forth_obj.top_node = temp_node_top", - " forth_obj.aform = temp_form", - " forth_obj.top_form = temp_form_top", - " temp_model1 = temp_model1['content']", - f" content[{self.name!r}] = temp_form1", - " pre,post,init,header = forth_obj.get_code_recursive(temp_model1)", - " forth_stash.add_to_header(header)", - " forth_stash.add_to_pre(pre)", - " forth_stash.add_to_post(post)", - " forth_stash.add_to_init(init)", + f" self._members[{self.name!r}] = c({self.typename.rstrip('*')!r}).read(chunk, cursor, af.add_to_path(forth_obj, context, {self.name!r}), file, self._file, self.concrete)", + " if forth_obj is not None:", + " if len(forth_obj.active_node.children) != 0:", + f" forth_obj.active_node.children[-1].field_name = {self.name!r}", ] ) diff --git a/tests/test_0637-setup-tests-for-AwkwardForth.py b/tests/test_0637-setup-tests-for-AwkwardForth.py index 85bd6b8a5..43e29cb5b 100644 --- a/tests/test_0637-setup-tests-for-AwkwardForth.py +++ b/tests/test_0637-setup-tests-for-AwkwardForth.py @@ -11,6 +11,39 @@ @pytest.mark.parametrize("is_forth", [False, True]) def test_00(is_forth): + # see AwkwardForth testing: L, P, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # output node3-offsets int64 + # output node4-data float64 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # 0 node3-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 6 stream skip + # dup 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # 6 stream skip + # 0 do + # stream !I-> stack + # dup node3-offsets +<- stack + # stream #!d-> node4-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("issue367b.root")) as file: branch = file["tree/weights"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -19,10 +52,47 @@ def test_00(is_forth): assert py[0]["0"][0] == "expskin_FluxUnisim" # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_01(is_forth): + # see AwkwardForth testing: A, B, D, E, J, N + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data float64 + # output node2-data float64 + # output node3-data float64 + # output node4-data float64 + # + # 0 node0-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 0 bytestops I-> stack + # begin + # dup stream pos <> + # while + # swap 1 + swap + # 0 stream skip + # 6 stream skip + # 10 stream skip + # 0 stream skip + # 6 stream skip + # 10 stream skip + # stream !d-> node1-data + # stream !d-> node2-data + # stream !d-> node3-data + # stream !d-> node4-data + # repeat + # swap node0-offsets +<- stack drop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-delphes-pr442.root")) as file: branch = file["Delphes/GenJet/GenJet.SoftDroppedSubJet1"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -32,10 +102,47 @@ def test_01(is_forth): assert py[0][0]["fP"]["fZ"] == pytest.approx(-81.600465) # py[-1] == array([, ], dtype=object) assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_02(is_forth): + # see AwkwardForth testing: A, B, D, E, J, N + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data float64 + # output node2-data float64 + # output node3-data float64 + # output node4-data float64 + # + # 0 node0-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 0 bytestops I-> stack + # begin + # dup stream pos <> + # while + # swap 1 + swap + # 0 stream skip + # 6 stream skip + # 10 stream skip + # 0 stream skip + # 6 stream skip + # 10 stream skip + # stream !d-> node1-data + # stream !d-> node2-data + # stream !d-> node3-data + # stream !d-> node4-data + # repeat + # swap 5 / node0-offsets +<- stack drop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-delphes-pr442.root")) as file: branch = file["Delphes/GenJet/GenJet.TrimmedP4[5]"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -45,10 +152,35 @@ def test_02(is_forth): assert py[-1][8][3]["fE"] == 0 # py[-1] == array([[, , , , ], [, , , , ]], dtype=object) assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_03(is_forth): + # see AwkwardForth testing: L, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-FCCDelphesOutput.root")) as file: branch = file["metadata/gaudiConfigOptions"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -61,10 +193,37 @@ def test_03(is_forth): ) # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_04(is_forth): + # see AwkwardForth testing: P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # stream #!I-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["POOLContainerForm/DataHeaderForm/m_uints"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -74,18 +233,69 @@ def test_04(is_forth): assert py[0][3][2] == 589824 # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) - - -def test_05(): + if is_forth: + assert interp._complete_forth_code is not None + + +@pytest.mark.parametrize("is_forth", [False, True]) +def test_05(is_forth): + # see AwkwardForth testing: A, E (previously, this hadn't been tested: library="np") + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-data uint32 + # output node1-data uint32 + # output node2-data uint32 + # + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 0 stream skip + # stream !I-> node0-data + # stream !I-> node1-data + # stream !I-> node2-data + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["CollectionTree/TrigConfKeys"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) - py = branch.array(interp, library="np", entry_stop=2) + interp._forth = is_forth + py = branch.array(interp, library="ak", entry_stop=2) # py[-1] == + assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_06(is_forth): + # see AwkwardForth testing: P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data int32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # stream #!i-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["CollectionTree/AnalysisJetsAuxDyn.NumTrkPt500"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -94,10 +304,37 @@ def test_06(is_forth): assert py[1][-1][-2] == 0 # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_07(is_forth): + # see AwkwardForth testing: P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data float32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # stream #!f-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["CollectionTree/AnalysisJetsAuxDyn.SumPtTrkPt500"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -106,18 +343,93 @@ def test_07(is_forth): assert py[1][2][0] == pytest.approx(53949.015625) # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) - - -def test_08(): + if is_forth: + assert interp._complete_forth_code is not None + + +@pytest.mark.parametrize("is_forth", [False, True]) +def test_08(is_forth): + # see AwkwardForth testing: A, B, E, P (previously, this hadn't been tested: library="np") + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint32 + # output node3-data uint32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # 0 do + # 0 stream skip + # 6 stream skip + # 4 stream skip + # 6 stream skip + # 4 stream skip + # stream !I-> node2-data + # stream !I-> node3-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["CollectionTree/AnalysisJetsAuxDyn.GhostTrack"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) - py = branch.array(interp, library="np", entry_stop=2) + interp._forth = is_forth + py = branch.array(interp, library="ak", entry_stop=2) # py[-1] == > (version 1) at 0x7fc6a08f2f70>, ...], ...] at 0x7fc6a08f2f10> + assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_09(is_forth): + # see AwkwardForth testing: A, B, E, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint32 + # output node3-data uint32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # 0 do + # 0 stream skip + # 6 stream skip + # 4 stream skip + # 6 stream skip + # 4 stream skip + # stream !I-> node2-data + # stream !I-> node3-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["CollectionTree"][ "AntiKt10UFOCSSKJetsAuxDyn.GhostVR30Rmax4Rmin02TrackJet_BTagging201903" @@ -128,10 +440,37 @@ def test_09(is_forth): assert py[0][0][0]["m_persKey"] == 352341021 # py[-1] == > (version 1) at 0x7febbf1b2fa0>], ...] at 0x7febbf1b2f40> assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_10(is_forth): + # see AwkwardForth testing: P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data float32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # stream #!f-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["CollectionTree/CaloCalTopoClustersAuxDyn.e_sampl"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -140,10 +479,46 @@ def test_10(is_forth): assert py[0][0][0] == pytest.approx(168.03048706054688) # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_11(is_forth): + # see AwkwardForth testing: A, B, E, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint32 + # output node3-data uint32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # 0 do + # 0 stream skip + # 6 stream skip + # 4 stream skip + # 6 stream skip + # 4 stream skip + # stream !I-> node2-data + # stream !I-> node3-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["CollectionTree"][ "TruthBosonsWithDecayVerticesAuxDyn.incomingParticleLinks" @@ -154,10 +529,46 @@ def test_11(is_forth): assert py[0][0][0]["m_persKey"] == 921521854 # py[-1] == > (version 1) at 0x7f636a9484c0>], ...] at 0x7f636a948eb0> assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_12(is_forth): + # see AwkwardForth testing: A, B, E, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint32 + # output node3-data uint32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # 0 do + # 0 stream skip + # 6 stream skip + # 4 stream skip + # 6 stream skip + # 4 stream skip + # stream !I-> node2-data + # stream !I-> node3-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["CollectionTree/TruthBottomAuxDyn.parentLinks"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -166,10 +577,46 @@ def test_12(is_forth): assert py[0][0][0]["m_persIndex"] == 2 # py[-1] == > (version 1) at 0x7fc259ae37c0>], ...] at 0x7fc259ae3f10> assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_13(is_forth): + # see AwkwardForth testing: A, B, E, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint32 + # output node3-data uint32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # 0 do + # 0 stream skip + # 6 stream skip + # 4 stream skip + # 6 stream skip + # 4 stream skip + # stream !I-> node2-data + # stream !I-> node3-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["CollectionTree/egammaClustersAuxDyn.constituentClusterLinks"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -178,10 +625,37 @@ def test_13(is_forth): assert py[0][0][0]["m_persIndex"] == 0 # py[-1] == > (version 1) at 0x7fa94e968c10>], ...] at 0x7fa94e968c70> assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_14(is_forth): + # see AwkwardForth testing: P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data float32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # stream #!f-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["CollectionTree/egammaClustersAuxDyn.eta_sampl"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -190,10 +664,46 @@ def test_14(is_forth): assert py[0][0][-1] == pytest.approx(0.4663555920124054) # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_15(is_forth): + # see AwkwardForth testing: A, B, E, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint32 + # output node3-data uint32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # 0 do + # 0 stream skip + # 6 stream skip + # 4 stream skip + # 6 stream skip + # 4 stream skip + # stream !I-> node2-data + # stream !I-> node3-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["CollectionTree/AnalysisHLT_mu24_ilooseAuxDyn.TrigMatchedObjects"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -202,10 +712,46 @@ def test_15(is_forth): assert py[1][-1][-1]["m_persKey"] == 980095599 # py[-1] == > (version 1) at 0x7fb9b9d24c10>], ...] at 0x7fb9b9d29250> assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_16(is_forth): + # see AwkwardForth testing: A, B, E, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint32 + # output node3-data uint32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # 0 do + # 0 stream skip + # 6 stream skip + # 4 stream skip + # 6 stream skip + # 4 stream skip + # stream !I-> node2-data + # stream !I-> node3-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-123a.root")) as file: branch = file["CollectionTree/AnalysisHLT_mu40AuxDyn.TrigMatchedObjects"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -214,10 +760,14 @@ def test_16(is_forth): assert py[1][0]["m_persKey"][0] == 980095599 # py[-1] == > (version 1) at 0x7f6e29be5cd0>], ...] at 0x7f6e29bea250> assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_17(is_forth): + # see AwkwardForth testing: P + # (never finishes producing AwkwardForth code) with uproot.open(skhep_testdata.data_path("uproot-issue390.root")) as file: branch = file["E/Evt/AAObject/usr_names"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -230,6 +780,8 @@ def test_17(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_18(is_forth): + # see AwkwardForth testing: (none?) + # That's right: this interpretation is AsJagged(AsDtype('>f8')), which doesn't ever use AwkwardForth. with uproot.open(skhep_testdata.data_path("uproot-issue390.root")) as file: branch = file["E/Evt/hits/hits.t"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -242,6 +794,8 @@ def test_18(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_19(is_forth): + # see AwkwardForth testing: (none?) + # That's right: this interpretation is AsJagged(AsDtype('>f8')), which doesn't ever use AwkwardForth. with uproot.open(skhep_testdata.data_path("uproot-issue390.root")) as file: branch = file["E/Evt/hits/hits.a"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -254,6 +808,8 @@ def test_19(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_20(is_forth): + # see AwkwardForth testing: (none?) + # That's right: this interpretation is AsJagged(AsDtype('>i4')), which doesn't ever use AwkwardForth. with uproot.open(skhep_testdata.data_path("uproot-issue390.root")) as file: branch = file["E/Evt/hits/hits.trig"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -266,6 +822,8 @@ def test_20(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_21(is_forth): + # see AwkwardForth testing: (none?) + # That's right: this interpretation is AsJagged(AsDtype('>u4')), which doesn't ever use AwkwardForth. with uproot.open(skhep_testdata.data_path("uproot-issue390.root")) as file: branch = file["E/Evt/hits/hits.tot"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -278,6 +836,8 @@ def test_21(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_22(is_forth): + # see AwkwardForth testing: (none?) + # That's right: this interpretation is AsJagged(AsDtype('>f8')), which doesn't ever use AwkwardForth. with uproot.open(skhep_testdata.data_path("uproot-issue390.root")) as file: branch = file["E/Evt/hits/hits.pos.x"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -290,6 +850,8 @@ def test_22(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_23(is_forth): + # see AwkwardForth testing: N, P + # (never finishes producing AwkwardForth code) with uproot.open(skhep_testdata.data_path("uproot-issue390.root")) as file: branch = file["E/Evt/trks/trks.usr_names"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -302,6 +864,34 @@ def test_23(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_24(is_forth): + # see AwkwardForth testing: N, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data int32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # 0 bytestops I-> stack + # begin + # dup stream pos <> + # while + # swap 1 + swap + # stream !I-> stack + # dup node1-offsets +<- stack + # stream #!i-> node2-data + # repeat + # swap node0-offsets +<- stack drop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue390.root")) as file: branch = file["E/Evt/trks/trks.rec_stages"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -310,10 +900,38 @@ def test_24(is_forth): assert py[0][1][-1] == 5 # py[-1] == array([, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ], dtype=object) assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_25(is_forth): + # see AwkwardForth testing: L, N + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # 0 bytestops I-> stack + # begin + # dup stream pos <> + # while + # swap 1 + swap + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # repeat + # swap node0-offsets +<- stack drop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-208.root")) as file: branch = file["config/VERSION/VERSION._name"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -322,9 +940,12 @@ def test_25(is_forth): assert py[0][-1] == "numuCCAnalysis" # py[-1] == array(['psychePolicy', 'psycheEventModel', 'psycheCore', 'psycheUtils', 'psycheND280Utils', 'psycheIO', 'psycheSelections', 'psycheSystematics', 'highlandEventModel', 'highlandTools', 'highlandCore', 'highlandCorrections', 'highlandIO', 'baseAnalysis', 'baseTrackerAnalysis', 'numuCCAnalysis'], dtype=object) assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None def test_26(): + # see AwkwardForth testing: N, P with uproot.open(skhep_testdata.data_path("uproot-issue-208.root")) as file: branch = file["config/SEL/SEL._firstSteps"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -334,6 +955,38 @@ def test_26(): @pytest.mark.parametrize("is_forth", [False, True]) def test_27(is_forth): + # see AwkwardForth testing: L, N, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-offsets int64 + # output node3-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # 0 node2-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # 0 bytestops I-> stack + # begin + # dup stream pos <> + # while + # swap 1 + swap + # stream !I-> stack + # dup node1-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node2-offsets +<- stack stream #!B-> node3-data + # loop + # repeat + # swap node0-offsets +<- stack drop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-208.root")) as file: branch = file["config/SEL/SEL._branchAlias"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -342,10 +995,40 @@ def test_27(is_forth): assert py[0][0][-1] == "muFGD+Np" # py[-1] == array([], dtype=object) assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_28(is_forth): + # see AwkwardForth testing: N, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # 0 bytestops I-> stack + # begin + # dup stream pos <> + # while + # swap 1 + swap + # stream !I-> stack + # dup node1-offsets +<- stack + # stream #!I-> node2-data + # repeat + # swap node0-offsets +<- stack drop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-208.root")) as file: branch = file["config/SEL/SEL._nCutsInBranch"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -354,9 +1037,13 @@ def test_28(is_forth): assert py[0][0][-1] == 10 # py[-1] == array([], dtype=object) assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None def test_29(): + # see AwkwardForth testing: A, B, C, D, E, J, M + # This one CannotBeAwkward. with uproot.open(skhep_testdata.data_path("uproot-issue213.root")) as file: branch = file["T/eventPack/fGenInfo"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -366,6 +1053,32 @@ def test_29(): @pytest.mark.parametrize("is_forth", [False, True]) def test_30(is_forth): + # see AwkwardForth testing: L, N + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # 0 bytestops I-> stack + # begin + # dup stream pos <> + # while + # swap 1 + swap + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # repeat + # swap node0-offsets +<- stack drop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue243-new.root")) as file: branch = file["triggerList/triggerMap/triggerMap.first"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -374,10 +1087,37 @@ def test_30(is_forth): assert len(py[0]) == 0 # py[-1] == array(['HLT_2j35_bmv2c2060_split_2j35_L14J15.0ETA25', 'HLT_j100_2j55_bmv2c2060_split'], dtype=object) assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_31(is_forth): + # see AwkwardForth testing: P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # stream #!I-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-308.root")) as file: branch = file["MetaData/BranchIDLists"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -386,10 +1126,28 @@ def test_31(is_forth): assert py[0][0][-1] == 2428801822 # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_32(is_forth): + # see AwkwardForth testing: (none?) + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data uint8 + # + # 0 node0-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # stream !I-> stack dup node0-offsets +<- stack stream #B-> node1-data + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue31.root")) as file: branch = file["T/data/name"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -398,10 +1156,45 @@ def test_32(is_forth): assert py[-1] == "two" # py[-1] == "two" assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_33(is_forth): + # see AwkwardForth testing: L, P, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # output node3-offsets int64 + # output node4-data float64 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # 0 node3-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 6 stream skip + # dup 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # 6 stream skip + # 0 do + # stream !I-> stack + # dup node3-offsets +<- stack + # stream #!d-> node4-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue367b.root")) as file: branch = file["tree/weights"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -410,10 +1203,29 @@ def test_33(is_forth): assert py[0][4]["1"][-1] == 1.0 # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_34(is_forth): + # see AwkwardForth testing: (none?) + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data uint8 + # + # 0 node0-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node0-offsets +<- stack stream #!B-> node1-data + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue371.root")) as file: branch = file["Header/Header./Header.geant4Version"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -421,10 +1233,46 @@ def test_34(is_forth): py = branch.array(interp, library="ak", entry_stop=2) assert py[-1] == "$Name: geant4-10-05-patch-01 $" assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_35(is_forth): + # see AwkwardForth testing: A, E, G, L, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data int32 + # output node2-offsets int64 + # output node3-data uint8 + # output node4-data int32 + # output node5-data float64 + # + # 0 node0-offsets <- stack + # 0 node2-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # dup + # stream #!i-> node1-data + # 0 do + # 0 stream skip + # 6 stream skip + # 4 stream skip + # 6 stream skip + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node2-offsets +<- stack stream #!B-> node3-data + # stream !i-> node4-data + # stream !d-> node5-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue371.root")) as file: branch = file["Geant4Data/Geant4Data./Geant4Data.particles"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -433,10 +1281,35 @@ def test_35(is_forth): assert py[0, "1", 0, "name"] == "anti_alpha" # py[-1] == , ...} at 0x7fb557a012e0> assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_36(is_forth): + # see AwkwardForth testing: L, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue371.root")) as file: branch = file["Model/Model./Model.samplerNamesUnique"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -445,10 +1318,40 @@ def test_36(is_forth): assert py[0][-1] == "MP_F_99." # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_37(is_forth): + # see AwkwardForth testing: (none?) + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data float64 + # output node2-data float64 + # output node3-data float64 + # + # 0 node0-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # 0 stream skip + # 6 stream skip + # 10 stream skip + # stream !d-> node1-data + # stream !d-> node2-data + # stream !d-> node3-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue371.root")) as file: branch = file["Model/Model./Model.staPos"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -457,10 +1360,214 @@ def test_37(is_forth): assert py[0][555]["fZ"] == 100.94856572890848 # py[-1] == array([, , , ..., , , ], dtype=object) assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_38(is_forth): + # see AwkwardForth testing: A, B, D, G, L, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data uint8 + # output node2-data int32 + # output node3-offsets int64 + # output node4-data float32 + # output node5-offsets int64 + # output node6-data float32 + # output node7-offsets int64 + # output node8-data float32 + # output node9-data float32 + # output node10-offsets int64 + # output node11-data float32 + # output node12-offsets int64 + # output node13-data float32 + # output node14-offsets int64 + # output node15-data float32 + # output node16-offsets int64 + # output node17-data float32 + # output node18-offsets int64 + # output node19-data float32 + # output node20-offsets int64 + # output node21-data int32 + # output node22-offsets int64 + # output node23-data int32 + # output node24-offsets int64 + # output node25-data int32 + # output node26-data int32 + # output node27-offsets int64 + # output node28-data int32 + # output node29-data float32 + # output node30-offsets int64 + # output node31-data float32 + # output node32-offsets int64 + # output node33-data float32 + # output node34-offsets int64 + # output node35-data float32 + # output node36-offsets int64 + # output node37-data float32 + # output node38-offsets int64 + # output node39-data float32 + # output node40-offsets int64 + # output node41-data int32 + # output node42-offsets int64 + # output node43-data float32 + # output node44-offsets int64 + # output node45-data float32 + # output node46-offsets int64 + # output node47-data float32 + # output node48-offsets int64 + # output node49-data bool + # output node50-offsets int64 + # output node51-data int32 + # output node52-offsets int64 + # output node53-data int32 + # output node54-offsets int64 + # output node55-data int32 + # + # 0 node0-offsets <- stack + # 0 node3-offsets <- stack + # 0 node5-offsets <- stack + # 0 node7-offsets <- stack + # 0 node10-offsets <- stack + # 0 node12-offsets <- stack + # 0 node14-offsets <- stack + # 0 node16-offsets <- stack + # 0 node18-offsets <- stack + # 0 node20-offsets <- stack + # 0 node22-offsets <- stack + # 0 node24-offsets <- stack + # 0 node27-offsets <- stack + # 0 node30-offsets <- stack + # 0 node32-offsets <- stack + # 0 node34-offsets <- stack + # 0 node36-offsets <- stack + # 0 node38-offsets <- stack + # 0 node40-offsets <- stack + # 0 node42-offsets <- stack + # 0 node44-offsets <- stack + # 0 node46-offsets <- stack + # 0 node48-offsets <- stack + # 0 node50-offsets <- stack + # 0 node52-offsets <- stack + # 0 node54-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 0 stream skip + # 10 stream skip + # 6 stream skip + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node0-offsets +<- stack stream #!B-> node1-data + # stream !i-> node2-data + # 6 stream skip + # stream !I-> stack + # dup node3-offsets +<- stack + # stream #!f-> node4-data + # 6 stream skip + # stream !I-> stack + # dup node5-offsets +<- stack + # stream #!f-> node6-data + # 6 stream skip + # stream !I-> stack + # dup node7-offsets +<- stack + # stream #!f-> node8-data + # stream !f-> node9-data + # 6 stream skip + # stream !I-> stack + # dup node10-offsets +<- stack + # stream #!f-> node11-data + # 6 stream skip + # stream !I-> stack + # dup node12-offsets +<- stack + # stream #!f-> node13-data + # 6 stream skip + # stream !I-> stack + # dup node14-offsets +<- stack + # stream #!f-> node15-data + # 6 stream skip + # stream !I-> stack + # dup node16-offsets +<- stack + # stream #!f-> node17-data + # 6 stream skip + # stream !I-> stack + # dup node18-offsets +<- stack + # stream #!f-> node19-data + # 6 stream skip + # stream !I-> stack + # dup node20-offsets +<- stack + # stream #!i-> node21-data + # 6 stream skip + # stream !I-> stack + # dup node22-offsets +<- stack + # stream #!i-> node23-data + # 6 stream skip + # stream !I-> stack + # dup node24-offsets +<- stack + # stream #!i-> node25-data + # stream !i-> node26-data + # 6 stream skip + # stream !I-> stack + # dup node27-offsets +<- stack + # stream #!i-> node28-data + # stream !f-> node29-data + # 6 stream skip + # stream !I-> stack + # dup node30-offsets +<- stack + # stream #!f-> node31-data + # 6 stream skip + # stream !I-> stack + # dup node32-offsets +<- stack + # stream #!f-> node33-data + # 6 stream skip + # stream !I-> stack + # dup node34-offsets +<- stack + # stream #!f-> node35-data + # 6 stream skip + # stream !I-> stack + # dup node36-offsets +<- stack + # stream #!f-> node37-data + # 6 stream skip + # stream !I-> stack + # dup node38-offsets +<- stack + # stream #!f-> node39-data + # 6 stream skip + # stream !I-> stack + # dup node40-offsets +<- stack + # stream #!i-> node41-data + # 6 stream skip + # stream !I-> stack + # dup node42-offsets +<- stack + # stream #!f-> node43-data + # 6 stream skip + # stream !I-> stack + # dup node44-offsets +<- stack + # stream #!f-> node45-data + # 6 stream skip + # stream !I-> stack + # dup node46-offsets +<- stack + # stream #!f-> node47-data + # 6 stream skip + # stream !I-> stack + # dup node48-offsets +<- stack + # stream #!?-> node49-data + # 6 stream skip + # stream !I-> stack + # dup node50-offsets +<- stack + # stream #!i-> node51-data + # 6 stream skip + # stream !I-> stack + # dup node52-offsets +<- stack + # stream #!i-> node53-data + # 6 stream skip + # stream !I-> stack + # dup node54-offsets +<- stack + # stream #!i-> node55-data + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue371.root")) as file: branch = file["Event/PRBHF_46."] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -469,10 +1576,46 @@ def test_38(is_forth): assert py[0]["zp"][0] == pytest.approx(0.9999998807907104) # py[-1] == (version 4) at 0x7f9be2f7b2e0> assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_39(is_forth): + # see AwkwardForth testing: A, E, G, L, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data int32 + # output node2-offsets int64 + # output node3-data uint8 + # output node4-data int32 + # output node5-data float64 + # + # 0 node0-offsets <- stack + # 0 node2-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # dup + # stream #!i-> node1-data + # 0 do + # 0 stream skip + # 6 stream skip + # 4 stream skip + # 6 stream skip + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node2-offsets +<- stack stream #!B-> node3-data + # stream !i-> node4-data + # stream !d-> node5-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue399.root")) as file: branch = file["Geant4Data/Geant4Data./Geant4Data.particles"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -481,10 +1624,26 @@ def test_39(is_forth): assert py[-1][1]["0"] == -1000020030 # py[-1] == , ...} at 0x7f6d057397f0> assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_40(is_forth): + # see AwkwardForth testing: (none?) + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-data int32 + # + # + # 0 do + # byteoffsets I-> stack + # stream seek + # stream !I-> node0-data + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue-407.root")) as file: branch = file["tree/branch"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -493,10 +1652,14 @@ def test_40(is_forth): assert py[0]["fDatime"] == 1749155840 # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_41(is_forth): + # see AwkwardForth testing: P + # (never finishes producing AwkwardForth code) with uproot.open(skhep_testdata.data_path("uproot-issue468.root")) as file: branch = file["Event/Trajectory./Trajectory.XYZ"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -509,6 +1672,8 @@ def test_41(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_42(is_forth): + # see AwkwardForth testing: P + # (never finishes producing AwkwardForth code) with uproot.open(skhep_testdata.data_path("uproot-issue468.root")) as file: branch = file["Event/Trajectory./Trajectory.energyDeposit"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -521,6 +1686,8 @@ def test_42(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_43(is_forth): + # see AwkwardForth testing: P + # (never finishes producing AwkwardForth code) with uproot.open(skhep_testdata.data_path("uproot-issue468.root")) as file: branch = file["Event/Trajectory./Trajectory.ionA"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -533,6 +1700,42 @@ def test_43(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_44(is_forth): + # see AwkwardForth testing: A, C, D, F, G, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-data bool + # output node1-data bool + # output node2-offsets int64 + # output node3-data uint32 + # output node4-data bool + # output node5-offsets int64 + # output node6-offsets int64 + # output node7-data bool + # + # 0 node2-offsets <- stack + # variable var_N + # 0 node5-offsets <- stack + # 0 node6-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 0 stream skip + # stream !?-> node0-data + # 10 dup node2-offsets +<- stack + # stream #!?-> node1-data + # stream !I-> stack dup var_N ! node3-data <- stack + # 1 stream skip + # var_N @ dup node5-offsets +<- stack + # stream #!?-> node4-data + # 6 stream skip + # stream !I-> stack + # dup node6-offsets +<- stack + # stream #!?-> node7-data + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue46.root")) as file: branch = file["tree/evt"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -541,9 +1744,13 @@ def test_44(is_forth): assert py[0]["ArrayBool"][-1] == True # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None def test_45(): + # see AwkwardForth testing: A, B, E, G, J, L, M, P + # This one CannotBeAwkward. with uproot.open(skhep_testdata.data_path("uproot-issue485.root")) as file: branch = file["MCTrack/global"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -552,6 +1759,8 @@ def test_45(): def test_46(): + # see AwkwardForth testing: A, B, E, J, M, P + # This one CannotBeAwkward. with uproot.open(skhep_testdata.data_path("uproot-issue485.root")) as file: branch = file["MCParticle/detector1"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -561,6 +1770,40 @@ def test_46(): @pytest.mark.parametrize("is_forth", [False, True]) def test_47(is_forth): + # see AwkwardForth testing: A, E, G, L, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data int32 + # output node2-offsets int64 + # output node3-data uint8 + # output node4-data int32 + # output node5-data float64 + # + # 0 node0-offsets <- stack + # 0 node2-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # dup + # stream #!i-> node1-data + # 0 do + # 0 stream skip + # 6 stream skip + # 4 stream skip + # 6 stream skip + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node2-offsets +<- stack stream #!B-> node3-data + # stream !i-> node4-data + # stream !d-> node5-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue494.root")) as file: branch = file["Geant4Data/Geant4Data./Geant4Data.particles"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -569,9 +1812,13 @@ def test_47(is_forth): assert py[-1][-1]["1"]["mass"] == pytest.approx(3.727379) # py[-1] == , ...} at 0x7f53a44278b0> assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None def test_48(): + # see AwkwardForth testing: R + # This one CannotBeAwkward. with uproot.open(skhep_testdata.data_path("uproot-issue494.root")) as file: branch = file["Geant4Data/Geant4Data./Geant4Data.ions"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -582,6 +1829,8 @@ def test_48(): def test_49(): + # see AwkwardForth testing: A, B, E, J, M, P + # This one CannotBeAwkward. with uproot.open(skhep_testdata.data_path("uproot-issue498.root")) as file: branch = file["MCParticle/timepix"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -591,6 +1840,8 @@ def test_49(): def test_50(): + # see AwkwardForth testing: A, B, E, G, J, M, P + # This one CannotBeAwkward. with uproot.open(skhep_testdata.data_path("uproot-issue498.root")) as file: branch = file["PixelHit/timepix"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -602,6 +1853,32 @@ def test_50(): @pytest.mark.parametrize("is_forth", [False, True]) def test_51(is_forth): + # see AwkwardForth testing: L, N + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # 0 bytestops I-> stack + # begin + # dup stream pos <> + # while + # swap 1 + swap + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # repeat + # swap node0-offsets +<- stack drop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue510b.root")) as file: branch = file["EDepSimEvents/Event/Primaries/Primaries.GeneratorName"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -609,10 +1886,46 @@ def test_51(is_forth): py = branch.array(interp, library="ak", entry_stop=2) assert py[-1][0] == "GENIE:fixed@density-fixed" assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_52(is_forth): + # see AwkwardForth testing: A, N + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node2-offsets int64 + # output node3-data uint8 + # output node4-data int32 + # output node5-offsets int64 + # output node6-data int32 + # + # 0 node0-offsets <- stack + # 0 node2-offsets <- stack + # 0 node5-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 0 bytestops I-> stack + # begin + # dup stream pos <> + # while + # swap 1 + swap + # 6 stream skip + # 10 stream skip + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node2-offsets +<- stack stream #!B-> node3-data + # stream !I-> stack dup node4-data <- stack + # 6 stream skip + # dup node5-offsets +<- stack stream #!I-> node6-data + # repeat + # swap node0-offsets +<- stack drop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue513.root")) as file: branch = file["Delphes/EFlowPhoton/EFlowPhoton.Particles"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -621,10 +1934,47 @@ def test_52(is_forth): assert py[1][-1]["refs"][-1] == 2223 # py[-1] == array([, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ], dtype=object) assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_53(is_forth): + # see AwkwardForth testing: (none?) + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data float64 + # output node2-data float64 + # output node3-data float64 + # output node4-data float64 + # + # 0 node0-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 0 bytestops I-> stack + # begin + # dup stream pos <> + # while + # swap 1 + swap + # 0 stream skip + # 6 stream skip + # 10 stream skip + # 0 stream skip + # 6 stream skip + # 10 stream skip + # stream !d-> node1-data + # stream !d-> node2-data + # stream !d-> node3-data + # stream !d-> node4-data + # repeat + # swap node0-offsets +<- stack drop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue513.root")) as file: branch = file["Delphes/Jet/Jet.SoftDroppedSubJet2"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -633,10 +1983,47 @@ def test_53(is_forth): assert py[0][-1]["fE"] == 0.0 # py[-1] == array([, , , , , ], dtype=object) assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_54(is_forth): + # see AwkwardForth testing: (none?) + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data float64 + # output node2-data float64 + # output node3-data float64 + # output node4-data float64 + # + # 0 node0-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 0 bytestops I-> stack + # begin + # dup stream pos <> + # while + # swap 1 + swap + # 0 stream skip + # 6 stream skip + # 10 stream skip + # 0 stream skip + # 6 stream skip + # 10 stream skip + # stream !d-> node1-data + # stream !d-> node2-data + # stream !d-> node3-data + # stream !d-> node4-data + # repeat + # swap 5 / node0-offsets +<- stack drop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue513.root")) as file: branch = file["Delphes/Jet/Jet.TrimmedP4[5]"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -645,10 +2032,37 @@ def test_54(is_forth): assert py[0][-1][4]["fE"] == 0.0 # py[-1] == array([[, , , , ], [, , , , ], [, , , , ], [, , , , ], [, , , , ], [, , , , ]], dtype=object) assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_55(is_forth): + # see AwkwardForth testing: P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data float32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # stream #!f-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-issue519.root")) as file: branch = file["testtree/testbranch"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -657,10 +2071,225 @@ def test_55(is_forth): assert py[-1][1][5] == pytest.approx(0.346174418926239) # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_56(is_forth): + # see AwkwardForth testing: A, C, D, E, F, G, J, L, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data uint8 + # output node2-data int16 + # output node3-data int32 + # output node4-data int64 + # output node5-data uint16 + # output node6-data uint32 + # output node7-data uint64 + # output node8-data float32 + # output node9-data float64 + # output node10-offsets int64 + # output node11-data uint8 + # output node12-data int32 + # output node13-data float64 + # output node14-data int32 + # output node15-data int16 + # output node16-offsets int64 + # output node17-data int32 + # output node18-offsets int64 + # output node19-data int64 + # output node20-offsets int64 + # output node21-data uint16 + # output node22-offsets int64 + # output node23-data uint32 + # output node24-offsets int64 + # output node25-data uint64 + # output node26-offsets int64 + # output node27-data float32 + # output node28-offsets int64 + # output node29-data float64 + # output node30-offsets int64 + # output node31-data uint32 + # output node32-data int16 + # output node33-offsets int64 + # output node34-data int32 + # output node35-offsets int64 + # output node36-data int64 + # output node37-offsets int64 + # output node38-data uint16 + # output node39-offsets int64 + # output node40-data uint32 + # output node41-offsets int64 + # output node42-data uint64 + # output node43-offsets int64 + # output node44-data float32 + # output node45-offsets int64 + # output node46-data float64 + # output node47-offsets int64 + # output node48-offsets int64 + # output node49-data uint8 + # output node50-offsets int64 + # output node51-data int16 + # output node52-offsets int64 + # output node53-data int32 + # output node54-offsets int64 + # output node55-data int64 + # output node56-offsets int64 + # output node57-data uint16 + # output node58-offsets int64 + # output node59-data uint32 + # output node60-offsets int64 + # output node61-data uint64 + # output node62-offsets int64 + # output node63-data float32 + # output node64-offsets int64 + # output node65-data float64 + # output node66-offsets int64 + # output node67-offsets int64 + # output node68-data uint8 + # output node69-offsets int64 + # output node70-data uint8 + # + # 0 node0-offsets <- stack + # 0 node10-offsets <- stack + # 0 node16-offsets <- stack + # 0 node18-offsets <- stack + # 0 node20-offsets <- stack + # 0 node22-offsets <- stack + # 0 node24-offsets <- stack + # 0 node26-offsets <- stack + # 0 node28-offsets <- stack + # 0 node30-offsets <- stack + # variable var_N + # 0 node33-offsets <- stack + # 0 node35-offsets <- stack + # 0 node37-offsets <- stack + # 0 node39-offsets <- stack + # 0 node41-offsets <- stack + # 0 node43-offsets <- stack + # 0 node45-offsets <- stack + # 0 node47-offsets <- stack + # 0 node48-offsets <- stack + # 0 node50-offsets <- stack + # 0 node52-offsets <- stack + # 0 node54-offsets <- stack + # 0 node56-offsets <- stack + # 0 node58-offsets <- stack + # 0 node60-offsets <- stack + # 0 node62-offsets <- stack + # 0 node64-offsets <- stack + # 0 node66-offsets <- stack + # 0 node67-offsets <- stack + # 0 node69-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 0 stream skip + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node0-offsets +<- stack stream #!B-> node1-data + # stream !h-> node2-data + # stream !i-> node3-data + # stream !q-> node4-data + # stream !H-> node5-data + # stream !I-> node6-data + # stream !Q-> node7-data + # stream !f-> node8-data + # stream !d-> node9-data + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node10-offsets +<- stack stream #!B-> node11-data + # 0 stream skip + # 6 stream skip + # 4 stream skip + # stream !i-> node12-data + # stream !d-> node13-data + # stream !i-> node14-data + # 10 dup node16-offsets +<- stack + # stream #!h-> node15-data + # 10 dup node18-offsets +<- stack + # stream #!i-> node17-data + # 10 dup node20-offsets +<- stack + # stream #!q-> node19-data + # 10 dup node22-offsets +<- stack + # stream #!H-> node21-data + # 10 dup node24-offsets +<- stack + # stream #!I-> node23-data + # 10 dup node26-offsets +<- stack + # stream #!Q-> node25-data + # 10 dup node28-offsets +<- stack + # stream #!f-> node27-data + # 10 dup node30-offsets +<- stack + # stream #!d-> node29-data + # stream !I-> stack dup var_N ! node31-data <- stack + # 1 stream skip + # var_N @ dup node33-offsets +<- stack + # stream #!h-> node32-data + # 1 stream skip + # var_N @ dup node35-offsets +<- stack + # stream #!i-> node34-data + # 1 stream skip + # var_N @ dup node37-offsets +<- stack + # stream #!q-> node36-data + # 1 stream skip + # var_N @ dup node39-offsets +<- stack + # stream #!H-> node38-data + # 1 stream skip + # var_N @ dup node41-offsets +<- stack + # stream #!I-> node40-data + # 1 stream skip + # var_N @ dup node43-offsets +<- stack + # stream #!Q-> node42-data + # 1 stream skip + # var_N @ dup node45-offsets +<- stack + # stream #!f-> node44-data + # 1 stream skip + # var_N @ dup node47-offsets +<- stack + # stream #!d-> node46-data + # 6 stream skip + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node48-offsets +<- stack stream #!B-> node49-data + # 6 stream skip + # stream !I-> stack + # dup node50-offsets +<- stack + # stream #!h-> node51-data + # 6 stream skip + # stream !I-> stack + # dup node52-offsets +<- stack + # stream #!i-> node53-data + # 6 stream skip + # stream !I-> stack + # dup node54-offsets +<- stack + # stream #!q-> node55-data + # 6 stream skip + # stream !I-> stack + # dup node56-offsets +<- stack + # stream #!H-> node57-data + # 6 stream skip + # stream !I-> stack + # dup node58-offsets +<- stack + # stream #!I-> node59-data + # 6 stream skip + # stream !I-> stack + # dup node60-offsets +<- stack + # stream #!Q-> node61-data + # 6 stream skip + # stream !I-> stack + # dup node62-offsets +<- stack + # stream #!f-> node63-data + # 6 stream skip + # stream !I-> stack + # dup node64-offsets +<- stack + # stream #!d-> node65-data + # 6 stream skip + # stream !I-> stack + # dup node66-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node67-offsets +<- stack stream #!B-> node68-data + # loop + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node69-offsets +<- stack stream #!B-> node70-data + # + # loop with uproot.open( skhep_testdata.data_path("uproot-small-evnt-tree-nosplit.root") ) as file: @@ -671,231 +2300,808 @@ def test_56(is_forth): assert py[1]["SliceU64"][0] == 1 # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_57(is_forth): + # see AwkwardForth testing: L, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/vector_string"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[-1][1] == "two" + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_58(is_forth): + # see AwkwardForth testing: L, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/vector_tstring"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth - py = branch.array(interp, library="ak", entry_stop=2) + py = branch.array(interp, library="ak") assert py[1][1] == "two" + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_59(is_forth): + # see AwkwardForth testing: P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data int32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # stream #!i-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/vector_vector_int32"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[-1][1][1] == 2 + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_60(is_forth): + # see AwkwardForth testing: L, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-offsets int64 + # output node3-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # 0 node2-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node2-offsets +<- stack stream #!B-> node3-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/vector_vector_string"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[-1][1][1] == "two" + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_61(is_forth): + # see AwkwardForth testing: L, P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-offsets int64 + # output node3-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # 0 node2-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node2-offsets +<- stack stream #!B-> node3-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/vector_vector_tstring"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[-1][1][1] == "two" + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_62(is_forth): + # see AwkwardForth testing: P, Q + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data int32 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # stream #!i-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/vector_set_int32"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[-1][1][1] == 2 + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_63(is_forth): + # see AwkwardForth testing: L, P, Q + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-offsets int64 + # output node3-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # 0 node2-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node2-offsets +<- stack stream #!B-> node3-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/vector_set_string"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[-1][1][1] == "two" + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_64(is_forth): + # see AwkwardForth testing: Q + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data int32 + # + # 0 node0-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # stream #!i-> node1-data + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/set_int32"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[-1][1] == 2 + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_65(is_forth): + # see AwkwardForth testing: L, Q + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/set_string"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[-1][1] == "two" + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_66(is_forth): + # see AwkwardForth testing: R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data int32 + # output node2-data int16 + # + # 0 node0-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # dup + # stream #!i-> node1-data + # stream #!h-> node2-data + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_int32_int16"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[-1]["1"][1] == 2 + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_67(is_forth): + # see AwkwardForth testing: P, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data int32 + # output node2-offsets int64 + # output node3-data int16 + # + # 0 node0-offsets <- stack + # 0 node2-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # dup + # stream #!i-> node1-data + # 6 stream skip + # 0 do + # stream !I-> stack + # dup node2-offsets +<- stack + # stream #!h-> node3-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_int32_vector_int16"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[1][1]["1"][1] == 2 + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_68(is_forth): + # see AwkwardForth testing: L, P, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data int32 + # output node2-offsets int64 + # output node3-offsets int64 + # output node4-data uint8 + # + # 0 node0-offsets <- stack + # 0 node2-offsets <- stack + # 0 node3-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # dup + # stream #!i-> node1-data + # 6 stream skip + # 0 do + # stream !I-> stack + # dup node2-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node3-offsets +<- stack stream #!B-> node4-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_int32_vector_string"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[1][1]["1"][1] == "two" + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_69(is_forth): + # see AwkwardForth testing: Q, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data int32 + # output node2-offsets int64 + # output node3-data int16 + # + # 0 node0-offsets <- stack + # 0 node2-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # dup + # stream #!i-> node1-data + # 6 stream skip + # 0 do + # stream !I-> stack + # dup node2-offsets +<- stack + # stream #!h-> node3-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_int32_set_int16"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[1][1]["1"][1] == 2 + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_70(is_forth): + # see AwkwardForth testing: L, Q, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data int32 + # output node2-offsets int64 + # output node3-offsets int64 + # output node4-data uint8 + # + # 0 node0-offsets <- stack + # 0 node2-offsets <- stack + # 0 node3-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # dup + # stream #!i-> node1-data + # 6 stream skip + # 0 do + # stream !I-> stack + # dup node2-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node3-offsets +<- stack stream #!B-> node4-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_int32_set_string"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[1][1]["1"][1] == "two" + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_71(is_forth): + # see AwkwardForth testing: L, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # output node3-data int16 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 6 stream skip + # dup 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # stream #!h-> node3-data + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_string_int16"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[1][1]["1"] == 2 + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_72(is_forth): + # see AwkwardForth testing: L, P, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # output node3-offsets int64 + # output node4-data int16 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # 0 node3-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 6 stream skip + # dup 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # 6 stream skip + # 0 do + # stream !I-> stack + # dup node3-offsets +<- stack + # stream #!h-> node4-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_string_vector_int16"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[1][1]["1"][1] == 2 + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_73(is_forth): + # see AwkwardForth testing: L, P, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # output node3-offsets int64 + # output node4-offsets int64 + # output node5-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # 0 node3-offsets <- stack + # 0 node4-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 6 stream skip + # dup 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # 6 stream skip + # 0 do + # stream !I-> stack + # dup node3-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node4-offsets +<- stack stream #!B-> node5-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_string_vector_string"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[1][1]["1"][1] == "two" + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_74(is_forth): + # see AwkwardForth testing: L, Q, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # output node3-offsets int64 + # output node4-data int16 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # 0 node3-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 6 stream skip + # dup 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # 6 stream skip + # 0 do + # stream !I-> stack + # dup node3-offsets +<- stack + # stream #!h-> node4-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_string_set_int16"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[1][1]["1"][1] == 2 + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_75(is_forth): + # see AwkwardForth testing: L, Q, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # output node3-offsets int64 + # output node4-offsets int64 + # output node5-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # 0 node3-offsets <- stack + # 0 node4-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 6 stream skip + # dup 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # 6 stream skip + # 0 do + # stream !I-> stack + # dup node3-offsets +<- stack + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node4-offsets +<- stack stream #!B-> node5-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_string_set_string"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) + if is_forth: + assert interp._complete_forth_code is not None assert py[1][1]["1"][1] == "two" # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @@ -903,11 +3109,48 @@ def test_75(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_76(is_forth): + # see AwkwardForth testing: P, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data int32 + # output node2-offsets int64 + # output node3-offsets int64 + # output node4-data int16 + # + # 0 node0-offsets <- stack + # 0 node2-offsets <- stack + # 0 node3-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # dup + # stream #!i-> node1-data + # 6 stream skip + # 0 do + # stream !I-> stack + # dup node2-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node3-offsets +<- stack + # stream #!h-> node4-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_int32_vector_vector_int16"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) + if is_forth: + assert interp._complete_forth_code is not None assert py[1][1]["1"][1][1] == 2 # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @@ -915,23 +3158,93 @@ def test_76(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_77(is_forth): + # see AwkwardForth testing: P, Q, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-data int32 + # output node2-offsets int64 + # output node3-offsets int64 + # output node4-data int16 + # + # 0 node0-offsets <- stack + # 0 node2-offsets <- stack + # 0 node3-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # dup + # stream #!i-> node1-data + # 6 stream skip + # 0 do + # stream !I-> stack + # dup node2-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node3-offsets +<- stack + # stream #!h-> node4-data + # loop + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_int32_vector_set_int16"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) assert py[1][1]["1"][1][1] == 2 + if is_forth: + assert interp._complete_forth_code is not None # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @pytest.mark.parametrize("is_forth", [False, True]) def test_78(is_forth): + # see AwkwardForth testing: L, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # output node3-offsets int64 + # output node4-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # 0 node3-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 6 stream skip + # dup 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # 6 stream skip + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node3-offsets +<- stack stream #!B-> node4-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_string_string"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) + if is_forth: + assert interp._complete_forth_code is not None assert py[1, 1, "1"] == "TWO" # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) @@ -939,6 +3252,36 @@ def test_78(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_79(is_forth): + # see AwkwardForth testing: L, R + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data uint8 + # output node3-offsets int64 + # output node4-data uint8 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # 0 node3-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 12 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 6 stream skip + # dup 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node1-offsets +<- stack stream #!B-> node2-data + # loop + # 0 do + # stream !B-> stack dup 255 = if drop stream !I-> stack then dup node3-offsets +<- stack stream #!B-> node4-data + # loop + # + # loop with uproot.open(skhep_testdata.data_path("uproot-stl_containers.root")) as file: branch = file["tree/map_string_tstring"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) @@ -947,10 +3290,37 @@ def test_79(is_forth): assert py[1, 1, "1"] == "TWO" # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) def test_80(is_forth): + # see AwkwardForth testing: P + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-offsets int64 + # output node1-offsets int64 + # output node2-data float64 + # + # 0 node0-offsets <- stack + # 0 node1-offsets <- stack + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 6 stream skip + # stream !I-> stack + # dup node0-offsets +<- stack + # 0 do + # stream !I-> stack + # dup node1-offsets +<- stack + # stream #!d-> node2-data + # loop + # + # loop with uproot.open( skhep_testdata.data_path("uproot-vectorVectorDouble.root") ) as file: @@ -958,6 +3328,8 @@ def test_80(is_forth): interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak") + if is_forth: + assert interp._complete_forth_code is not None assert py.tolist() == [ [], [[], []], @@ -970,11 +3342,34 @@ def test_80(is_forth): @pytest.mark.parametrize("is_forth", [False, True]) def test_81(is_forth): + # see AwkwardForth testing: (none?) + # Expected AwkwardForth code: + # input stream + # input byteoffsets + # input bytestops + # output node0-data float64 + # output node1-data float64 + # + # + # 0 do + # byteoffsets I-> stack + # stream seek + # 0 stream skip + # 6 stream skip + # 10 stream skip + # stream !d-> node0-data + # stream !d-> node1-data + # + # loop with uproot.open(skhep_testdata.data_path("uproot-HZZ-objects.root")) as file: branch = file["events/MET"] interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) interp._forth = is_forth py = branch.array(interp, library="ak", entry_stop=2) + if is_forth: + assert interp._complete_forth_code is not None assert py[0]["fY"] == pytest.approx(2.5636332035064697) # py[-1] == assert py.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None diff --git a/tests/test_0692_fsspec_writing.py b/tests/test_0692_fsspec_writing.py index 9e089d56b..5cb73b1ef 100644 --- a/tests/test_0692_fsspec_writing.py +++ b/tests/test_0692_fsspec_writing.py @@ -130,13 +130,8 @@ def test_fsspec_writing_ssh(tmp_path, scheme): def test_fsspec_writing_memory(tmp_path, scheme): uri = f"{scheme}{tmp_path}/file.root" - # when https://github.com/fsspec/filesystem_spec/pull/1426 is merged this will work, we must remove the catch - with pytest.raises(ValueError): - with uproot.recreate(uri) as f: - f["tree"] = {"x": np.array([1, 2, 3])} - - with uproot.open(uri) as f: - assert f["tree"]["x"].array().tolist() == [1, 2, 3] + with uproot.recreate(uri) as f: + f["tree"] = {"x": np.array([1, 2, 3])} - if scheme == "simplecache::memory://": - raise ValueError("wait for next fsspec release and remove this") + with uproot.open(uri) as f: + assert f["tree"]["x"].array().tolist() == [1, 2, 3] diff --git a/tests/test_0798_DAOD_PHYSLITE.py b/tests/test_0798_DAOD_PHYSLITE.py index d3877a44c..320abe399 100644 --- a/tests/test_0798_DAOD_PHYSLITE.py +++ b/tests/test_0798_DAOD_PHYSLITE.py @@ -36,6 +36,8 @@ def test_AnalysisJetsAuxDyn_GhostTrack(is_forth): assert str(array.type) == expected_type assert array[0, 0].tolist() == expected_data assert array.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) @@ -58,6 +60,8 @@ def test_TruthBosonAuxDyn_childLinks(is_forth): assert str(array.type) == expected_type assert array[0].tolist() == expected_data assert array.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) @@ -81,6 +85,8 @@ def test_TruthPhotonsAuxDyn_parentLinks(is_forth): assert str(array.type) == expected_type assert array[0].tolist() == expected_data assert array.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None @pytest.mark.parametrize("is_forth", [False, True]) @@ -101,3 +107,5 @@ def test_TruthTopAuxDyn_parentLinks(is_forth): assert str(array.type) == expected_type assert array[0].tolist() == expected_data assert array.layout.form == interp.awkward_form(branch.file) + if is_forth: + assert interp._complete_forth_code is not None diff --git a/tests/test_0912-fix-pandas-and-double-nested-vectors-issue-885.py b/tests/test_0912-fix-pandas-and-double-nested-vectors-issue-885.py index 168eeee9c..48399daf5 100644 --- a/tests/test_0912-fix-pandas-and-double-nested-vectors-issue-885.py +++ b/tests/test_0912-fix-pandas-and-double-nested-vectors-issue-885.py @@ -52,3 +52,9 @@ def test_pandas_and_double_nested_vectors_issue_885(tmp_path): assert ak.to_list(u["2Dvector"][0]) == [[0, 1, 2], [0, 1, 2, 3, 4]] assert ak.to_list(u["1Dvector"][0]) == [1, 2, 3, 4] assert ak.to_list(u["othervector"][0]) == [0, 1, 3, 4, 5, 6, 7, 8, 9] + + branch = fs["2Dvector"] + interp = uproot.interpretation.identify.interpretation_of(branch, {}, False) + interp._forth = False + u2 = branch.array(interp, library="pd") + assert isinstance(u2[0], ak.highlevel.Array)