-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Update error examples in documentation #3404
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
Changes from all commits
8e4296b
9a32a15
94aa1ba
49ec476
208ced4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -83,7 +83,7 @@ Functions | |
| # type: (int) -> None | ||
| pass | ||
| quux(3) # Fine | ||
| quux(__x=3) # Error | ||
| quux(__x=3) # error: Unexpected keyword argument "__x" for "quux" | ||
|
|
||
| # This is how you annotate a function value. | ||
| x = f # type: Callable[[int, float], float] | ||
|
|
@@ -106,7 +106,7 @@ Functions | |
| body=None # type: List[str] | ||
| ): | ||
| # type: (...) -> bool | ||
| <code> | ||
| pass | ||
|
|
||
|
|
||
| When you're puzzled or when things are complicated | ||
|
|
@@ -119,7 +119,7 @@ When you're puzzled or when things are complicated | |
| # To find out what type mypy infers for an expression anywhere in | ||
| # your program, wrap it in reveal_type. Mypy will print an error | ||
| # message with the type; remove it again before running the code. | ||
| reveal_type(1) # -> error: Revealed type is 'builtins.int' | ||
| reveal_type(1) # error: Revealed type is 'builtins.int' | ||
|
|
||
| # Use Union when something could be one of a few types. | ||
| x = [3, 5, "test", "fun"] # type: List[Union[int, str]] | ||
|
|
@@ -146,8 +146,8 @@ When you're puzzled or when things are complicated | |
| a = [4] | ||
| b = cast(List[int], a) # passes fine | ||
| c = cast(List[str], a) # passes fine (no runtime check) | ||
| reveal_type(c) # -> error: Revealed type is 'builtins.list[builtins.str]' | ||
| print(c) # -> [4] the object is not cast | ||
| reveal_type(c) # error: Revealed type is 'builtins.list[builtins.str]' | ||
| print(c) # [4] the object is not cast | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps, it would be good to give an indication that print(c) # prints [4] because the cast did not change the object's type at runtime |
||
|
|
||
| # TODO: explain "Need type annotation for variable" when | ||
| # initializing with None or an empty container | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -78,7 +78,7 @@ Python 3 introduces an annotation syntax for function declarations in `PEP 3107 | |
| def quux(__x: int) -> None: | ||
| pass | ||
| quux(3) # Fine | ||
| quux(__x=3) # Error | ||
| quux(__x=3) # error: Unexpected keyword argument "__x" for "quux" | ||
|
|
||
| # This is how you annotate a function value. | ||
| x = f # type: Callable[[int, float], float] | ||
|
|
@@ -113,7 +113,7 @@ When you're puzzled or when things are complicated | |
| # To find out what type mypy infers for an expression anywhere in | ||
| # your program, wrap it in reveal_type. Mypy will print an error | ||
| # message with the type; remove it again before running the code. | ||
| reveal_type(1) # -> error: Revealed type is 'builtins.int' | ||
| reveal_type(1) # error: Revealed type is 'builtins.int' | ||
|
|
||
| # Use Union when something could be one of a few types. | ||
| x = [3, 5, "test", "fun"] # type: List[Union[int, str]] | ||
|
|
@@ -139,8 +139,8 @@ When you're puzzled or when things are complicated | |
| a = [4] | ||
| b = cast(List[int], a) # passes fine | ||
| c = cast(List[str], a) # passes fine (no runtime check) | ||
| reveal_type(c) # -> error: Revealed type is 'builtins.list[builtins.str]' | ||
| print(c) # -> [4] the object is not cast | ||
| reveal_type(c) # error: Revealed type is 'builtins.list[builtins.str]' | ||
| print(c) # [4] the object is not cast | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See comment for py2 cheatsheet. |
||
|
|
||
| # TODO: explain "Need type annotation for variable" when | ||
| # initializing with None or an empty container | ||
|
|
@@ -190,8 +190,6 @@ Classes | |
| def my_method(self, num: int, str1: str) -> str: | ||
| return num * str1 | ||
|
|
||
|
|
||
|
|
||
| # User-defined classes are written with just their own names. | ||
| x = MyClass() # type: MyClass | ||
|
|
||
|
|
@@ -228,7 +226,7 @@ Other stuff | |
|
|
||
| # forward references are useful if you want to referemce a class before it is designed | ||
|
|
||
| def f(foo: A) -> int: # this will fail | ||
| def f(foo: A) -> int: # this will fail at runtime | ||
| ... | ||
|
|
||
| class A: | ||
|
|
@@ -253,7 +251,7 @@ Mypy brings limited support for PEP 526 annotations. | |
| name: str = "Eric Idle" | ||
|
|
||
| # class instances can be annotated as follows | ||
| mc : MyClass = MyClass() | ||
| mc: MyClass = MyClass() | ||
|
|
||
| # tuple packing can be done as follows | ||
| tu: Tuple[str, ...] = ('a', 'b', 'c') | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,8 +46,8 @@ flagged as an error. | |
| .. code-block:: python | ||
|
|
||
| def foo(a: str) -> str: | ||
| return '(' + a.split() + ')' | ||
| # error: Unsupported operand types for + ("str" and List[str]) | ||
| return '(' + a.split() + ')' # error: Unsupported operand types | ||
| # for + ("str" and List[str]) | ||
|
|
||
| If you don't know what types to add, you can use ``Any``, but beware: | ||
|
|
||
|
|
@@ -98,7 +98,7 @@ module: | |
|
|
||
| .. code-block:: python | ||
|
|
||
| import frobnicate # Error: No module "frobnicate" | ||
| import frobnicate # error: No module "frobnicate" | ||
| frobnicate.start() | ||
|
|
||
| You can add a ``# type: ignore`` comment to tell mypy to ignore this | ||
|
|
@@ -123,14 +123,17 @@ Types of empty collections | |
| -------------------------- | ||
|
|
||
| You often need to specify the type when you assign an empty list or | ||
| dict to a new variable, as mentioned earlier: | ||
| dict to a new variable: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| a = [] # type: List[int] | ||
| a = [] # error: Need type annotation for variable | ||
|
|
||
| Without the annotation mypy can't always figure out the | ||
| precise type of ``a``. | ||
| Without an annotation mypy can't always figure out the precise type of ``a``. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| a = [] # type: List[int] | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would make more sense to flip the two examples. Something like the following (I'm omitting the exact words there) |
||
|
|
||
| You can use a simple empty list literal in a dynamically typed function (as the | ||
| type of ``a`` would be implicitly ``Any`` and need not be inferred), if type | ||
|
|
@@ -161,7 +164,8 @@ with the ``Any`` type. | |
| def f() -> None: | ||
| n = 1 | ||
| ... | ||
| n = 'x' # Type error: n has type int | ||
| n = 'x' # error: Incompatible types in assignment (expression | ||
| # has type "str", variable has type "int") | ||
|
|
||
| .. note:: | ||
|
|
||
|
|
@@ -197,15 +201,16 @@ unexpected errors when combined with type inference. For example: | |
|
|
||
| lst = [A(), A()] # Inferred type is List[A] | ||
| new_lst = [B(), B()] # inferred type is List[B] | ||
| lst = new_lst # mypy will complain about this, because List is invariant | ||
| lst = new_lst # error: Incompatible types in assignment (expression | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's worth mentioning that mypy complains about the assignment because of the fact that |
||
| # has type List[B], variable has type List[A]) | ||
|
|
||
| Possible strategies in such situations are: | ||
|
|
||
| * Use an explicit type annotation: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| new_lst: List[A] = [B(), B()] | ||
| new_lst = [B(), B()] # type: List[A] | ||
| lst = new_lst # OK | ||
|
|
||
| * Make a copy of the right hand side: | ||
|
|
@@ -220,7 +225,8 @@ Possible strategies in such situations are: | |
|
|
||
| def f_bad(x: List[A]) -> A: | ||
| return x[0] | ||
| f_bad(new_lst) # Fails | ||
| f_bad(new_lst) # error: Argument 1 to "f_bad" has incompatible | ||
| # type List[B]; expected List[A] | ||
|
|
||
| def f_good(x: Sequence[A]) -> A: | ||
| return x[0] | ||
|
|
@@ -238,17 +244,18 @@ of a name (assume here that ``Shape`` is the base class of both | |
|
|
||
| shape = Circle() # Infer shape to be Circle | ||
| ... | ||
| shape = Triangle() # Type error: Triangle is not a Circle | ||
| shape = Triangle() # error: Incompatible types in assignment | ||
| # (expression has type "Triangle", variable has | ||
| # type "Circle") | ||
|
|
||
| You can just give an explicit type for the variable in cases such the | ||
| above example: | ||
| You can give an explicit type for the variable in cases such the above example: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| shape = Circle() # type: Shape # The variable s can be any Shape, | ||
| # not just Circle | ||
| shape = Circle() # type: Shape # The variable s can be any Shape, | ||
| # not just Circle | ||
| ... | ||
| shape = Triangle() # OK | ||
| shape = Triangle() # OK | ||
|
|
||
| Complex type tests | ||
| ------------------ | ||
|
|
@@ -262,7 +269,8 @@ explicit type cast: | |
| def f(o: object) -> None: | ||
| if type(o) is int: | ||
| o = cast(int, o) | ||
| g(o + 1) # This would be an error without the cast | ||
| g(o + 1) # This would be an error without the cast: | ||
| # error: Unsupported operand types for + ("object" and "int") | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's confusing to write out the error since it doesn't actually happen. I would just leave this comment as is. Alternatively, you can have the following: |
||
| ... | ||
| else: | ||
| ... | ||
|
|
@@ -285,11 +293,11 @@ style anyway). We can write the above code without a cast by using | |
|
|
||
| def f(o: object) -> None: | ||
| if isinstance(o, int): # Mypy understands isinstance checks | ||
| g(o + 1) # Okay; type of o is inferred as int here | ||
| g(o + 1) # Okay; type of o is inferred as int here | ||
| ... | ||
|
|
||
| Type inference in mypy is designed to work well in common cases, to be | ||
| predictable and to let the type checker give useful error | ||
| predictable, and to let the type checker give useful error | ||
| messages. More powerful type inference strategies often have complex | ||
| and difficult-to-predict failure modes and could result in very | ||
| confusing error messages. The tradeoff is that you as a programmer | ||
|
|
@@ -368,9 +376,9 @@ understand how mypy handles a particular piece of code. Example: | |
| .. note:: | ||
|
|
||
| ``reveal_type`` is only understood by mypy and doesn't exist | ||
| in Python, if you try to run your program. You'll have to remove | ||
| any ``reveal_type`` calls before you can run your code. | ||
| ``reveal_type`` is always available and you don't need to import it. | ||
| in Python. You'll have to remove any ``reveal_type`` calls before you run | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: remove all |
||
| your code. ``reveal_type`` is always available and you don't need to import | ||
| it. | ||
|
|
||
| .. _import-cycles: | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be better to keep
<code>here because if you putpassit technically doesn't typecheck. Or, perhaps, we can make the return type of the functionNoneinstead ofbool.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, just tested it and
passdoes typecheck :)I think it's okay to leave
passthere then.