Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 5 additions & 4 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ def test_generic_read(self):
path = os.path.join(self.repo_dir, 'metadata', metadata + '.json')
metadata_obj = Metadata.from_file(path)
with open(path, 'rb') as f:
metadata_str = f.read()
metadata_obj2 = JSONDeserializer().deserialize(metadata_str)
metadata_obj2 = Metadata.from_bytes(f.read())

# Assert that both methods instantiate the right inner class for
# each metadata type and ...
Expand All @@ -119,15 +118,17 @@ def test_generic_read(self):
self.assertDictEqual(
metadata_obj.to_dict(), metadata_obj2.to_dict())


# Assert that it chokes correctly on an unknown metadata type
bad_metadata_path = 'bad-metadata.json'
bad_metadata = {'signed': {'_type': 'bad-metadata'}}
bad_string = json.dumps(bad_metadata).encode('utf-8')
Copy link
Member

Choose a reason for hiding this comment

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

Is indentation off here, or is it just the GitHub app?

with open(bad_metadata_path, 'wb') as f:
f.write(json.dumps(bad_metadata).encode('utf-8'))
f.write(bad_string)

with self.assertRaises(DeserializationError):
Metadata.from_file(bad_metadata_path)
with self.assertRaises(DeserializationError):
Metadata.from_bytes(bad_string)

os.remove(bad_metadata_path)

Expand Down
34 changes: 27 additions & 7 deletions tuf/api/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,20 +128,40 @@ def from_file(
A TUF Metadata object.

"""
if storage_backend is None:
storage_backend = FilesystemBackend()

with storage_backend.get(filename) as file_obj:
return cls.from_bytes(file_obj.read(), deserializer)

@staticmethod
def from_bytes(
data: bytes,
deserializer: Optional[MetadataDeserializer] = None,
) -> "Metadata":
"""Loads TUF metadata from raw data.

Arguments:
data: metadata content as bytes.
deserializer: Optional; A MetadataDeserializer instance that
Copy link
Member

Choose a reason for hiding this comment

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

is this notation standard? Would we be better off just relying on the typing annotations to indicate optional arguments?

Copy link
Member Author

Choose a reason for hiding this comment

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

I saw that in a google style guide example -- could leave that out as well, it does duplicate the annotation...

Copy link
Member

Choose a reason for hiding this comment

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

Let's leave it for now. Could you create an issue to ensure we review docstrings and make sure they are consistent before we cut a release.

implements deserialization. Default is JSONDeserializer.

Raises:
tuf.api.serialization.DeserializationError:
The file cannot be deserialized.

Returns:
A TUF Metadata object.
"""

if deserializer is None:
# Use local scope import to avoid circular import errors
# pylint: disable=import-outside-toplevel
from tuf.api.serialization.json import JSONDeserializer

deserializer = JSONDeserializer()

if storage_backend is None:
storage_backend = FilesystemBackend()

with storage_backend.get(filename) as file_obj:
raw_data = file_obj.read()

return deserializer.deserialize(raw_data)
return deserializer.deserialize(data)

def to_dict(self) -> Dict[str, Any]:
"""Returns the dict representation of self. """
Expand Down