Skip to main content

How to Validate Types Safely in Python Dictionaries

In Python, dictionaries are powerful but mutable, meaning their structure can change unexpectedly. Validating dictionary types is essential for ensuring data integrity, preventing runtime errors, and building robust applications, especially when handling external data like API responses.

This guide explores techniques for validating dictionary types, checking keys and values, and handling errors gracefully.

Basic Type Validation

The most fundamental check is ensuring that the variable you are working with is actually a dictionary.

Using isinstance()

This built-in function checks if an object is an instance of dict.

def process_data(data):
# ✅ Correct: Validate the input type first
if not isinstance(data, dict):
raise TypeError(f"Expected a dictionary, got {type(data).__name__}")

print("Valid dictionary received.")
return True

# Test Cases
try:
process_data({"id": 1}) # Success
process_data([1, 2]) # Fails (List)
except TypeError as e:
print(f"Error: {e}")

Output:

Valid dictionary received.
Error: Expected a dictionary, got list

Validating Keys and Values

Once you know it's a dictionary, you often need to verify its contents: are the required keys present, and do the values have the correct types?

Checking for Required Keys

def validate_keys(data, required_keys):
# Identify missing keys
missing = [key for key in required_keys if key not in data]

if missing:
raise KeyError(f"Missing required keys: {missing}")
return True

user = {"name": "Alice", "age": 25}
required = ["name", "email"]

try:
validate_keys(user, required)
except KeyError as e:
print(e)

Output:

"Missing required keys: ['email']"

Checking Value Types

You can enforce a schema where specific keys must hold specific data types (e.g., "age" must be an int).

def validate_schema(data, schema):
for key, expected_type in schema.items():
# Check if key exists and if value type matches
if key in data and not isinstance(data[key], expected_type):
raise ValueError(f"Invalid type for '{key}': Expected {expected_type.__name__}")
print("Schema validation passed.")

schema = {
"name": str,
"age": int,
"active": bool
}

user_data = {"name": "Bob", "age": "thirty", "active": True}

try:
validate_schema(user_data, schema)
except ValueError as e:
print(e)

Output:

Invalid type for 'age': Expected int

Error Handling and Safe Access

Even with validation, accessing keys can fail. Robust code handles these exceptions gracefully.

Using .get() for Safety

The .get() method returns None (or a default value) instead of raising a KeyError if a key is missing.

config = {"theme": "dark"}

# ⛔️ Unsafe: Raises KeyError if 'lang' is missing
# language = config["lang"]

# ✅ Correct: Returns 'en' default if missing
language = config.get("lang", "en")
print(f"Language: {language}")

Output:

Language: en

Try-Except Blocks

When performing operations on dictionary values (like conversion), wrap them in try-except blocks.

data = {"count": "not_a_number"}

try:
count = int(data["count"])
except KeyError:
print("Key 'count' is missing.")
except ValueError:
print("Value for 'count' is not a valid integer.")

Output:

Value for 'count' is not a valid integer.

Using Decorators for Complex Validation

For reusable validation logic across multiple functions, decorators keep your code clean.

import functools

def validate_dict_input(func):
@functools.wraps(func)
def wrapper(data, *args, **kwargs):
if not isinstance(data, dict):
raise TypeError("Input must be a dictionary")
return func(data, *args, **kwargs)
return wrapper

@validate_dict_input
def analyze_metrics(metrics):
print(f"Analyzing {len(metrics)} metrics...")

# Usage
analyze_metrics({"cpu": 90}) # Works
# analyze_metrics("invalid") # Raises TypeError automatically

Output:

Analyzing 1 metrics...

Conclusion

To validate dictionaries safely in Python:

  1. Use isinstance(obj, dict) to verify the data structure.
  2. Validate Keys & Types using helper functions or schemas to ensure data integrity.
  3. Use .get() for optional keys to avoid crashes.
  4. Use try-except to catch KeyError and TypeError when processing untrusted input.