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

Expand "getting started" docs to discuss type hints in more detail #6226

Merged
merged 5 commits into from Feb 1, 2019

Conversation

Projects
None yet
4 participants
@Michael0x2a
Copy link
Collaborator

commented Jan 20, 2019

This pull request expands our "getting started" docs so they discuss how to use type hints in more detail.

In general, I'm hoping this pull request will accomplish two main things:

  1. Give users a better "tour" of the available PEP 484 types.

  2. Do a better job of giving users a "heads-up" of common gotchas: for example, how dynamically typed functions aren't type-checked.

Here's a list of specific changes I made:

  1. I combined "Installing mypy" and "Running mypy" into one section.

  2. I modified the "Function signatures" section to focus more on the distinction between dynamic and static typing: I suspect that's a common tripup new users run into.

    I also changed the examples so they'll actually produce a runtime error if you misuse them.

  3. I moved the existing text on annotating no-argument functions or functions with default arguments into a separate "More function signatures" to try and keep the new "Function signatures and dynamic vs static typing" section focused.

  4. I expanded the section about using the "typing" module to be more thorough. In particular, I wanted to expose the user to the concept of concrete generic types (List), abstract generic types/protocols (Iterable), and to more non-conventional types like Union.

    I think these three examples are broadly representative of the different "flavors" of PEP 484 types and so should help new users be a little more aware of the kinds of things they can do with types.

    The main thing that's missing is an introduction to custom generic classes and functions: that's probably too complex of a topic to belong in this page.

  5. I added a section on local type inference: it's a new concept for people who are more used to languages like Java or C# so felt like it was worth mentioning.

    This section also covers the other stumbling block I think new users are likely to run into: the "Need type annotation for 'variable'" error message.

  6. I added a section on customizing mypy via the command line flags. I don't think enough users are aware that you can do this, despite how useful the flags can be.

Expand "getting started" docs to discuss type hints in more detail
This pull request expands our "getting started" docs so they discuss how
to use type hints in more detail.

In general, I'm hoping this pull request will accomplish two main
things:

1. Give users a better "tour" of the available PEP 484 types.

2. Do a better job of giving users a "heads-up" of common gotchas:
   for example, how dynamically typed functions aren't type-checked.

Here's a list of specific changes I made:

1. I combined "Installing mypy" and "Running mypy" into one section.

2. I modified the "Function signatures" section to focus more on the
   distinction between dynamic and static typing: I suspect that's
   a common tripup new users run into.

   I also changed the examples so they'll actually produce a runtime
   error if you misuse them.

3. I moved the existing text on annotating no-argument functions or
   functions with default arguments into a separate "More function
   signatures" to try and keep the new "Function signatures and and
   dynamic vs static typing" section focused.

4. I expanded the section about using the "typing" module to be more
   thorough. In particular, I wanted to expose the user to the concept
   of concrete generic types (List), abstract generic types/protocols
   (Iterable), and to more non-conventional types like Union.

   I think these three examples are broadly representative of the
   different "flavors" of PEP 484 types and so should help new users
   be a little more aware of the kinds of things they can do with types.

   The main thing that's missing is an introduction to custom generic
   classes and functions: that's probably too complex of a topic to
   belong in this page.

5. I added a section on local type inference: it's a new concept for
   people who are more used to languages like Java or C# so felt like
   it was worth mentioning.

   This section also covers the final stumbling block I think new users
   are likely to run into: the "Need type annotation for 'variable'"
   error message.

6. I added a section on customizing mypy via the command line flags.
   I don't think enough users are aware that you can do this, despite
   how useful the flags can be.
Show resolved Hide resolved docs/source/getting_started.rst Outdated
Show resolved Hide resolved docs/source/getting_started.rst Outdated
generic types) by looking through the
:ref:`type system reference <overview-type-system-reference>`.

One final note: when adding types, the convention is to import types

This comment has been minimized.

Copy link
@bluetech

bluetech Jan 20, 2019

Is it also fair to say that it is conventional to put typing imports as the first imports? (It seems like it to me, at least).

If it's not actually a common convention, then it shouldn't derail this PR, but if it is I think it will be nice to mention.

This comment has been minimized.

Copy link
@Michael0x2a

Michael0x2a Jan 20, 2019

Author Collaborator

I also personally like that style (and I think mypy itself also follows that convention), but I'm thinking it's probably best to not mention this for now -- I'm not sure if other Python linters have caught up on this convention yet. For example, I think isort will sort imports alphabetically?

This comment has been minimized.

Copy link
@ilevkivskyi

ilevkivskyi Jan 20, 2019

Collaborator

I don't have a strong preference, but I also like typing imports first. isort however has a different opinion (maybe it is configurable, I have very little experience with it).

This comment has been minimized.

Copy link
@JukkaL

JukkaL Jan 21, 2019

Collaborator

I don't think that this convention is followed very widely. The mypy implementation doesn't consistently put typing imports first. I would rather not recommend any particular placement for the imports.

Show resolved Hide resolved docs/source/getting_started.rst Outdated

bluetech and others added some commits Jan 20, 2019

Apply suggestions from code review
Co-Authored-By: Michael0x2a <michael.lee.0x2a@gmail.com>
@JukkaL
Copy link
Collaborator

left a comment

Thanks for improving our docs! This should make it easier for new users to get started. Left a bunch of mostly minor comments.

Show resolved Hide resolved docs/source/getting_started.rst Outdated
Show resolved Hide resolved docs/source/getting_started.rst Outdated
Show resolved Hide resolved docs/source/getting_started.rst Outdated

.. code-block:: python
def f():
1 + 'x' # No static type error (dynamically typed)
def stars(*names: str, **kwargs: float) -> float:

This comment has been minimized.

Copy link
@JukkaL

JukkaL Jan 21, 2019

Collaborator

I think that this example is a bit too clever. Maybe instead write too simpler (unrelated) functions, one for demonstrating *args and the other for **kwargs.

This comment has been minimized.

Copy link
@Michael0x2a

Michael0x2a Jan 22, 2019

Author Collaborator

I decided to just give up on trying to come up with a motivated example in this case and just left in comments describing what types 'args' and 'kwargs' would have.

generic types) by looking through the
:ref:`type system reference <overview-type-system-reference>`.

One final note: when adding types, the convention is to import types

This comment has been minimized.

Copy link
@JukkaL

JukkaL Jan 21, 2019

Collaborator

I don't think that this convention is followed very widely. The mypy implementation doesn't consistently put typing imports first. I would rather not recommend any particular placement for the imports.

Show resolved Hide resolved docs/source/getting_started.rst Outdated
Show resolved Hide resolved docs/source/getting_started.rst Outdated
add a dynamically-typed function by mistake. You can make mypy do this
by running mypy with the ``--disallow-untyped-defs`` flag.

One particularly useful command is the ``--strict`` flag. Running

This comment has been minimized.

Copy link
@JukkaL

JukkaL Jan 21, 2019

Collaborator

I'm not sure if we should recommend --strict here. Even mypy doesn't use all the options it enables yet. At least I think that there is too much emphasis on it now. I think it might be okay to mention it here as option for people who want to go the extra mile.

This comment has been minimized.

Copy link
@Michael0x2a

Michael0x2a Jan 22, 2019

Author Collaborator

Ok, I decreased the emphasis a bit -- let me know if you want me to go even further.

@JukkaL

This comment has been minimized.

Copy link
Collaborator

commented Jan 21, 2019

Two more things:

  • Optional[x] is very common -- more common than regular union types. Maybe at least add a quick mention?
  • Maybe also quickly introduce Tuple[...], since tuple types are common.
Respond to Ivan and Jukka's code reviews
- Fix small suggestions made
- Simplify the `*args` and `**kwargs` example (or rather, just give up
  on constructing an example altogether)
- Sneak in an example of `Tuple[...]` when discussing `*args`
- Discuss `Optional[...]` -- and also sneak in an example of mypy
  understanding `x is None` checks.
@Michael0x2a

This comment has been minimized.

Copy link
Collaborator Author

commented Jan 22, 2019

@ilevkivskyi and @JukkaL -- ok, this should be ready for a second look whenever!

@JukkaL -- I added in a section about Optional types, as suggested. I also tried adding in some discussion of Tuple, but everything I tried adding felt a little bloated. I think as a compromise, what I'll do is submit a follow-up diff where I expand the "built-in types" page and have the "getting started" page directly link to that.

.. code-block:: python
# If you are using Python 3.6+, you can use variable annotations.
# See https://www.python.org/dev/peps/pep-0526/ for more on variable annotations.

This comment has been minimized.

Copy link
@ilevkivskyi

ilevkivskyi Jan 22, 2019

Collaborator

I think a clickable link would look better. For example, ...we could `annotate <pep526_>`_ it... in the text above. Or maybe just abandon this idea, in any case non-clickable links look bad in the docs.

Also I thought most of the documentation uses "you could..." style, but you have couple of "we" in that sentence above.

@JukkaL

JukkaL approved these changes Jan 22, 2019

Copy link
Collaborator

left a comment

Thanks for the updates! Looks good to me now, just one minor comment.

print('Hello, {}'.format(name))
print('Hello ' + name)
As a final example, suppose want to write a function that can accept *either*

This comment has been minimized.

Copy link
@JukkaL

JukkaL Jan 22, 2019

Collaborator

Nit: this is no longer the final example.

@Michael0x2a Michael0x2a merged commit 9ffb7ca into python:master Feb 1, 2019

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details

@Michael0x2a Michael0x2a deleted the Michael0x2a:expand-getting-started branch Feb 1, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.