Enhance Code Reliability with Mypy Type Checking
This challenge focuses on integrating static type checking into a Python project using MyPy. Static type checking helps catch a significant class of bugs early in the development cycle by verifying type consistency before code execution. You will be tasked with setting up MyPy and resolving type errors in a provided code snippet.
Problem Description
Your task is to make a given Python script fully compliant with MyPy's static type checking. This involves:
- Installing MyPy: If not already installed.
- Running MyPy: Executing MyPy against the provided Python code.
- Resolving Type Errors: Identifying and fixing all type-related errors reported by MyPy. This might involve adding type annotations, adjusting function signatures, or correcting existing type usage.
- Ensuring a Clean Run: The ultimate goal is to run MyPy on your modified code and receive no error output, indicating that all type annotations are consistent.
Key Requirements:
- The provided Python script must be runnable after your modifications.
- MyPy must report zero errors when run against the final version of the script.
- Do not introduce significant changes to the core logic or functionality of the script. The focus is solely on type correctness.
Expected Behavior:
When MyPy is executed on your corrected code, it should exit with a status code of 0 and produce no output on stderr.
Edge Cases to Consider:
- Complex Type Hinting: Be prepared to handle more intricate type hints like
Optional,Union,List,Dict, and customTypedDictif they are present or become necessary. - Third-Party Libraries: If the script uses external libraries, you might need to ensure you have their corresponding type stubs installed (e.g.,
pip install mypy-extensionsorpip install types-requests).
Examples
Example 1: Basic Type Annotation and Error Correction
# Original Code (before your modifications)
def greet(name):
return f"Hello, {name}!"
message = greet(123)
print(message)
MyPy Output (Illustrative):
main.py:3: error: Argument 1 to "greet" of "..." has incompatible type "int"; expected "str" [arg-type]
main.py:5: error: Cannot infer type of ... [possibly-undefined]
Found 2 errors in 1 file (checked 1 source file)
Your Task: Modify the code to include type annotations and correct the call to greet.
Corrected Code (Illustrative Output):
# Your Corrected Code
def greet(name: str) -> str:
return f"Hello, {name}!"
message: str = greet("Alice")
print(message)
MyPy Output (After your corrections):
# No output, indicating success
Explanation:
The original greet function accepted any type for name, but was intended to work with strings. The call greet(123) passed an integer. By adding the type hint name: str to the function signature and message: str to the variable, and by correcting the call to greet("Alice"), MyPy can now verify type consistency.
Example 2: Handling Optional Types
# Original Code (before your modifications)
def get_user_id(username):
if username == "admin":
return 1
else:
return None
user_id = get_user_id("guest")
if user_id:
print(f"User ID: {user_id}")
else:
print("User not found.")
MyPy Output (Illustrative):
main.py:2: error: Missing return type annotation for "get_user_id" [no-untyped-def]
main.py:6: error: Unsupported operand types for == ("None" and "str") [operator]
Found 2 errors in 1 file (checked 1 source file)
Your Task: Add type hints, including for optional return values, and fix type incompatibilities.
Corrected Code (Illustrative Output):
# Your Corrected Code
from typing import Optional
def get_user_id(username: str) -> Optional[int]:
if username == "admin":
return 1
else:
return None
user_id: Optional[int] = get_user_id("guest")
if user_id is not None: # More explicit check for None
print(f"User ID: {user_id}")
else:
print("User not found.")
MyPy Output (After your corrections):
# No output, indicating success
Explanation:
The get_user_id function could return either an integer or None. This is represented by Optional[int]. The comparison username == "admin" was also problematic because username's type wasn't explicitly defined, and get_user_id("guest") returned None, which MyPy flagged in the if user_id: check (though the explicit is not None is a clearer Pythonic way and also resolves MyPy warnings).
Constraints
- The provided Python script will be Python 3.8 or later.
- The script will not rely on overly obscure or highly experimental Python features.
- You are expected to use standard MyPy configurations. No advanced or custom plugins are required.
- The primary focus is on correctness of type hints and adherence to MyPy's findings, not on optimizing runtime performance.
Notes
- You will be provided with a Python script file (e.g.,
main.py). Your task is to modify this file in place or create a new corrected version. - The goal is to achieve a successful MyPy run with no errors reported.
- Familiarize yourself with common type hints like
str,int,float,bool,List,Dict,Tuple,Set,Optional, andUnion. - Use
mypy your_script_name.pyto run the checks. - Consider using a type checking configuration file (
mypy.iniorpyproject.toml) for more complex projects, though for this challenge, direct execution might suffice. - Remember that type checking happens statically; it does not affect the runtime behavior of your code, but it drastically improves its robustness and maintainability.