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

Unexpected Any for complex import structure #4110

Closed
matzipan opened this issue Oct 13, 2017 · 8 comments
Closed

Unexpected Any for complex import structure #4110

matzipan opened this issue Oct 13, 2017 · 8 comments
Labels
bug mypy got something wrong priority-1-normal

Comments

@matzipan
Copy link

matzipan commented Oct 13, 2017

Hello guys, I have the following snippet:

def blabla_call(command: List[str], modules: Optional[List[str]] = None) -> Tuple[int, str]:
    if modules is None:
        modules = []

    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    output_buffer = io.StringIO()

    for line in process.stdout:
        decoded_line = line.decode("utf-8")
        sys.stdout.write(decoded_line)
        output_buffer.write(decoded_line)

    if process.returncode:
        raise RuntimeError("Shell command failure")

    return process.returncode, output_buffer.getvalue()

def make_step(options: Iterable[str]) -> Tuple[int, str]:
     return blabla_call(["make"])

On the very last line of the function make_step the following warning is reported only when running with --strict enabled: warning: Returning Any from function declared to return "Tuple[int, str]".

This sounds like a type propagation bug of sorts in mypy since there is no error reported in the type defintion of blabla_call, but only further on does mypy get confused.

@ilevkivskyi
Copy link
Member

I cannot reproduce this on master.

@matzipan
Copy link
Author

I'm on 0.530 and I can't see what changed in the meanwhile that fixed it.

@matzipan
Copy link
Author

Ah you are right. My testcase doesn't produce the issue.

@matzipan
Copy link
Author

I've managed to eliminate Tuple as an issue, I still get this issue with just str: warning: Returning Any from function declared to return "str"

I've managed to get the same issue when I have the following file:

import sys
from typing import Optional, List

def call(command: List[str], modules: Optional[List[str]] = None) -> str:
    if modules is None:
        modules = []

    output_buffer = io.StringIO()

    return output_buffer.getvalue()

But I understand this, because this doesn't import io. However, the file where I have blabla_call defined has an import io at the top and it can execute without any errors (unfortunately I can't share the full file).

@ilevkivskyi
Copy link
Member

Yes, everything unknown is Any.

and it can execute without any errors

x: int = 'hi' also executes without errors. I will be glad to fix the bug, if you show the bug, currently from what I see everything works as expected.

@matzipan
Copy link
Author

Ok. I think I've narrowed down and located the issue.

I have the following directory structure:

blamodule
|-- __init__.py
|-- backends
|   |-- Bla.py
|   `-- __init__.py
`-- call_command.py

With the following contents:

  • blamodule/__init__.py
from . import call_command
from . import backends
  • blamodule/backends/__init__.py
from .Bla import Bla
  • blamodule/backends/Bla.py
import blamodule
from typing import Iterable

class Bla:
    def __init__(self, path: str) -> None:
        self.path = path

    def method(self, options: Iterable[str]) -> str:
        return blamodule.call_command.call(["BLA"])
  • blamodule/call_command.py
import io

def call() -> str:

    output_buffer = io.StringIO()

    return output_buffer.getvalue()

This works fine when I run in python because the sys.path contains the folder which is one level up of blamodule folder (the root of the project). However, mypy does not seem to take this into consideration and it can't find blamodule to import in backends/Bla.py and thus it expects a return of Any.

@ilevkivskyi
Copy link
Member

This may be related to #3277 but it doesn't look like a duplicate, since there are no explicit import cycle.

@ilevkivskyi ilevkivskyi reopened this Oct 13, 2017
@ilevkivskyi ilevkivskyi added bug mypy got something wrong priority-1-normal labels Oct 13, 2017
@ilevkivskyi ilevkivskyi changed the title Mypy strict mode is confused about return type Unexpected Any for complex import structure Oct 13, 2017
@JukkaL
Copy link
Collaborator

JukkaL commented Mar 8, 2018

Looks like this was fixed by #4695.

@JukkaL JukkaL closed this as completed Mar 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong priority-1-normal
Projects
None yet
Development

No branches or pull requests

3 participants