-
-
Notifications
You must be signed in to change notification settings - Fork 631
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
Let data_key and attribute default to field name #1897
base: dev
Are you sure you want to change the base?
Conversation
src/marshmallow/schema.py
Outdated
field_name = ( | ||
field_obj.data_key if field_obj.data_key is not None else attr_name | ||
) | ||
field_name = field_obj.data_key | ||
raw_value = data.get(field_name, missing) |
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.
error: Argument 1 to "get" of "Mapping" has incompatible type "Optional[str]"; expected "str"
The problem is that Fields.__init__
assigned a Optional[str]
type to data_key
. _bind_to_schema
guarantees that field_obj.data_key
is a str
, but the type checker doesn't know that _deserialize
is guaranteed to run after _bind_to_schema
. I guess the get
type annotation enforces this argument, but AFAICT, None
doesn't actually error. 🤷
It wants you to ensure data_key
is never None
. The only thing I can think of is to make data_key
a @property
that raises an exception if the field is unbound.
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.
Yes, we agree on the reason behind the error.
It would be a shame to "complicate" the code, even slightly, to please the linter.
I suppose we could add comments to skip test on each failing line, but I'd rather find a way to centralize that by somehow forcing the type of self.data_key
once and for all.
We could use a cast:
self.data_key = typing.cast(str, data_key)
but doing this in __init__
before field binding would be wrong.
Or we do it just before the type check error:
field_name = typing.cast(str, field_obj.data_key)
Still not ideal because:
- It is not done everywhere, only where the error was triggered. Other errors may occur later here or in other libs.
- It is executed on each deserialization, although IIUC it is neglectable.
I just pushed a commit doing that.
64c268d
to
a53475a
Compare
Notes:
|
I performed a quick test on apispec codebase to see how things could be simplified there and the result is a bit disappointing. apispec operates on schema instances or classes, and when operating on a class, fields are not bound to the schema so we can't rely on This feature would be more useful if it occurred on schema class creation, not instantiation. Technically, that could mean adding a With this last commit, the changes in apispec work. Notes:
|
@lafrech yes, that's right. I use the |
Closes #1864.
Trying to address #1864, I get typing issues, as foreseen in #1864 (comment). I wouldn't mind a bit of help, here.
This change spares users the hassle of checking if
data_key
isNone
, as can be seen in the changes in schema.py. This would be used in apispec, for instance.Notes:
None
but only for truthyness, which may be wrong for empty strings. I didn't look into it any further but this PR would fix it.data_key
to the repr. The printed name will be the actual value, be it the parameter or the field name (default). I don't think it is an issue.