-
-
Notifications
You must be signed in to change notification settings - Fork 155
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
Use kw-only arguments where sensible #472
Conversation
Looks like this is not allowed in Python 3.5 def parse(
self,
argmap,
req=None,
*,
location=None,
validate=None,
error_status_code=None,
error_headers=None,
): I can't find a documented change in 3.6 explaining this. I could go with def parse(
self,
argmap,
*,
req=None,
location=None,
validate=None,
error_status_code=None,
error_headers=None,
): but wouldn't it be too much? |
Just in case someone else thinks of it, I tried the "too clever solution" of making parse's signature different in different pythons, but it doesn't work easily because py3.5 can't even parse the desired signature for 3.6+. I'll share because it's fun to think about: polyglot_parse decorator# decorate it to have different signatures
# doesn't work in py3.5
def polyglot_parse(real_parse_func):
if sys.version_info < (3, 6):
def parse(
self,
argmap,
req=None,
location=None,
validate=None,
error_status_code=None,
error_headers=None,
):
return real_parse_func(
self,
argmap,
req=req,
location=location,
validate=validate,
error_status_code=error_status_code,
error_headers=error_headers,
)
else:
def parse(
self,
argmap,
req=None,
*,
location=None,
validate=None,
error_status_code=None,
error_headers=None,
):
return real_parse_func(
self,
argmap,
req=req,
location=location,
validate=validate,
error_status_code=error_status_code,
error_headers=error_headers,
)
return parse It is possible if we're determined -- you can do things like adding a second module which only gets imported in 3.6, or write it all as a string and use There's also the "faking it" way with a def parse(
self,
argmap,
*args,
req=None,
location=None,
validate=None,
error_status_code=None,
error_headers=None,
):
if len(args) > 1:
raise ValueError
if args and req is not None:
raise ValueError
if args[0] is not None and req is None:
req = args[0]
... But this also seems awkward and undesirable. Python 3.5 EOLs later this year, but I don't want to wait that long to be able to use webargs 6. I'm not sure if there's a potential issue is with The major alternative I see is just leaving this as-is, on the grounds that we can't do what we really want. It can be changed in a later major version upgrade. |
Thanks for looking into this. I don't want to overthink it. I just exposed it here in the hope to get an explanation because I couldn't find any item in the changelog explaining this. I agree we don't want to do anything messy. Either we decide Or we just skip this method. No big deal either way. I'll settle this one way or another. |
bbc4054
to
7fe1c27
Compare
Ah ah. Turns out the issue was not exactly the kw-only thing but the trailing comma in the signature. Apparently, the trailing comma is fine, unless there is a kw-only So this works: def parse(
self,
argmap,
req=None,
*, # <-----------
location=None,
validate=None,
error_status_code=None,
error_headers=None
):
pass
def parse(
self,
argmap,
req=None,
location=None,
validate=None,
error_status_code=None,
error_headers=None, # <-----------
):
pass But this does not: def parse(
self,
argmap,
req=None,
*, # <-----------
location=None,
validate=None,
error_status_code=None,
error_headers=None, # <-----------
):
pass Go figure... (I just found an online Python 3.4 interpreter to test that.) |
Yeah, I just checked and that works on my py35 version (3.5.6). And I upgraded to 3.5.9 to check, works on that too. Weird though. shrugs |
src/webargs/core.py
Outdated
@@ -503,7 +515,7 @@ def load_files(self, req, schema): | |||
return missing | |||
|
|||
def handle_error( | |||
self, error, req, schema, error_status_code=None, error_headers=None | |||
self, error, req, *, schema, error_status_code=None, error_headers=None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should schema
be a required keyword-only arg?
I would have left all required arguments as positionals and made only the optional arguments (error_status_code
, error_headers
) keyword-only.
I also see some variation in the signatures for this in the various parsers, which I assume is accidental.
This is not critical, since handle_error
is only really called internally and exposed as a hook for users to write something which gets called by webargs (if they write their own parser subclassing the core parser). But the two signatures which occur to me are
# everything keyword-only
def handle_error(
self, *, error, req, schema, error_status_code=None, error_headers=None
):
# optional args keyword-only
def handle_error(
self, error, req, schema, *, error_status_code=None, error_headers=None
):
7fe1c27
to
51db973
Compare
Thanks for reviewing. I pushed a new version. I didn't find the signature variations but anyway, I checked everywhere and I think it is fine, now. I also changed the signature in docstrings/docs. |
The thing which I see varying is whether or not I don't think this really has any impact -- those values should always be supplied when an error handler is called -- but now that I've noticed it, I can't help but suggest making them all identical. (If I'm reading correctly, this was actually slightly inconsistent before, with some locations declaring them as positional arguments and some as keyword arguments.) |
51db973
to
3360ce7
Compare
Good catch I reworked the PR to make these consistent.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me. I don't know if we need @sloria to weigh in on this or not.
(I am, after all, still just some guy on the Internet, not a maintainer. 😄 )
I'd like @sloria to approve the 6.0.0 release, be it before or after we merge this.
Good point. I just sent you an invitation to join the maintainers team. |
I'll take a look at the release when I have some time, but don't block on me! I consider @lafrech more the owner of webargs at this point. Also glad to see @sirosen as maintainer =). As discussed on Slack, my only hesitation here is P.S. @sirosen email me at sloria1 AT gmail.com if you'd like to join the marshmallow slack. |
3360ce7
to
3469728
Compare
3469728
to
528c56f
Compare
I agree. I just edited the PR to make |
I keep hesitating to merge this because the last couple of changes have been so small and subtle, but I think this is good now and I'm going to go ahead. Using my newfound powers! I think this takes us down to "last call" for changes in 6.0. |
Yep. Let's release a last beta. Then it leaves us a few days to update the docs (upgrading instructions) during which clients can provide feedback about the beta. |
I was about to write an upgrading guide, but on second thought, the comprehensive instructions in the CHANGELOG should be enough. I didn't see the point of duplicating them in another doc page. |
Closes the second item in #440.