Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions docs/source/common_issues.rst
Original file line number Diff line number Diff line change
Expand Up @@ -811,3 +811,35 @@ This is best understood via an example:
To get this code to type check, you could assign ``y = x`` after ``x`` has been
narrowed, and use ``y`` in the inner function, or add an assert in the inner
function.

'types' module vs 'typing'
--------------------------

While these two might sound the same,
they are created for completely different purposes.

``typing`` is used for type annotations,
while ``types`` is used to define useful runtime types and primitives.

Types from ``types`` module are not recognised by a type checker,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This isn't always true; a few types in types are useful in annotations (e.g. TracebackType, which is used in __exit__ annotations).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Oh no 😆

I was not aware of that. Any others?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think some people use types.FunctionType? Also I think I've seen types.ModuleType a few times.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Various types in types are properly typed and recognized by type checkers, such as GeneratorType, MappingProxyType, EllipsisType.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@ethanhs ok, then we need a new plan. Maybe we can focus on "valid" usecases of using types? Experience from typeshed will totally help! 👍

here's an example of what you should not do:

.. code-block:: python

import types

def a() -> types.NoneType: # Incompatible return value type (got "None", expected "NoneType")
return None

b: types.FunctionType = a # Incompatible types in assignment (expression has type "Callable[[], NoneType]", variable has type "FunctionType")

Instead, use ``typing`` module:

.. code-block:: python

import typing

def a() -> None:
return None

b: typing.Callable = a # ok