To what extent does Google Colab support Python typing?

Viewed 1370

I've entered code that had these lines.

from typing import Dict, List, Set, Tuple

def pairs_sum_to_k(a_set: Set[int], k: int) -> List[Tuple[int, int]]:
    ...

The code compiled and ran. That's good. It's also good that when I attempted to import something that wasn't in typing Colab generated an error message.

What's not good is that when the type hints were inconsistent with the program, , e.g., change the return type to a simple int, Colab didn't complain. This suggests that Colab can deal with type hint syntax, but that it doesn't do anything at all with the type declarations. Is that the case? What kind of typing support, if any, should I expect from Colab?

Thanks.

1 Answers

Type annotations in Python are just decoration – Python does not do any type validation natively. From the Python docs:

Note: The Python runtime does not enforce function and variable type annotations. They can be used by third party tools such as type checkers, IDEs, linters, etc.

If you want to validate your types, you need to use a tool like mypy, which is designed to do this.

I'm not aware of any built-in type checking functionality in Colab, but it's relatively straightforward to define yourself. For example, you could create a Jupyter cell magic that performs typechecks on the cell contents using mypy:

# Simple mypy cell magic for Colab
!pip install mypy
from IPython.core.magic import register_cell_magic
from IPython import get_ipython
from mypy import api

@register_cell_magic
def mypy(line, cell):
  for output in api.run(['-c', '\n' + cell] + line.split()):
    if output and not output.startswith('Success'):
      raise TypeError(output)
  get_ipython().run_cell(cell)

Then you can use it like this:

%%mypy

def foo(x: int) -> int:
  return 2 * x

foo('a')

Upon execution, this is the output:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-21dcff84b262> in <module>()
----> 1 get_ipython().run_cell_magic('mypy', '', "\ndef foo(x: int) -> int:\n  return 2 * x\n\nfoo('a')")

/usr/local/lib/python3.6/dist-packages/IPython/core/interactiveshell.py in run_cell_magic(self, magic_name, line, cell)
   2115             magic_arg_s = self.var_expand(line, stack_depth)
   2116             with self.builtin_trap:
-> 2117                 result = fn(magic_arg_s, cell)
   2118             return result
   2119 

<ipython-input-5-d2e45a31f6bb> in mypy(line, cell)
      8   for output in api.run(['-c', '\n' + cell] + line.split()):
      9     if output:
---> 10       raise TypeError(output)
     11   get_ipython().run_cell(cell)

TypeError: <string>:6: error: Argument 1 to "foo" has incompatible type "str"; expected "int"
Found 1 error in 1 file (checked 1 source file)
Related