Enforcing dictionary access via .get(...) to prevent KeyErrors

128 Views Asked by At

I frequently run into KeyErrors triggered by situations like

d: dict[str, int] = {"a": 1}
foo = "bar"
...
d[foo]  # boom

Our team uses mypy for type checking. If it were possible to automatically detect the use of d[foo], and disallow it in favour of d.get(foo), the result would have an explicit type of Optional[int], which would prevent the author from forgetting about the edge case of the key not existing.

Are there tools that are able to detect and warn about such square-bracket access? Are there situations I'm forgetting where .get(...) doesn't work as an alternative?

1

There are 1 best solutions below

0
On

You can definitely do this with Semgrep, and even suggest the fix:

rules:
- id: use .get
  patterns:
    - pattern-inside: |
        $D = {...}
        ...
    - pattern: $D[$K]
  fix: $D.get($K)
  message: Match found
  languages: [python]
  severity: WARNING

Playground link: https://semgrep.dev/s/B3o5