-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Untangle most of the big import cycle #7397
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.
Yay! Are we going to use black next? :-)
@@ -237,3 +237,55 @@ def callable_corresponding_argument(typ: CallableType, | |||
and is_equivalent(by_name.typ, by_pos.typ)): | |||
return FormalArgument(by_name.name, by_pos.pos, by_name.typ, False) | |||
return by_name if by_name is not None else by_pos | |||
|
|||
|
|||
def make_simplified_union(items: Sequence[Type], |
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.
I know this will break Dropbox's Edgestore plugin. It's easily fixed, but I wonder how many other 3rd party plugins will be affected?
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.
We should document the change in the issue that tracks plugin API changes (and potentially in mypy release notes).
The introduction of recursive types will break many plugins as well, probably more than this change.
mypy/erasetype.py
Outdated
@@ -87,7 +87,9 @@ def visit_literal_type(self, t: LiteralType) -> ProperType: | |||
|
|||
def visit_union_type(self, t: UnionType) -> ProperType: | |||
erased_items = [erase_type(item) for item in t.items] | |||
return UnionType.make_simplified_union(erased_items) | |||
from mypy.typeops import make_simplified_union # asdf | |||
# XXX: does this need to be simplified? |
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.
I think sometimes it may be useful. For example we probably want Union[List[T], List[S]]
become just List[Any]
, not Union[List[Any], List[Any]]
. I think a similar applies to the question below.
I think this makes sense.
I would like to point out one nasty dependency:
Good idea! |
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.
This is great! I've been thinking about doing this myself for a long time but never got around to doing it.
@@ -237,3 +237,55 @@ def callable_corresponding_argument(typ: CallableType, | |||
and is_equivalent(by_name.typ, by_pos.typ)): | |||
return FormalArgument(by_name.name, by_pos.pos, by_name.typ, False) | |||
return by_name if by_name is not None else by_pos | |||
|
|||
|
|||
def make_simplified_union(items: Sequence[Type], |
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.
We should document the change in the issue that tracks plugin API changes (and potentially in mypy release notes).
The introduction of recursive types will break many plugins as well, probably more than this change.
I went and mostly fixed #6329; we can now import any module first except for Would it be worth adding a test at some point for that? |
If it is not too tricky I think it makes sense to add some tests that would prevent us from recreating (or enlarging) those import cycles. |
We could perhaps run another incremental build after self check in verbose mode and assert that the largest import cycle is below some size limit. Alternatively, we could modify verbose mode to write more details about SCCs in incremental mode and make more specific assertions, such as requiring that the nodes, typeops and checker cycles are disjoint. |
Currently mypy has a 47 module import cycle, which is not great.
This untangles things, leaving the following cycles:
The untangling done here is pretty simple and consists of two main parts:
mypy.types
's dependency on the type ops tangle by moving all of its functions that depend on it intomypy.typeops
.mypy.checkmember
tomypy.typeops
.