Skip to content

Commit

Permalink
Introduce a ByteString model field
Browse files Browse the repository at this point in the history
As models have to be JSON-serializable and byte
fields apparently don't fit in, let's introduce
a special model field type that could be used in
such situations.
Basic ByteString serialization tests added.

OAMG-4306
  • Loading branch information
fernflower committed Jul 29, 2022
1 parent 85d7548 commit 9201e95
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
28 changes: 28 additions & 0 deletions leapp/models/fields/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import base64
import copy
import datetime
import json
Expand Down Expand Up @@ -239,6 +240,33 @@ def _model_type(self):
return six.string_types + (six.binary_type,)


class ByteString(BuiltinField):
"""
ByteString field
"""
@property
def _model_type(self):
# NOTE(ivasilev) Both string_types and binary_types are necessary here to pass value checks on
# serialization/deserialization. Serialized JSON-friendly model will have of a string type field (the base64
# ascii string) while deserialized model will have a binary type field.
return six.string_types + (six.binary_type,)

def _convert_to_model(self, value, name):
self._validate_model_value(value=value, name=name)
if not value:
return value

return base64.b64decode(value)

def _convert_from_model(self, value, name):
self._validate_model_value(value=value, name=name)
if not value:
return value

# NOTE(ivasilev) b64 encoding is always ascii, thus ascii decoding to get a string
return base64.b64encode(value).decode('ascii')


class DateTime(BuiltinField):
"""
DateTime field to handle datetime objects which are converted to the ISO format and parsed back from there
Expand Down
11 changes: 11 additions & 0 deletions tests/scripts/test_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ class WithNestedListModel(Model):
items = fields.List(fields.Model(BasicModel))


class WithByteStringModel(Model):
topic = ModelTestTopic
message = fields.ByteString()


class AllFieldTypesModel(Model):
topic = ModelTestTopic
float_field = fields.Float(default=3.14)
Expand Down Expand Up @@ -74,6 +79,12 @@ def test_basic_model():
assert m.message == m2.message


def test_bytestring_model():
m = WithByteStringModel(message=b'\xf3\xcf\xcf\xc2\xdd\xc5\xce\xc9\xc5')
m2 = WithByteStringModel.create(m.dump())
assert m.message == m2.message


def test_string_list_model():
m = WithStringListModel(messages=['Some message'])
m2 = WithStringListModel.create(m.dump())
Expand Down

0 comments on commit 9201e95

Please sign in to comment.