-
-
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 3 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 |
|---|---|---|
|
|
@@ -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: List[int] = [] | ||
|
|
||
| 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,7 +201,8 @@ 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 | ||
| # has type List[B], variable has type List[A]) | ||
|
|
||
| Possible strategies in such situations are: | ||
|
|
||
|
|
@@ -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: Shape = Circle() # 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: | ||
| ... | ||
|
|
@@ -289,7 +297,7 @@ style anyway). We can write the above code without a cast by using | |
| ... | ||
|
|
||
| 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: | ||
|
|
||
|
|
@@ -430,3 +438,23 @@ Here's the above example modified to use ``MYPY``: | |
|
|
||
| def listify(arg: 'bar.BarClass') -> 'List[bar.BarClass]': | ||
| return [arg] | ||
|
|
||
| .. _variable-types: | ||
|
|
||
| Variable definition type syntax | ||
| ------------------------------- | ||
|
|
||
| If running a Python older than 3.6, the following type declaration will fail: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| x: List[str] = [] # SyntaxError: invalid syntax | ||
|
|
||
|
|
||
| You can instead use this format in older Pythons (including 2): | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| x = [] # type: List[str] | ||
|
|
||
|
|
||
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's worth mentioning that mypy complains about the assignment because of the fact that
Listis invariant.