-
-
Notifications
You must be signed in to change notification settings - Fork 276
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 inference tips for dataclass attributes #1126
Add inference tips for dataclass attributes #1126
Conversation
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.
Thanks for the great description :D I wonder what it would be like if you were awake and it was much detailed ;)
I looked at the failing tests and it seems like what is failing is failing because it's now better than before (better inference ?). I wonder if the name node should be "Unknown" though.
Regarding the regression tests in pylint, let's add them on top of pylint-dev/pylint#4816, you should have the right to do it but if you don't or if you don't have the time, I'll do it :)
I'm still a bit hesitant about that. As python is a dynamic language, nothing really prevents anyone to assign anything they want. Furthermore, not all types can correctly be inferred currently. That especially applies to |
@Pierre-Sassoulas thanks, I fixed up the tests. Version 3.7 needed a different @cdce8p I think those are totally fair points. Personally I think it's still worthwhile to try to infer at least some basic types, but deciding this can easily be deferred to later. For now, I can change this part of the code to just yield |
P.S. sorry about the style commits, I hadn't set up the pre-commit hooks in this repo. I can rebase and clean up once the branch is finalized. |
I'm more and more convinced that we must trust what the user is using in the typing. In conjunction with mypy that will tell the user about problem with it's own typing it should make pylint a lot more efficient. There's a discussion about this subject here based on a comment by @PCManticore: pylint-dev/pylint#4813 |
@Pierre-Sassoulas I added tests the branch but I didn't have write access to your repository, but I pushed to my own branch: https://github.com/david-yz-liu/pylint/tree/regression-test-533-2224-2626. I wouldn't think I have edit permissions on MRs to pylint, but maybe I just messed something up, please let me know. The tests I added are all consistent with yielding Let me know which direction on the inference you'd like to go with, either way is good with me 😄 |
Hey @david-yz-liu thank you for creating all those tests in pylint. Maybe you had to be a "maintener" in order to modify the branch and "contributor" is not enough, my bad. Regarding this change I think the way it's done right now is fine. Using typing when the inference fails us is something that we've already done in another MR if I remember correctly. I think using typing all the time even before inference for performance purpose needs to be discussed between maintainers but this is not what is done here. What do you think @hippo91 , @cdce8p ? |
@Pierre-Sassoulas I understand that you would like to use typing for inference. As mentioned earlier, I'm still not convinced that's the way to go, but then again inference is not really a topic of expertise for me. Let's put it differently, as long as it doesn't cause major regressions or other unforeseen issues, go ahead with it. |
I haven't been able to narrow it down just yet, but this change causes a regression for Home-Assistant
https://github.com/cdce8p/ha-core/tree/f684e4df349f7b95da473a1003f708ac67284848 |
Opened #1129 with a short code snipped that is enough to reproduce the issue. |
…10.0 Andreas Finkler (3): Create common ``Printer`` base class for ``pyreverse`` and improve typing. (#4731) ``pyreverse``: add PlantUML output (#4846) ``pyreverse``: Add option for colored output (#4850) Daniël van Noord (9): Add unspecified-encoding checker #3826 (#4753) Remove classes.dot after testing #4762 Add new checkers ``use-list-literal`` and ``use-dict-literal`` (#4769) Add ``forgotten-debug-statement`` checker (#4771) Fix false positives for ``superfluous-parens`` (#4784) Refactor ``--list-msgs`` & ``--list-msgs-enabled`` (#4793) Add ``format-string-without-interpolation`` checker (#4794) Add ``disable-next`` option (#4797) Add ``redundant-u-string-prefix`` checker (#4804) David Liu (6): Fix false negative for used-before-assignment (ExceptHandler) (#4791) Fix bugs in W0640 cell-var-from-loop checker (#4827) Additional tests for pylint-dev/astroid#1126 Improve invalid-metaclass error message for Instances Update test requirements to astroid 2.7.1 Add typecheck tests for dataclass attributes DudeNr33 (14): Move logic for constructing the label from ``DiagramWriter`` into the ``Printer`` classes. Refactor to reduce indentation and pull all "label building" logic together Refactor to reduce indentation Remove unnecessary specializations of ``DiagramWriter`` Move tests for ``pyreverse`` into a own subdirectory. Rename test files to follow the same conventions as other test modules Extract tests for ``pylint.pyreverse.utils`` into own test module. Extract commonly used test helpers into ``conftest.py`` and a testutils component. Add tests for ``Printer`` classes which are not covered yet implicitly through ``test_writer`` Use ``default_factory`` for mutable attribute. Use custom class, as ``dataclasses`` was only introduced in Python 3.7. Update license link to point to main, not master Convert ``get_project`` to a fixture instead of implementing it under ``pylint.testutils.pyreverse``. Suppress ``consider-using-with`` on return statements Eisuke Kawashima (1): Use `XDG_CACHE_HOME` for `PYLINTHOME` (#4661) Julien Palard (1): Similar check: Passe min_lines to recombined. Maksym Humetskyi (2): [duplicate-code] Ignore decorators lines by similarities checker when ignore signatures flag enabled (#4840) [duplicate-code] Parse functions and class methods recursively when gathering signature lines (#4858) Marc Mueller (22): Omit no-member error if guarded behind if stmt (#4764) Fix style issues Changelog + What's New Extended consider-using-tuple check to cover 'in' comparisons (#4768) Remove empty line Fix false-positive used-before-assignment with := in Return node Revert "Extended consider-using-tuple check to cover 'in' comparisons (#4768)" Keep bugfix Refactor visit_comprehension Add new check - use-sequence-for-iteration Fix existing tests Improvements consider-using-tuple (#4838) Add pylintrc config for typing extension (#4843) Allow true / false in pylintrc (#4844) Use alias for astroid.nodes 01 (#4855) Use alias for astroid.nodes 02 (#4863) Use alias for astroid.nodes 03 (#4866) Use alias for astroid.nodes 04 (#4869) Refactor existing code - code_style extension (#4872) Add cached infer_all helper function Add InferenceContext argument Increase cache size Revert cache size increase Mark Byrne (2): Handle has-a relationships for type-hinted arguments in class diagrams (#4745) pyreverse - Handle a regression with typehints of type astroid.Subscript (#4859) Michal Vasilek (1): Fix IsADirectoryError in tests/lint/unittest_lint (#4781) Nick Drozd (4): Enable some Pylint extensions (#4842) Add extension check against use of while loops (#4860) Change some if/assign blocks to if-expressions Add consider-ternary-expression extension PaaEl (1): Update option_manager_mixin.py - issue 3839 (#4812) Pierre Sassoulas (26): Move back to a dev version following 2.9.6 release Add modify_sys_path to __all__ in pylint API Add typing to PyReverse and fix an unused-argument Add documentation for useless-suppression Do not test unsupported item assignment for python 3.10 Upgrade astroid to 2.6.6 Add regression tests for issue #3711 Add regression tests for astroid issue 1111 Documentation for what blocks are and FAQ clean up (#4800) Fix the link to the discord server in the doc (#4830) Add a regression test for #4823 Permit to lint to the end in case of crash on a file (#4810) Simplification in error handling inside Pylinter (#4834) Add a regression test for #4837 (#4847) Fix crash on relative import beyond top-level package Fix functional test no-value-for-parameter when instancing an enum Add regression tests for issue with subclassed enums Upgrade astroid to 2.7.0 Limit the dataclasses tests to python 3.7 Prevent crashing when it's impossible to create the issue template ``astroid.const.BUILTINS`` use removed for clarity and so astroid can also removes it later (#4868) Add a test for false positive no-member in subclassed dataclasses [PYLINT-HOME change] Less spam when using pylint in parallel Upgrade astroid to 2.7.2 Prevent crash in CI environnement if we can't write in pylint's cache Bump pylint to 2.10.0, update changelog Rebecca Turner (1): Add ignored-parents option to design checker (#4758) Yu Shao, Pang (5): [unused-private-member] add logic for checking nested functions update PR based on comments Update pr based on review Update pr based on review update pr based on review dependabot[bot] (4): Bump sphinx from 4.1.1 to 4.1.2 (#4785) Bump isort from 5.9.2 to 5.9.3 Bump types-toml from 0.1.3 to 0.1.5 Update pre-commit requirement from ~=2.13 to ~=2.14 hippo91 (1): Performance improvment of the Similarity checker (#4565) kasium (1): Fix false positives for invalid-all-format (#4711) (#4829) pre-commit-ci[bot] (3): [pre-commit.ci] auto fixes from pre-commit.com hooks [pre-commit.ci] pre-commit autoupdate [pre-commit.ci] pre-commit autoupdate yushao2 (2): Fix false-positive of `unused-private-member` with class name (#4782) Fix crash for `unused-private-member` when there are nested attributes (#4783)
Steps
Description
I'm a little sleepy 😴 so I'm going to write up a short version of the description and elaborate later (perhaps upon request only). The short version is I've added two new inference tips related to dataclasses, in
astroid/brain/brain_dataclasses.py
:infer_dataclass_field_call
, for handling calls tofield
to infer the default value they actually evaluate to.infer_dataclass_attribute
, for handling inference of dataclass instance attributes. Note: the previous transform modified the dataclassClassDef
node'slocals
dict:https://github.com/PyCQA/astroid/blob/4704ca75539c085cdd0476a8d79771a7d2b8740d/astroid/brain/brain_dataclasses.py#L58-L64
I thought that was a bit too extreme, as it removed possible inferences that could be done for class attributes. So I removed the update to
locals
, and so the class variable inference "just works", without using this inference tip. See the tests I added for what I mean.Unknown
nodes, I had to make a few changes to the underlying node infrastructure, namelyUnknown.infer
andAstroidManager.visit
. I'm pretty sure both of these changes are fine, but please let me know if that's an issue.Using type annotations (?)
For the instance attribute inference, I used the type annotation to provide an alternative to the default value. E.g.,
x: int = 10
gets two inference results, one forConst(10)
and one forInstance of type int
. My sense looking at the issues for astroid/pylint is that using type annotations for inference is a possibility but hasn't really been explored. So this PR has one small way foray into using type annotations for inference, but let me know if you want to avoid that. I could yield anUninferable
instead.Other changes
In addition to these two changes, I updated the existing inference tip (
dataclass_transform
) to be more robust in checking for dataclass usage (including renaming of the dataclass import), and added basic support forInitVar
as well.Also,
Assign
nodes shouldn't be included, onlyAnnAssign
nodes. For dataclasses, the "magic" only occurs for class variables with type annotations.Testing
As usual, I've tried to communicate various intentions through some tests. See also related pylint issues below.
Type of Changes
Related Issue
Closes pylint-dev/pylint#2600
Closes pylint-dev/pylint#2698
Closes pylint-dev/pylint#3405
Closes pylint-dev/pylint#3794
I've written "closes" even though I couldn't reproduce some of them, but I was going a bit quickly and I'd appreciate a second look.
For the field-specific ones, the commit (3e4eac7) that introduced the transform should have fixed the false positive
no-member
complaints becauseUnknown
infers toUninferable
, which I think causes pylint to not emitno-member
.However, with the change in this PR, a more specific type is emitted, meaning that the false positives described in the issues should not occur, but there should be fewer false negatives too. E.g.,
So IMO it'd be good to add regression tests for these issues, even if they aren't reproducible on main. Let me know if you want me to do it.