Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StripeObject: only add changed values to _unsaved_values #372

Merged
merged 3 commits into from
Nov 29, 2017

Conversation

blueyed
Copy link
Contributor

@blueyed blueyed commented Nov 13, 2017

No description provided.

@blueyed
Copy link
Contributor Author

blueyed commented Nov 13, 2017

It would still trigger an update for metadata, which is mentioned in

# Note: ideally, we'd want the library to NOT issue requests in this
# case (i.e. the assert should actually be `assert_not_called()`).
self.requestor_mock.request.assert_called_with(
'post',
'/v1/myupdateables/myid',
{'metadata': {}},
None
)
.

I've also found https://github.com/blueyed/stripe-python/blob/1751c911b497c37cb60bdf74eeb4073b04ef423c/tests/api_resources/abstract/test_updateable_api_resource.py#L301-L306, which seems even to be incorrect?! Doesn't it empty legal_entity.address?

@ob-stripe
Copy link
Contributor

Hey @blueyed, thanks a lot for the contribution! This looks very promising.

Doesn't it empty legal_entity.address?

So, no, although I can see why you'd think so! We mock APIRequestor, which can receive empty dicts. Those will be ignored in the outgoing request though:

>>> list(stripe.api_requestor._api_encode({'metadata': {}}))
[]

I agree it would be better and clearer if APIRequestor would not receive empty dicts in the first place! I'll take a closer look at your patch today.

@@ -237,7 +238,9 @@ def serialize(self, previous):
elif isinstance(v, stripe.api_resources.abstract.APIResource):
continue
elif hasattr(v, 'serialize'):
params[k] = v.serialize(previous.get(k, None))
child = v.serialize(previous.get(k, None))
if child:
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure if it's possible in practice, but in theory serialize could return an empty string "" to unset the entire attribute, and because empty strings are falsey in Python this would get ignored. It might be better to explicitly compare the returned value to an empty dict.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense.
Should have a test for it then, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if it's possible in practice

The two internal serialize methods will return a dict always, so it is unlikely to come from there.

Added a test with a specialized StripeObject, which is likely what you had in mind?!

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, exactly. Thanks again!

@ob-stripe
Copy link
Contributor

I left a comment, but generally this looks pretty great to me!

r? @deontologician-stripe Do you mind taking a look at this?

@deontologician-stripe
Copy link
Contributor

I am +1 on this. I wish we could do the checking for _unsaved_values in __setstate__ instead of just in time when it's needed, but that is unrelated to this PR.

@deontologician-stripe
Copy link
Contributor

r? @ob-stripe To approve after the test you mentioned in the comment is added

@ob-stripe
Copy link
Contributor

lgtm

@ob-stripe
Copy link
Contributor

@dpetrovics-stripe (dev-platform run, feel free to re-assign) Mind merging this and releasing a version? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants