You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Improve unification of conditional expressions #1094
Tree.py: note: In member "__init__" of class "Node":
Tree.py:10: error: Incompatible types in assignment (expression has type"object", variable has type List[Node])
I think it's something related to the children parameter setted to None, but the problem is... how do I specify that yes, maybe the children parameter can be None, but self.children, by construction is always a List of Nodes?
This looks like the type of the expression `([] if ... else children)`,
where children has type `List[Node]`, is inferred as `object` whereas it
should really be inferred as `List[Node]`. We should fix this. In the
meantime you can work around it by replacing `[]` with `cast(List[Node],
[])`. But that's a very verbose solution and mypy should do better.
The if..else expression doesn't propagate the type context (in your example List[Node]) to the child expressions. Propagating the context would let mypy infer type List[Node] for the left operand.
A related way to fix this would be to use the type of the right operand as the type context for the first expression, in case the latter has an incomplete inferred type. This would have the benefit of not requiring a type annotation.
I think that you could also work around the problem by rearranging the expression:
self.children = children if children is not None else []
I keep running into this. The type of (a if x else b) where a and b don't have the same type often degenerates to object or some other useless type rather than the intersection of the two types. Latest example:
class A: pass
class B:
def foo(self): pass
class C(A, B): pass # No error if we switch this to C(B, A)
a = B() if True else C()
a.foo() # E: "object" has no attribute "foo"
Also, e.g.in Python 2 mode:
float(Decimal(0) if True else 0) # E: No overload variant of "float" matches argument types [builtins.object]
In Python 3 mode this gives
error: Argument 1 to "float" has incompatible type "object"; expected "Union[SupportsFloat, str, bytes]"
changed the title [-]Incompatible types in assignment (handling optional parameters)[/-][+]Improve unification of conditional expressions[/+]on Apr 14, 2016
Activity
gvanrossum commentedon Dec 22, 2015
JukkaL commentedon Dec 28, 2015
The if..else expression doesn't propagate the type context (in your example
List[Node]) to the child expressions. Propagating the context would let mypy infer typeList[Node]for the left operand.A related way to fix this would be to use the type of the right operand as the type context for the first expression, in case the latter has an incomplete inferred type. This would have the benefit of not requiring a type annotation.
I think that you could also work around the problem by rearranging the expression:
gvanrossum commentedon Dec 30, 2015
gvanrossum commentedon Mar 8, 2016
I keep running into this. The type of (a if x else b) where a and b don't have the same type often degenerates to object or some other useless type rather than the intersection of the two types. Latest example:
Also, e.g.in Python 2 mode:
In Python 3 mode this gives
[-]Incompatible types in assignment (handling optional parameters)[/-][+]Improve unification of conditional expressions[/+]gvanrossum commentedon Apr 15, 2016
I'm going to have a crack at this.
Improve unification of conditional expressions when the left branch h…
Improve unification of conditional expressions when the left branch h…