Mypy: Forward reference to a type alias results in an "Invalid type ..." error

Created on 11 Oct 2016  路  9Comments  路  Source: python/mypy

mypy 0.4.5 and 0.4.4, CPython 3.5.1 and 3.5.2.

Code:

# code.py
def f(p: 'Alias') -> None:
    print(p)

Alias = int

Expected result:

% mypy code.py
%

Actual result:

% mypy code.py
code.py: note: In function "f":
code.py:1: error: Invalid type "code.Alias"
%
bug priority-1-normal

Most helpful comment

As far as I can tell, it is currently not possible to represent the output of json.load/s with types due to this.

JSON = Union[None, str, int, float, bool, List['JSON'], Dict[str, 'JSON']]

Adding newtypes in various bits didn't help the situation, I'm still getting 'Invalid type'

All 9 comments

Hm, interesting. Looks like aliases can't be used in forward references.
This is unfortunate, but shouldn't be hard to work around, right? I don't
know yet what it would take to fix (both aliases and forward references are
somewhat murky corners of mypy).

I think that type aliases also don't work reliably across different modules in import cycles.

As far as I can tell, it is currently not possible to represent the output of json.load/s with types due to this.

JSON = Union[None, str, int, float, bool, List['JSON'], Dict[str, 'JSON']]

Adding newtypes in various bits didn't help the situation, I'm still getting 'Invalid type'

Here's another example I ran into:

from typing import List

class A(object):
    b: 'B'  # E: Invalid type "recurse.B"

B = List[A]

I'm also seeing this occur with new Python 3.6-style NamedTuple type hint declarations.

import typing as typ

class EdgeDef(typ.NamedTuple):
    id: int
    stack_cmd: 'StackCommand' # ERROR: Invalid type "test.StackCommand"

# Other defs that depend on `EdgeDef`

StackCommand = typ.Tuple[bool, int]

I think we have enough examples at this point. :-)

@ThatsGobbles Is that the same issue though? This issue is with recursive type aliases, but your example doesn't actually have any recursion, just and out-of-order alias.

@kirbyfan64

This issue is with recursive type aliases

The original example does not have any recursion. Moreover, I am quite sure that there is no big difference between recursive and non-recursive situations with classes. The problem is very simple: type aliases are not analysed during first pass, but solution is not easy and requires refactoring semantic analyser (see roadmap).

cough I...uhh... totally knew that... cough

Was this page helpful?
0 / 5 - 0 ratings