Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 35 additions & 9 deletions uproot/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -792,19 +792,45 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True):
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:
raise NotImplementedError(
"""memberwise serialization of {0}
in file {1}""".format(
type(self).__name__, selffile.file_path
# let's hard-code in logic for std::pair<T1,T2> for now
if not _value_typename.startswith("pair"):
raise NotImplementedError(
"""memberwise serialization of {0}({1})
in file {2}""".format(
type(self).__name__, _value_typename, selffile.file_path
)
)
)

length = cursor.field(chunk, _stl_container_size, context)
# there's extra stuff, maybe?
_num_memberwise_bytes = cursor.field(chunk, _stl_container_size, context)
_something_else = cursor.field(chunk, struct.Struct(">H"), context)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This portion that we're at right now looks like

--+---+---+---+---+---+---+---+---+---+
  0   0   0 215 190 210   0   0   0  13  
--- --- --- --- --- --- --- --- --- --- 

Unclear what the first 6 bytes are here, but the last 4 seem to be number of elements in the vector (length) in the line below. I assumed it might be 4 bytes / 2 bytes but still not sure what they're meant to match up with.


# length is number of elements in vector
length = cursor.field(chunk, _stl_container_size, context)

model = self._values.new_class(file, "max")

# make a shell
values = numpy.empty(length, dtype=_stl_object_type)
for i in uproot._util.range(length):
values[i] = model.read(
chunk, cursor, {**context, "reading": False}, file, selffile, parent
)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here, we make a shell, which means we skip actually reading anything out (in this case, this means "moving the cursor"). We'd just want to inflate all of our classes/objects so we can ask them to each read the file one by one to fill member-wise (see next block).


# memberwise reading!
for member_index in uproot._util.range(len(values[0].member_names)):
for i in uproot._util.range(length):
values[i].read_member_n(chunk, cursor, context, file, member_index)
else:
length = cursor.field(chunk, _stl_container_size, context)

values = _read_nested(
self._values, length, chunk, cursor, context, file, selffile, parent
)

values = _read_nested(
self._values, length, chunk, cursor, context, file, selffile, parent
)
out = STLVector(values)

if self._header and header:
Expand Down
64 changes: 34 additions & 30 deletions uproot/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -760,30 +760,33 @@ def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None):
old_breadcrumbs = context.get("breadcrumbs", ())
context["breadcrumbs"] = old_breadcrumbs + (self,)

self.hook_before_read(chunk=chunk, cursor=cursor, context=context, file=file)

self.read_numbytes_version(chunk, cursor, context)

if (
issubclass(cls, VersionedModel)
and self._instance_version != classname_version(cls.__name__)
and self._instance_version is not None
):
correct_cls = file.class_named(self.classname, self._instance_version)
if classname_version(correct_cls.__name__) != classname_version(
cls.__name__
if context.get("reading", True):
self.hook_before_read(
chunk=chunk, cursor=cursor, context=context, file=file
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to take this hook out of the if context.get("reading", True) because we're already in the read method. The read_members method, on the other hand, gets entirely skipped.


self.read_numbytes_version(chunk, cursor, context)

if (
issubclass(cls, VersionedModel)
and self._instance_version != classname_version(cls.__name__)
and self._instance_version is not None
):
cursor.move_to(self._cursor.index)
context["breadcrumbs"] = old_breadcrumbs
return correct_cls.read(
chunk,
cursor,
context,
file,
selffile,
parent,
concrete=concrete,
)
correct_cls = file.class_named(self.classname, self._instance_version)
if classname_version(correct_cls.__name__) != classname_version(
cls.__name__
):
cursor.move_to(self._cursor.index)
context["breadcrumbs"] = old_breadcrumbs
return correct_cls.read(
chunk,
cursor,
context,
file,
selffile,
parent,
concrete=concrete,
)

if context.get("in_TBranch", False):
if self._num_bytes is None and self._instance_version != self.class_version:
Expand All @@ -793,15 +796,16 @@ def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None):
elif self._instance_version == 0:
cursor.skip(4)

self.hook_before_read_members(
chunk=chunk, cursor=cursor, context=context, file=file
)
if context.get("reading", True):
self.hook_before_read_members(
chunk=chunk, cursor=cursor, context=context, file=file
)

self.read_members(chunk, cursor, context, file)
self.read_members(chunk, cursor, context, file)

self.hook_after_read_members(
chunk=chunk, cursor=cursor, context=context, file=file
)
self.hook_after_read_members(
chunk=chunk, cursor=cursor, context=context, file=file
)

self.check_numbytes(chunk, cursor, context)

Expand Down
Loading