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

Add decorator-based pre/post-dump/load support #191

Merged
merged 3 commits into from
Apr 18, 2015

Conversation

taion
Copy link
Contributor

@taion taion commented Apr 9, 2015

For #153

@taion
Copy link
Contributor Author

taion commented Apr 9, 2015

Two open questions:

  1. What do you want to do about deprecating the old hooks? I didn't add any deprecation warnings.
  2. In general the pattern for these is going to be mutating the passed-in item. I forgot to return the item a few times. It might improve ergonomics to just assume that the passed-in object was mutated in-place if the processor function returns None.

@sloria
Copy link
Member

sloria commented Apr 10, 2015

What do you want to do about deprecating the old hooks?

preprocessor, data_handler, and extra can all be deprecated, but I think we can defer that for now until this new API is finalized.

It might improve ergonomics to just assume that the passed-in object was mutated in-place if the processor function returns None.

I agree.

@sloria
Copy link
Member

sloria commented Apr 10, 2015

@taion Thanks for your work on this. I will look at this more in-depth over the weekend.

mro = klass.mro()

klass.processors = defaultdict(list)
for attr_name in dir(klass):
Copy link
Contributor

Choose a reason for hiding this comment

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

dir apparently returns an alphabetical list of attributes, meaning that decorated methods might not be applied in order expected by the developer. You might use inspect or store a counter on the decorators to get the right order.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you think we need to guarantee order beyond "raw processors last when dumping, raw processors first when loading"? I feel that this would not be an especially obvious feature, and that ordering dependencies would be better expressed by putting them in the same processor, rather than depending on some guaranteed order.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed that users should handle order by putting ordered operations in the same callback. But they might not, and if they don't, I could imagine this being a debugging headache. Anyway, if we don't want callbacks to run in any particular order, the docs should be clear about that, so that users don't make assumptions and get confused.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd be inclined to go with telling users not to depend on any ordering guarantees in the docs. It just seems like not the best idea. @sloria what do you think?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I think the docs should clearly state that ordering is not guaranteed.

POST_LOAD = 'post_load'


def pre_dump(*args, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

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

For documentation purposes, it might be clearer to explicitly include raw in these signatures. The tag_processor includes the raw value in the tuple tags anyway.

@sloria
Copy link
Member

sloria commented Apr 14, 2015

Looking good so far @taion . Let me know when this is ready for further review.

@taion
Copy link
Contributor Author

taion commented Apr 15, 2015

New commit includes (2) from my 1st comment about treating None return values (implicit or otherwise) from processors as meaning that the element was modified in place, in addition to what was mentioned in comments on commit.

# the class, we let standard inheritance do all the hard work.
mro = klass.mro()

klass.__processors__ = defaultdict(list)
Copy link
Member

Choose a reason for hiding this comment

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

Can this "processor tag" logic be put in a separate helper function or method?

@sloria
Copy link
Member

sloria commented Apr 17, 2015

Just a minor nitpicky refactor, and this should be good to merge!

@taion
Copy link
Contributor Author

taion commented Apr 17, 2015

Done. Is this for 2.x, or will there be a 1.3 line that includes new features without removing old ones?

@sloria
Copy link
Member

sloria commented Apr 18, 2015

Thanks @taion . This will go into 2.0-a.

sloria added a commit that referenced this pull request Apr 18, 2015
Add decorator-based pre/post-dump/load support
@sloria sloria merged commit 3a9a299 into marshmallow-code:dev Apr 18, 2015
@sloria sloria added this to the 2.0-a milestone Apr 18, 2015
@taion taion deleted the jjia/processors branch April 26, 2015 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants