Skip to content

Conversation

@vilmibm
Copy link
Contributor

@vilmibm vilmibm commented May 22, 2017

This addresses #2393.

In addition to adding actual error strings, there are some minor grammar and format edits.

vilmibm added 2 commits May 22, 2017 15:07
To increase google-ability, this commit adds actual error messages where
appropriate.

This commit also contains some very minor grammar and sentence editing.
the x: List[str] = [] style of declaration is new in 3.6 and used
throughout this doc. For users who might be reading this doc and using
an older python, this section explains the older # type: List[str]
format.
Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few nits.


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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/./:/

a = [] # type: List[int]
a = [] # error: Need type annotation for variable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for two blank lines.

Without the annotation mypy can't always figure out the
precise type of ``a``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fewer blank lines here too.

shape = Circle() # type: Shape # The variable s can be any Shape,
# not just Circle
shape: Shape = Circle() # The variable s can be any Shape,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I agree with changing this -- it uses syntax that only works in Python 3.6.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was per @ilevkivskyi 's suggestion, which is why I added the new section at the end about falling back to the pre 3.6 syntax. Perhaps I can demonstrate both in the code example?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to use the same stance as the PY3 cheatsheet: use # type: comments in most places, call out the new PEP 526 syntax in one place.

Backwards compatibility is still important to most people!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree we don't need to change existing docs with respect to PEP 526 syntax.
(Although, I think it is OK to use it from time to time in new docs.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good! Sorry if I misunderstood. I'll take out the section I added, use # type everywhere, and then mention PEP 526 once in the initial introduction of the variable typing.

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK on the whitespace nits.

Will comment separately on the other thing.

This commit switches variable type annotations back to pre python 3.6
syntax and notes the new syntax when variable type annotations are
introduced.
@vilmibm vilmibm changed the title Update error examples in Common Issues documentation [WIP] Update error examples in documentation May 23, 2017
- Adds an actual error to code samples where appropriate
- Fixes some grammatical issues
- Fixes some whitespace
- Removes some inconsistencies in formatting
- Fixes some illegal Python samples (ie forgetting `pass`)
@vilmibm vilmibm changed the title [WIP] Update error examples in documentation Update error examples in documentation May 23, 2017
@vilmibm
Copy link
Contributor Author

vilmibm commented May 23, 2017

This is ready for feedback, now.

@ilinum ilinum self-assigned this Jul 7, 2017
Copy link
Collaborator

@ilinum ilinum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the long response!

Overall it looks good!
Had just a few comments.

):
# type: (...) -> bool
<code>
pass
Copy link
Collaborator

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 put pass it technically doesn't typecheck. Or, perhaps, we can make the return type of the function None instead of bool.

Copy link
Collaborator

@ilinum ilinum Jul 7, 2017

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 pass does typecheck :)
I think it's okay to leave pass there then.

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps, it would be good to give an indication that [4] is the output of the print statement.
Something like

print(c)  # prints [4] because the cast did not change the object's type at runtime

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment for py2 cheatsheet.


.. code-block:: python
a = [] # type: List[int]
Copy link
Collaborator

Choose a reason for hiding this comment

The 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)


1
--
You often need to specify the type...:

a = []  # type: List[int]

Without the annotation...

a = []  # error: Need type annotation for variable

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
Copy link
Collaborator

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 List is invariant.

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")
Copy link
Collaborator

Choose a reason for hiding this comment

The 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:

g(o + 1)  # error: Unsupported operand types for + ("object" and "int")
o = cast(int, o)
g(o + 1)  # This would be an error without the cast

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove all reveal_type calls

tcp_packet = TcpPacketId(packet) # OK
tcp_packet = TcpPacketId(127, 0) # Fails in type checker and at runtime
tcp_packet = TcpPacketId(127, 0) # error: Too many arguments for "TcpPacketId"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps, it would be good to point out that this line fails both in typechecker and at runtime.

Python 3.6 will have an alternative, class-based syntax for named tuples with types.
Mypy supports it already:
Python 3.6 has an alternative, class-based syntax for named tuples with types,
which Mypy supports:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to say which Mypy supports -- that is implied.

It was not obvious before Python 3.6 was released but now it is.

@JukkaL
Copy link
Collaborator

JukkaL commented Nov 24, 2017

@vilmibm Are you interested in finishing up this PR? There is one merge conflict now.

@emmatyping
Copy link
Member

@vilmibm feel free to leave a message if you feel like working on this again. Closing for now.

@emmatyping emmatyping closed this Dec 16, 2017
@gvanrossum
Copy link
Member

(This is an example of a PR where less would have been more -- if it had been broken up into a few smaller parts the majority would probably have landed long ago...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants