Get AI summaries of any video or article — Sign up free
Python Tutorial: Type Hinting vs Type Checking vs Data Validation - What’s the Difference? thumbnail

Python Tutorial: Type Hinting vs Type Checking vs Data Validation - What’s the Difference?

Corey Schafer·
5 min read

Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Type hints in Python are metadata for documentation and tooling; they are not enforced at runtime.

Briefing

Python’s type hints, type checking, and data validation solve different problems—even though all three relate to “types.” Type hints document what types a function expects and returns, type checking uses static analysis tools to flag mismatches before the code runs, and data validation enforces rules at runtime to stop bad input from entering an application. Understanding the split matters because it prevents a common mistake: assuming that adding type hints automatically prevents type-related bugs.

Type hinting (also called annotations) adds type information to variables, function parameters, and return values—improving readability and maintainability. In the example, a function takes first name and last name as strings and an age as an integer, and it declares a dictionary return type. Type hints can also be attached to variables that store a function’s result, making expectations visible at the call site. But Python ignores these hints at runtime; they’re metadata. If age is accidentally provided as a string instead of an integer, the program can still run without errors because nothing enforces the declared types during execution.

Type checking addresses that gap by analyzing code before it runs. Static type checkers (the tutorial uses MyPy) read the type hints and report incompatible types—such as passing a string where an integer is expected. In the editor, MyPy surfaces these issues as warnings/errors in a “problems” panel. Crucially, static analysis doesn’t block execution: the code still runs even when the type checker reports a mismatch, because the tool isn’t executing the program and can’t know what dynamic inputs will look like at runtime.

That’s where data validation comes in. Data validation performs runtime verification during execution, and it can fail fast by raising validation errors when inputs don’t meet requirements. It goes beyond basic type checking by validating values such as ranges and formats. The tutorial contrasts manual validation—writing explicit checks and raising errors—with using Pydantic, which leverages type hints to generate validation logic with far less boilerplate. With Pydantic’s validation decorator, invalid input produces detailed error messages that identify which field failed and what was expected. Pydantic can also coerce types in some cases—for example, converting the literal string "38" into an integer—while still allowing strictness to be configured.

In practice, data validation is most valuable for dynamic data: API payloads, user input, configuration loading, and environment variables. For scripts where inputs are hard-coded and controlled, validation may be unnecessary overhead. The recommended progression for real projects is to add type hints incrementally to existing codebases, pair them with an IDE-integrated type checker for early warnings, and reserve runtime validation (often via Pydantic) for external or untrusted data. The tutorial also notes ecosystem fit: Django has its own validation mechanisms, and FastAPI uses Pydantic heavily.

Overall, the three concepts form a pipeline: hints describe intent, static checking catches many mismatches early, and runtime validation protects the application when real-world data refuses to stay neatly typed.

Cornell Notes

Type hints in Python document expected types for function parameters and return values, but they are not enforced at runtime. Static type checking uses tools like MyPy to analyze code before execution and flag mismatches based on those hints, yet it still doesn’t stop the program from running. Data validation happens during execution and can enforce rules by raising errors when inputs fail requirements—often for dynamic data like API payloads or user input. Pydantic demonstrates how type hints can power rich runtime validation with detailed error messages and optional type coercion. Choosing among the three depends on whether the goal is documentation, early static warnings, or runtime protection against bad external data.

Why don’t Python type hints prevent bugs by themselves?

Python treats type hints as metadata that are ignored at runtime. That means assigning a value of the wrong type (for example, providing age as a string when the hint says int) won’t automatically raise an exception. The program can still run normally because nothing enforces the declared types during execution.

What does static type checking add that type hints don’t?

Static type checking analyzes code before it runs and compares actual usage against declared types. Using MyPy, the tutorial shows an editor “problems” warning when a function expecting an integer receives a string. The key limitation remains: static analysis doesn’t block execution, so the code can still run even with reported mismatches.

Why can’t static type checking fully protect applications with dynamic inputs?

Static analyzers can’t know what external data will contain at runtime—such as API payloads, user input, or file contents. Even if the code is type-correct in theory, runtime values may violate expectations. That’s why runtime validation is needed for untrusted or variable data sources.

How does data validation differ from type checking in enforcement and timing?

Type checking is static and happens before runtime; it warns about likely mismatches but doesn’t stop execution. Data validation runs during execution and can halt the program by raising validation errors when inputs fail specific requirements. It also validates more than types, such as formats or value constraints.

What advantages does Pydantic provide over manual validation?

Manual validation requires writing explicit checks and raising errors field by field, which becomes hard to maintain as functions grow. Pydantic uses type hints to generate validation logic automatically, producing more informative error messages (e.g., which field failed and what was expected). It can also coerce inputs like converting the string "38" into an integer, and strictness can be configured.

When should a developer use each tool in real projects?

A practical approach is: add type hints for documentation, use an IDE-integrated type checker (like MyPy) for early warnings, and apply data validation mainly to external/untrusted data (API payloads, users, environment variables, config). For small scripts with hard-coded inputs, runtime validation may be unnecessary overhead.

Review Questions

  1. If age is hinted as int but a string is passed, what happens at runtime and why?
  2. What are the two main limitations of static type checking highlighted in the tutorial?
  3. Give one example of dynamic data where runtime validation is especially important and explain what it prevents.

Key Points

  1. 1

    Type hints in Python are metadata for documentation and tooling; they are not enforced at runtime.

  2. 2

    Static type checking (e.g., with MyPy) uses type hints to catch mismatches before execution, but it doesn’t prevent the program from running.

  3. 3

    Data validation runs at runtime and can raise errors to stop invalid data from entering the application.

  4. 4

    Data validation can check more than types, including formats and value constraints, not just “is this an int?”

  5. 5

    Pydantic can replace large amounts of manual validation code by generating validation from type hints and returning detailed error messages.

  6. 6

    Pydantic may coerce compatible inputs (like "38" to 38) unless strictness is configured otherwise.

  7. 7

    Use type hints and type checking broadly, but reserve data validation primarily for external or untrusted inputs (APIs, users, environment variables).

Highlights

Type hints don’t enforce anything in Python; wrong types can still run without runtime errors.
MyPy can flag incompatible types before execution, yet the code still runs because static analysis doesn’t execute the program.
Pydantic turns type hints into runtime validation with field-level error messages and optional type coercion.
Data validation is most valuable for dynamic inputs like API payloads and user data, not for hard-coded script inputs.

Topics

  • Type Hinting
  • Static Type Checking
  • Runtime Data Validation
  • Pydantic
  • MyPy

Mentioned