Skip to content

Mutating globals() dict

Detects mutations to the globals() dictionary, which can bypass type checking and lead to runtime type errors.

The globals() function returns a dictionary representing the current global symbol table. When you modify this dictionary directly, you can change the types of global variables at runtime without the type checker being aware of the change.

What gets flagged

Python
1
2
3
4
5
6
x: int = 5

globals()['x'] = "hello"

# Type checker thinks `result` is an `int`, but it is a string
result: int = x
Unsoundness Checker Output
Text Only
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
error[mutating-globals-dict]: Mutating the `globals()` dictionary may lead to runtime type errors.
 --> main.py:3:1
  |
1 | x: int = 5
2 |
3 | globals()['x'] = "hello"
  | ^^^^^^^^^^^^^^
4 |
5 | # Type checker thinks `result` is an `int`, but it is a string
  |
info: rule `mutating-globals-dict` was selected in the configuration file

Mypy: No Diagnostic Emitted

Pyright: No Diagnostic Emitted

Ty: No Diagnostic Emitted

What is okay

If the type of the new value is assignable to the existing type of the symbol, we allow the mutation.

Python
1
2
3
4
x: int = 1

# `Literal[2]` is assignable to `int`
globals()["x"] = 2

Unsoundness Checker: No Diagnostic Emitted

Mypy: No Diagnostic Emitted

Pyright: No Diagnostic Emitted

Ty: No Diagnostic Emitted