-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Automatically strip MISSING from payloads
This change updates payload serialization in two significant ways: - MISSING is automatically removed from payloads, and this is applied recursively. This means that it can be included anywhere in a (well-formed) body and the SDK will find and remove it. Custom types inside of the payload could interfere, but native dict/list structures and PayloadWrapper objects are fully supported - PayloadWrapper types are recursively converted to dicts, meaning that it is now valid to construct a helper type based on PayloadWrapper which is nested As a result of this change, simplify the GroupPolicies code to always assign the ha timeout (with a default value of MISSING) and replace the unit test for this behavior with a functional test. The new recursive conversion was benchmarked against a version which was micro-optimized to avoid deep-copying of dict and list data, and found to be nearly 2x *faster* than the optimized version on a typical payload, by virtue of the fact that it did not make unnecessary method calls.
- Loading branch information
Showing
7 changed files
with
105 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import pytest | ||
|
||
from globus_sdk import utils | ||
|
||
|
||
def test_payload_preparation_strips_missing_dict(): | ||
original = {"foo": None, "bar": utils.MISSING} | ||
prepared = utils.PayloadWrapper._prepare(original) | ||
assert prepared == {"foo": None} | ||
|
||
|
||
# this is a weird case (not really recommended usage), but we have well defined behavior | ||
# for it, so exercise it here | ||
@pytest.mark.parametrize("type_", (list, tuple)) | ||
def test_payload_preparation_strips_missing_list_or_tuple(type_): | ||
original = type_([None, 1, utils.MISSING, 0]) | ||
prepared = utils.PayloadWrapper._prepare(original) | ||
assert prepared == [None, 1, 0] | ||
|
||
|
||
@pytest.mark.parametrize("original", (None, 1, 0, True, False, "foo", object())) | ||
def test_payload_preparation_retains_simple_datatype_identity(original): | ||
prepared = utils.PayloadWrapper._prepare(original) | ||
# check not only that the values are equal, but that they pass the identity test | ||
assert prepared is original | ||
|
||
|
||
# this test makes sense in the context of the identity test above: | ||
# check that the values are equal, although the type may be reconstructed | ||
@pytest.mark.parametrize("original", (["foo", "bar"], {"foo": "bar"})) | ||
def test_payload_preparation_retains_complex_datatype_equality(original): | ||
prepared = utils.PayloadWrapper._prepare(original) | ||
assert prepared == original | ||
|
||
|
||
def test_payload_preparation_dictifies_wrappers(): | ||
x = utils.PayloadWrapper() | ||
x["foo"] = 1 | ||
prepared = utils.PayloadWrapper._prepare(x) | ||
assert prepared == {"foo": 1} | ||
assert isinstance(prepared, dict) | ||
assert prepared is not x | ||
assert not isinstance(prepared, utils.PayloadWrapper) | ||
|
||
|
||
def test_payload_preparation_recursively_dictifies_wrappers(): | ||
x = utils.PayloadWrapper() | ||
x["foo"] = 1 | ||
y = utils.PayloadWrapper() | ||
y["bar"] = x | ||
y["baz"] = [2, x] | ||
prepared = utils.PayloadWrapper._prepare(y) | ||
assert prepared == {"bar": {"foo": 1}, "baz": [2, {"foo": 1}]} |