Skip to content

Type of conditional expression is object #8074

Closed

Description

@cjolowicz

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.

Activity

  1. changed the title [-]Type of conditional expressions is object[/-] [+]Type of conditional expression is object[/+] on Dec 4, 2019
  2. JukkaL commented on Dec 4, 2019

    @JukkaL
    Collaborator

    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.

  3. ilevkivskyi commented on Dec 4, 2019

    @ilevkivskyi
    Member

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

  4. cjolowicz commented on Dec 5, 2019

    @cjolowicz
    ContributorAuthor

    Here is a simpler reproduction:

    a, b = [1, 2] if bool() else (1, 2)
    
  5. intgr commented on Jan 26, 2020

    @intgr
    Contributor

    This issue is addressed in PR #8335.

  6. emmatyping commented on Feb 3, 2020

    @emmatyping
    Member

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

  7. carlosporta commented on Dec 12, 2021

    @carlosporta

    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")

  8. intgr commented on Dec 12, 2021

    @intgr
    Contributor

    @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.

  9. carlosporta commented on Dec 12, 2021

    @carlosporta

    @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.

    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?

  10. intgr commented on Dec 12, 2021

    @intgr
    Contributor

    @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

  11. carlosporta commented on Dec 12, 2021

    @carlosporta

    @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.

  12. hsghori commented on Mar 1, 2022

    @hsghori

    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)
    
  13. intgr commented on Mar 2, 2022

    @intgr
    Contributor

    @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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions