Skip to content

Use enum trick for dataclasses.MISSING #7127

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

Merged
merged 1 commit into from
Feb 5, 2022

Conversation

sirosen
Copy link
Contributor

@sirosen sirosen commented Feb 4, 2022

The goal of this change is to fix the behavior of dataclasses.Field. Several attributes of a Field may have a value of MISSING (a sentinel value). As a result, attributes of Field may be checked against MISSING as in

 [f for f in fields(obj) if f.default is MISSING]

default, default_factory, and kw_only are the attributes which may have a value of MISSING.

This workaround of defining _MISSING_TYPE as an enum, and MISSING as its only member, allows ... | Literal[MISSING] to be used in type annotations for these attributes. This is very slightly inaccurate -- primarily in that _MISSING_TYPE isn't really an enum -- but this allows for use in Literal. After PEP 661 (Sentinel Values), there may be a more accurate way of writing this, but for now this works.

This adjustment is only applied to the attributes of Field, not the arguments to functions and methods.


There have been two previous attempts to handle this, #5900 and #7126.
Per those PRs, PEP 661 (Sentinel Values) will provide the best solution for this in the future. The enum+Literal workaround used here was suggested as a way to handle dataclasses.MISSING while we wait for that PEP.

@sirosen sirosen force-pushed the dataclass-missing-use-enum branch from 1ac0d00 to c82309a Compare February 4, 2022 06:42
@github-actions

This comment has been minimized.

@sirosen sirosen force-pushed the dataclass-missing-use-enum branch from c82309a to 397786b Compare February 4, 2022 06:44
@github-actions

This comment has been minimized.

1 similar comment
@github-actions

This comment has been minimized.

Copy link
Collaborator

@hauntsaninja hauntsaninja left a comment

Choose a reason for hiding this comment

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

Thanks for the fix, looks great to me! I'll leave open for a little bit in case anyone else chimes in.

The goal of this change is to fix the behavior of
`dataclasses.Field`. Several attributes of a `Field` may have a value
of `MISSING` (a sentinel value). As a result, attributes of Field may
be checked against `MISSING` as in

     [f for f in fields(obj) if f.default is MISSING]

`default`, `default_factory`, and `kw_only` are the attributes
which may have a value of `MISSING`.

This workaround of defining `_MISSING_TYPE` as an enum, and `MISSING`
as its only member, allows `... | Literal[_MISSING_TYPE.MISSING]` to
be used in type annotations for these attributes. This is very
slightly inaccurate -- primarily in that `_MISSING_TYPE` isn't really
an enum -- but this allows for use in `Literal`.
After PEP 661 (Sentinel Values), there may be a more accurate way of
writing this, but for now this works.

This adjustment is only applied to the attributes of Field, not the
arguments to functions and methods.
@sirosen sirosen force-pushed the dataclass-missing-use-enum branch from 397786b to 550ea0c Compare February 4, 2022 17:00
@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2022

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

@JelleZijlstra JelleZijlstra merged commit 38d32a9 into python:master Feb 5, 2022
@sirosen sirosen deleted the dataclass-missing-use-enum branch February 5, 2022 05:53
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.

4 participants