Skip to content
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 type annotations to pyreverse #4551

Merged

Conversation

mbyrnepr2
Copy link
Member

@mbyrnepr2 mbyrnepr2 commented Jun 7, 2021

Closes #1548

Steps

  • Add yourself to CONTRIBUTORS if you are a new contributor.
  • Add a ChangeLog entry describing what your PR does.
  • If it's a new feature or an important bug fix, add a What's New entry in
    doc/whatsnew/<current release.rst>.
  • Write a good description on what the PR does.

Description

demo.py:

from typing import Dict, List, NamedTuple


class A:
    classvar1: Dict = None
    classvar2 = 'classvar2'

    def __init__(self, a: str = None, b: NamedTuple = None, c = 1):
        self.a = a
        self.b = b
        self.c = c

    def m1(self, i: str, j: int) -> List:
        pass

development branch:
development_branch_commit3

master branch:
master_branch

Type of Changes

Type
✨ New feature

Related Issue

@mbyrnepr2 mbyrnepr2 force-pushed the 1548_pyreverse_type_annotations branch from b485530 to 043c883 Compare June 7, 2021 15:17
@coveralls
Copy link

coveralls commented Jun 7, 2021

Coverage Status

Coverage increased (+0.02%) to 92.036% when pulling 194e6d3 on mbyrnepr2:1548_pyreverse_type_annotations into 99589b0 on PyCQA:master.

@mbyrnepr2 mbyrnepr2 force-pushed the 1548_pyreverse_type_annotations branch 3 times, most recently from ead9a4c to caed9b0 Compare June 9, 2021 20:33
@mbyrnepr2 mbyrnepr2 force-pushed the 1548_pyreverse_type_annotations branch from caed9b0 to 4b35586 Compare June 10, 2021 20:05
@mbyrnepr2 mbyrnepr2 marked this pull request as ready for review June 10, 2021 20:14
@Pierre-Sassoulas Pierre-Sassoulas added pyreverse Related to pyreverse component Enhancement ✨ Improvement to a component labels Jun 14, 2021
Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

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

Thank you for this changes :) I made some suggestions that could maybe simplify the code let me know if there is something that I did not see :)

Comment on lines 221 to 222
ann = getattr(node.parent, "annotation", None)
values = {ann} if ann else set(node.infer())
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
ann = getattr(node.parent, "annotation", None)
values = {ann} if ann else set(node.infer())
values = {getattr(node.parent, "annotation", node.infer())}

Would that work ?

@@ -229,8 +230,17 @@ def handle_assignattr_type(node, parent):
handle instance_attrs_type
"""
ann = None
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
ann = None
ann = node.infer()

I think doing that would simplify that following code.

@mbyrnepr2
Copy link
Member Author

@Pierre-Sassoulas thank you! I'll try that later today along with the further changes required to display variables a optional in the diagram.

@alexchandel
Copy link

This would be fantastic! There is no Python UML generator that understands type annotations right now. This also lays the groundwork for the future generation of dependency arrows for class attributes.

@mbyrnepr2 Did the requested changes work?

@mbyrnepr2
Copy link
Member Author

@alexchandel the suggested changes work perfectly. Aiming to update the pr with those + Optional output this week.

@Pierre-Sassoulas
Copy link
Member

@DudeNr33 I don't know if you saw that MR but someone else if working on pyreverse in parallel :) Maybe you can rebase on it as soon as it's merged to avoid handling conflicts late.

@DudeNr33
Copy link
Collaborator

Thanks for the heads up!
Great work, I actually also had the corresponding issue bookmarked for some time now because I think this is a great improvement! Will rebase my own branch as soon as I got time.

mbyrnepr2 and others added 3 commits June 20, 2021 18:12
- Indicate the attribute is optional in the dot files by
  inspecting the default value.
- Handle the Subscript type annotations
- Refactor & move the logic to obtain annotations to utils.py as
  re-usable functions
- Add unittests for the added functions
Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

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

Thank you for going back to this. I think there's should be a handling for the inference fail that can happen with infer() call. I don't have an example of code where there inference would fail, maybe we can patch NodeNg so it raises one in order to be able to test ?

@@ -218,7 +218,8 @@ def visit_assignname(self, node):
self.visit_module(frame)

current = frame.locals_type[node.name]
values = set(node.infer())
ann = utils.get_annotation(node)
values = {ann} if ann else set(node.infer())
Copy link
Member

Choose a reason for hiding this comment

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

Here there can be an inference fail, we should catch it (like line 238). Btw it look like the code is similar, maybe we can create a function for it ?

else:
return ann

default, *_ = node.infer()
Copy link
Member

Choose a reason for hiding this comment

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

There can be an InferenceError raised here.

- Add a try/except to deal with a possible InferenceError when using
NodeNG.infer method
- Create a function in utils and so remove repeated logic in inspector.py
- Add unittests to check the InferenceError logic
- Adjust the types in function input
@mbyrnepr2
Copy link
Member Author

Thanks again @Pierre-Sassoulas I agree with all the above. I've aimed to address the points in 194e6d3. I could easily have missed something though so happy to look again if something doesn't look right.

Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

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

Thank you for all the work that went into this !

@Pierre-Sassoulas Pierre-Sassoulas added this to the 2.9.0 milestone Jun 26, 2021
@Pierre-Sassoulas Pierre-Sassoulas merged commit 1e55ae6 into pylint-dev:master Jun 26, 2021
@Pierre-Sassoulas Pierre-Sassoulas mentioned this pull request Jun 26, 2021
3 tasks
@DudeNr33 DudeNr33 mentioned this pull request Aug 14, 2021
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement ✨ Improvement to a component pyreverse Related to pyreverse component
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use Python type hints for UML generation
5 participants