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

Decorators are sensitive to import cycle ordering #1303

Closed
ddfisher opened this issue Mar 18, 2016 · 8 comments
Closed

Decorators are sensitive to import cycle ordering #1303

ddfisher opened this issue Mar 18, 2016 · 8 comments
Assignees
Labels
bug mypy got something wrong

Comments

@ddfisher
Copy link
Collaborator

If we have two files:
test1.py:

from typing import Callable, Any
import test2

def deco(f: Callable[[int, int], Any]) -> Callable[[int, int], Any]:
    pass

@deco
def add(self, other: int) -> int:
    pass

test2.py:

import test1
test1.add(1, 1)

Running mypy test1.py test2.py results in:
test2.py:2: error: Cannot determine type of 'add'

Removing the @deco decorator from add or reversing the order of the files on the command line makes the error go away.

@JukkaL
Copy link
Collaborator

JukkaL commented Mar 18, 2016

Yeah, this is a known issue.

@ddfisher
Copy link
Collaborator Author

I didn't see it documented elsewhere, though?

@JukkaL
Copy link
Collaborator

JukkaL commented Mar 18, 2016

See #481 (though it's not very specific).

@JukkaL JukkaL added the bug mypy got something wrong label Mar 18, 2016
@JukkaL
Copy link
Collaborator

JukkaL commented Mar 18, 2016

I marked this as a bug as there is no acceptable workaround right now, and this is a common thing.

@JukkaL
Copy link
Collaborator

JukkaL commented Mar 23, 2016

The following was copied from #481 because it's relevant here:

Infer types for (most) decorated functions before the final type checking pass. Either do this during semantic analysis (we already do some, but it's pretty limited) or introduce another type checking pass. Decorated functions often cause trouble as mypy sometimes only infers their types during the final pass, when it can be too late as modules must be type checked in some specific, linear order.

A fairly simple approach would to improve the lightweight type inference engine we have just for function decorators.

Some ideas of additional things to support:

  1. Decorator contains a call
@decorator()
def func(...): ...

We could just "unwrap" the decorator type by taking the return type without checking the call otherwise.

  1. Decorator that always returns the same type (no type variables)
def decorator(f: Callable[[int], str]) -> Callable[[int], str]:
    ...

@decorator
def func(x: int) -> str:
    ...

We would just have to recognize if the return type has no type variables, which is easy, and then we can trivially infer the type of the decorated function.

The current implementation lives in semanal.py (ThirdPass.visit_decorator). I suggest implementing at least these improvements in 0.3.2, as they should be simple. What do you think?

@JukkaL JukkaL added this to the 0.3.2 milestone Mar 24, 2016
@JukkaL JukkaL self-assigned this Apr 7, 2016
@gvanrossum
Copy link
Member

Let's make this a stretch goal for the 0.3.2. release. It's important, but we feel only Jukka understands it well enough to be able to fix it. If Jukka can't do it, we can release 0.3.2 without this and push it to the next milestone -- rather than hold up the release.

@JukkaL
Copy link
Collaborator

JukkaL commented Apr 14, 2016

I started working on this a while back but haven't had time to finish it. I'll see if the current branch is good enough to merge already, even if it's not complete.

JukkaL added a commit that referenced this issue Apr 16, 2016
Infer more decorated function signatures during semantic analysis.
Also add extra test cases for import cycles in general.

Partially addresses #1303.
@JukkaL
Copy link
Collaborator

JukkaL commented May 5, 2016

The original example now works, so I'm closing this. We can create new issues for remaining cases where decorators don't work.

@JukkaL JukkaL closed this as completed May 5, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

3 participants