Skip to content

Commit

Permalink
Merge pull request #108 from ibrewster/develop
Browse files Browse the repository at this point in the history
Add ListTarget and associated test case
  • Loading branch information
siddhantgoel authored Jul 28, 2024
2 parents fd16383 + 95b7662 commit 77fe21d
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
41 changes: 41 additions & 0 deletions streaming_form_data/targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,47 @@ def value(self):
return b"".join(self._values)


class ListTarget(BaseTarget):
"""ListTarget stores the input in an in-memory list of bytes,
which is then joined into the final value and appended to an in-memory
list of byte strings when each value is finished.
This is usefull for situations where more than one value may be submitted for
the same argument.
"""

def __init__(self, _type=bytes, *args, **kwargs):
super().__init__(*args, **kwargs)

self._temp_value = []
self._values = []
self._type = _type

def on_data_received(self, chunk: bytes):
self._temp_value.append(chunk)

def on_finish(self):
value = b"".join(self._temp_value)
self._temp_value = []

if self._type == str:
value = value.decode("UTF-8")
elif self._type == bytes:
pass # already is bytes, no need to do anything
else:
value = self._type(value)

self._values.append(value)

@property
def value(self):
return self._values

@property
def finished(self):
return self._finished


class FileTarget(BaseTarget):
"""FileTarget writes (streams) the input to an on-disk file."""

Expand Down
33 changes: 33 additions & 0 deletions tests/test_targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
DirectoryTarget,
NullTarget,
ValueTarget,
ListTarget,
S3Target,
CSVTarget,
)
Expand Down Expand Up @@ -82,6 +83,38 @@ def test_value_target_total_size_validator():
target.data_received(b"world")


def test_list_target_basic():
target = ListTarget()

assert target.value == []

target.multipart_filename = None

target.start()
assert target.multipart_filename is None
assert target.value == []

# Send and finish multiple values
target.data_received(b"Cat")
target.finish()
target.data_received(b"Dog")
target.finish()
target.data_received(b"Big")
target.data_received(b" ")
target.data_received(b"Goldfish")
target.finish()

assert target.multipart_filename is None
assert target.value == [b"Cat", b"Dog", b"Big Goldfish"]


def test_list_target_not_set():
target = ListTarget()

assert target.multipart_filename is None
assert target.value == []


def test_file_target_basic():
filename = os.path.join(tempfile.gettempdir(), "file.txt")

Expand Down

0 comments on commit 77fe21d

Please sign in to comment.