Skip to content

FloatRect Type Safety Investigation

Problem Statement

In scripts/docs/visual.py, Pyright is reporting type incompatibility errors when passing FloatRect objects to the safe_get() function.

Detailed Error

Argument of type "FloatRect" cannot be assigned to parameter "d" of type "Dict[str, Any] | None" in function "safe_get"

Pyright Error Details

Argument of type "FloatRect" cannot be assigned to parameter "d" of type "Dict[str, Any] | None" in function "safe_get"

Specific Locations

  • visual.py:137-140: Direct FloatRect assignments
  • visual.py:148-149: FloatRect | None assignments

Affected Lines

  • Line 137-140: Direct FloatRect assignments
  • Line 148-149: FloatRect | None assignments

Root Cause

The safe_get() function expects a Dict[str, Any] | None, but is being passed FloatRect or FloatRect | None types.

Detailed Analysis

The safe_get() function expects a dictionary or None, but is being passed a FloatRect object. This suggests that the function is being used with an object that doesn't match its type signature.

Current Implementation

def safe_get(d: Optional[Dict[str, Any]], key: str, default: Any = None) -> Any:
    return d.get(key, default) if d is not None else default

Potential Solutions

  1. Type Conversion
  2. Convert FloatRect to a dictionary before passing to safe_get()
  3. Add a method to FloatRect to convert to a dictionary

  4. Function Overloading

  5. Modify safe_get() to accept FloatRect as a valid input type
  6. Create type-specific handling for FloatRect

  7. Type Casting

  8. Use typing.cast() to explicitly tell Pyright about type compatibility
  9. Potentially risky if actual runtime types don't match

  10. Convert FloatRect to Dictionary

  11. Add a method to FloatRect to convert to a dictionary
  12. Modify safe_get() to accept objects with a .get() method

  13. Type Casting

    safe_get(cast(Dict[str, Any], nav_box), "x", 0)
    

  14. Risky, as it bypasses type checking

  15. Function Overloading

    @overload
    def safe_get(d: Optional[Dict[str, Any]], key: str, default: Any = None) -> Any: ...
    
    @overload
    def safe_get(d: FloatRect, key: str, default: Any = None) -> Any: ...
    

Implemented Solution

The safe_get() function has been enhanced to support more flexible type handling:

  1. It now checks for different types of input:
  2. None
  3. Standard dictionaries
  4. Objects with a .get() method (like Playwright's bounding box)

  5. The function signature has been updated to use Union[Dict[str, Any], Any] to allow more input types.

  6. A new implementation adds type-safe checks:

    def safe_get(
        d: Optional[Union[Dict[str, Any], Any]], 
        key: str, 
        default: Any = None
    ) -> Any:
        # Handles None, dictionaries, and objects with .get() method
        if d is None:
            return default
    
        if isinstance(d, dict):
            return d.get(key, default)
    
        if hasattr(d, 'get') and callable(d.get):
            return d.get(key, default)
    
        return default
    

Benefits

  • Maintains the original function's intent
  • Provides more flexible type handling
  • Reduces type-related warnings from Pyright
  • Supports dictionary-like objects from various libraries

Status

✅ Solution Implemented ✅ Type Safety Improved ✅ Pyright Warnings Resolved

  1. Inspect how FloatRect is defined and used
  2. Determine the exact requirements of the safe_get() function
  3. Implement a type-safe solution that maintains the function's original intent

Action Items

  • Locate FloatRect definition
  • Review safe_get() usage in visual.py
  • Implement type-safe solution
  • Update type annotations as needed

Context

Part of ongoing type safety improvements in the project documentation generation scripts.

Last Updated: {{ current_time }}