-
Notifications
You must be signed in to change notification settings - Fork 215
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
Fix Optional
failing when default
is some builtins
#276
base: master
Are you sure you want to change the base?
Fix Optional
failing when default
is some builtins
#276
Conversation
bd13180
to
9213184
Compare
Optional
failing when default
is some builtins, and fix incompatibility with Python 2.7Optional
failing when default
is some builtins, and fix incompatibility with Python < 3.3
Thanks for this! Yeah, 3.3 is ancient and wasn't very widely used, so I'd be in favor of dropping support for it. Would that make your PR easier/more elegant? |
schema.py
Outdated
try: | ||
return f(**kwargs) | ||
except TypeError as e: | ||
if ( | ||
e.args[0].startswith("{}() got an unexpected keyword argument".format(f.__name__)) # Python 2/3. | ||
or e.args[0].startswith("{}() takes no arguments".format(f.__name__)) # Python 2 only. | ||
): | ||
return f() |
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.
Is there a realistic scenario wherein someone should be passing **kwargs
if the function does not support keyword-arguments in the first place?
Why not just skip the whole try/except
block and unconditionally return f(**kwargs)
?
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.
E.g. see test_optional_callable_default_ignore_inherited_schema_validate_kwargs
:
Lines 758 to 770 in 09c00ed
def test_optional_callable_default_ignore_inherited_schema_validate_kwargs(): | |
def convert(data, increment): | |
if isinstance(data, int): | |
return data + increment | |
return data | |
s = {"k": int, "d": {Optional("k", default=lambda: 42): int, "l": [{"l": [int]}]}} | |
v = {"k": 1, "d": {"l": [{"l": [3, 4, 5]}]}} | |
d = Schema(s).validate(v, increment=1) | |
assert d["k"] == 1 and d["d"]["k"] == 42 and d["d"]["l"][0]["l"] == [3, 4, 5] | |
d = Schema(s).validate(v, increment=10) | |
assert d["k"] == 1 and d["d"]["k"] == 42 and d["d"]["l"][0]["l"] == [3, 4, 5] |
That approach would work if lambda: 42
was instead lambda **_: 42
. This would be a backwards-incompatible change (warranting a major version bump), though.
Sorry for the delayed response! Following @BvB93's comment above, I think the underlying problem here is how #268 passes around kwargs. Schema is trying to pass Given this, though, This approach is fundamentally flawed for other reasons, though. For example, suppose Now, if #268 is to be kept and not rolled back, I think that the best way to deal with this is to (a) drop Python < 3.3 so that This would be a backwards-incompatible change that would necessitate a major version bump, but AFAIK it elegantly handles all of the relevant issues here: I've implemented this below and adjusted the tests relevant tests that were added in #268 accordingly. |
9213184
to
d3a93dc
Compare
On second thought: a major version bump is technically not necessary under SemVer even if this is merged, since Schema is still in major version 0. Schema still being v0.x.x means that if the major version is bumped, the reason for that bump should be to indicate public API stability, not to indicate backwards-incompatible changes. I am under the impression that the public API has already been stable for some time, though, so perhaps the major version should still be bumped if this is merged. |
Optional
failing when default
is some builtins, and fix incompatibility with Python < 3.3Optional
failing when default
is some builtins
Closes #272.
Note that
inspect.signature
(which is used in the current_invoke_with_optional_kwargs
!) is not available in Python < 3.3, which (I believe?) schema hasn't officially dropped support for yet. I know that I am just an outsider to this project, but I'd really suggest adopting #273.Also, I think that my implementation below is not the most elegant way to deal with this issue. It might be better to instead have
Optional
accept apass_kwargs
parameter rather than choosing whether or not to passkwargs
based on a heuristic.pass_args
could beTrue
by default (to pass all kwargs), but could also beFalse
or a set of strings (representing parameter names to pass). Let me know what you think!