Post

Dynamic Type Inference in VS Code: A Deep Dive

In this article, we'll explore how VS Code infers types dynamically, what factors influence this inference, and how to control or refine type inference for your Python code.

Python is a dynamically typed language, meaning variables do not have a fixed type at runtime. However, tools like VS Code (with the Pylance extension) offer type inference to predict the expected types of variables, function arguments, and return values. This feature helps developers catch potential bugs early and enhances the development experience by providing better autocompletion, type checking, and more.


Table of Contents


What is Type Inference?

Type inference is the process by which a programming tool or language automatically determines the type of a variable or expression based on its usage.

In statically typed languages, the type of every variable must be explicitly declared. But in dynamically typed languages like Python, the type of a variable is inferred at runtime based on its value.

VS Code, with the Pylance extension, infers types in Python code dynamically and provides real-time feedback on type-related issues. This improves productivity by providing better code suggestions, highlighting potential type errors, and ensuring the correct use of variables.


How VS Code Infers Types

VS Code uses type inference in several ways to predict the types of variables, function arguments, and return values. Here’s how:

From Initial Assignments

When a variable is assigned a value, VS Code determines its type based on the value assigned.

1
2
3
x = 10       # x is inferred as int
y = "Hello"  # y is inferred as str
z = True     # z is inferred as bool

From Function Calls

VS Code also infers types from function calls. The function signature helps VS Code predict the type of variables used in the function.

1
2
3
4
def add(a: int, b: int) -> int:
    return a + b

result = add(3, 4)  # result is inferred as int

If you pass a mismatched type:

1
result = add("3", 4)  # VS Code warns: Expected int, got str

VS Code will highlight a warning due to the incorrect type.

From List Operations

Lists dynamically update their inferred type based on the elements added.

1
2
3
4
my_list = []
my_list.append(10)      # Inferred as list[int]
my_list.append("hello") # Inferred as list[int | str]
my_list.append([1, 2])  # Inferred as list[int | str | list[int]]

VS Code adapts the list type dynamically based on the elements it contains.


Example of Type Inference in VS Code

Here’s a complete example demonstrating type inference in action:

1
2
3
4
5
6
values = []
values.append(10)           # values is inferred as list[int]
values.append("hello")      # values is now inferred as list[int | str]
values.append([1, 2])       # values is now inferred as list[int | str | list[int]]

print(values)

What Happens Here?

  • Initially, values is an empty list (list[Unknown]).
  • After appending 10, it becomes list[int].
  • After appending "hello", it changes to list[int | str].
  • After appending [1, 2], it updates to list[int | str | list[int]].

VS Code dynamically adjusts its understanding of the list. Resolving this can be done easily with explicit type hinting as such:

1
2
3
values: list[int] = []
values.append()

Now when we hover over it the append function the type hinting will look like the following:

alt text

As we can see that the object the append() takes is int data type. Without the expilict type hint it would type hint Any.


Type Hints and Static Analysis

Although Python is dynamically typed, type hints can provide additional information to VS Code and tools like mypy.

1
2
def add(a: int, b: int) -> int:
    return a + b

With static analysis, type hints can be verified before runtime, catching potential type errors early.


Adjusting Type Inference Behavior

Type Checking Modes

VS Code allows you to configure the level of type checking. The main modes are:

  1. Off: No type checking.
  2. Basic (default): Basic checks for common issues.
  3. Strict: Enforces strict type checking.

To change the type checking mode:

  1. Open VS Code settings (Ctrl + ,).
  2. Search for Python › Analysis: Type Checking Mode.
  3. Choose between Off, Basic, or Strict.

Alternatively, modify settings.json:

1
"python.analysis.typeCheckingMode": "strict"

Using Any for Flexibility

If you want to allow a variable to hold any type:

1
2
3
4
5
from typing import Any

data: Any = 10
data = "Hello"
data = [1, 2, 3]

Using Any removes type restrictions but also disables type checking for that variable.


Common Type Inference Issues in VS Code

  1. Argument Type Mismatch: If a function expects an int but receives a str, VS Code highlights it.
  2. Incorrect Return Type: If a function is annotated to return a type but returns a different one, VS Code warns you.
  3. Using Mixed Types in Lists: Lists with multiple types can lead to complex and unpredictable inferences.

Conclusion

Dynamic type inference in VS Code enhances the development experience by providing real-time feedback, autocompletion, and error detection.

By using type hints, you can improve Python code’s readability, reliability, and maintainability. Adjusting VS Code’s type inference settings ensures a balance between flexibility and strict type checking.

This post is licensed under CC BY 4.0 by the author.