10000 Type of conditional expression is object · Issue #8074 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

Type of conditional expression is object #8074

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

Closed
cjolowicz opened this issue Dec 4, 2019 · 12 comments
Closed

Type of conditional expression is object #8074

cjolowicz opened this issue Dec 4, 2019 · 12 comments

Comments

@cjolowicz
Copy link
Contributor
cjolowicz commented Dec 4, 2019

The type of the following conditional expression is object:

s: str = "key=value"
a, b = s.split("=", 1) if "=" in s else ("key", "default")
# main.py:2: error: 'builtins.object' object is not iterable

It should be a union type instead, such as Union[List[str], Tuple[str, str]].

(Note that str.split returns List[str] while the else branch has the type Tuple[str, str].)

This is a follow-up to #3487.

@cjolowicz cjolowicz changed the title Type of conditional expressions is object Type of conditional expression is object Dec 4, 2019
@JukkaL
Copy link
Collaborator
JukkaL commented Dec 4, 2019

Alternatively, inferring Sequence[str] for the conditional expression would help in this case.

Inferring a union type would break backward compatibility. If the fallout is not too bad, it may still make sense.

@ilevkivskyi
Copy link
Member

Note that a good fix for #4975 may automatically lead to inferring Sequence here.

@cjolowicz
Copy link
Contributor Author

Here is a simpler reproduction:

a, b = [1, 2] if bool() else (1, 2)

@intgr
Copy link
Contributor
intgr commented Jan 26, 2020

This issue is addressed in PR #8335.

JukkaL pushed a commit that referenced this issue Jan 31, 2020
…8335)

For example:

* Tuple[int] + Tuple[bool, ...] becomes Tuple[int, ...]
* List[int] + Tuple[bool, ...] becomes Sequence[int]

Previously Mypy simply punted and returned `object`.

This solves the other part of issue #4975. Fixes issue #8074.
    
@emmatyping
Copy link
Member

Closing as this was fixed by #8335. Thanks @intgr !

@carlosporta
Copy link

I am also facing a similar problem.

from typing import Protocol


class Shape(Protocol):
    def area(self) -> str:
        ...


class Circle:
    def area(self) -> str:
        return 'π * r²'


class Square:
    def area(self) -> str:
        return 'w * l'


class ShapeFactory:
    def create(self, shape_type: str) -> Shape:
        return Circle() if shape_type == 'circle' else Square()  # Here

Mypy shows this error message:

error: Incompatible return value type (got "object", expected "Shape")

@intgr
Copy link
Contributor
intgr commented Dec 12, 2021

@carlosporta That's a separate issue. Mypy tries to find the common base class of Circle and Square; since those two don't subclass Shape directly, the common base class happens to be object.

@carlosporta
Copy link

@intgr, I understood what is happening, but this only happens using when using a conditional expression. If I change it to a conditional statement mypy identifies the shape protocol correctly as the return type.< 8000 /p>

This works perfectly, no error messages on mypy:

class ShapeFactory:
    def create(self, shape_type: str) -> Shape:
        if shape_type == 'circle':
            return Circle() 
        else:
            return Square()

Should I create a new issue (Type of conditional expression is object) or am I facing something similar to this issue?

@intgr
Copy link
Contributor
intgr commented Dec 12, 2021

@carlosporta I suspect an issue already exists for that, not totally sure. If you don't find one, feel free to open a new one.

But there's a historical background to why the ternary condition works as it does, I believe there's no easy fix: #3487 #5095

@carlosporta
Copy link

@intgr, I did not find anything related to conditional expression and Protocol, so I created a new issue. If someone goes through a similar problem, here is the issue #11722.

@hsghori
Copy link
hsghori commented Mar 1, 2022

I'm still seeing this issue on mypy==0.910 (which FWICT should include #8335).

repro:

from typing import Tuple, List, cast

x: List[Tuple[str, str]] = [("a", "b"), ("c", "d")]

c1, c2 = zip(*x) if len(x) > 0 else ([], [])
> $ mypy --version                                       
mypy 0.910
                                                                                              
> $ mypy ~/scratch/test_types.py 
/Users/haroon/scratch/test_types.py:5: error: "builtins.object" object is not iterable
Found 1 error in 1 file (checked 1 source file)

@intgr
Copy link
Contributor
intgr commented Mar 2, 2022

@hsghori Please do not report bugs as comments on old bugs, unless you're absolutely certain it's the exact same root cause. And when reporting bugs, ensure that your bug is reproducible in the latest git version, or at least latest release version, of the project.

I cannot reproduce this issue with mypy 0.931

% cat errobject.py
x: list[tuple[str, str]] = [("a", "b"), ("c", "d")]
c1, c2 = zip(*x) if len(x) > 0 else ([], [])
reveal_type(c1)
reveal_type(c2)
% mypy errobject.py
errobject.py:3: note: Revealed type is "typing.Sequence[Any]"
errobject.py:4: note: Revealed type is "typing.Sequence[Any]"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants
0