Skip to content

Conversation

@rchristof
Copy link

Refactor expr_to_unanalyzed_type by extracting helper functions

Relates to #5917

This PR addresses the long function issue by splitting expr_to_unanalyzed_type into smaller, more manageable pieces.

What changed

The main expr_to_unanalyzed_type function was 189 lines long, which made it difficult to read and maintain. I've extracted the logic for each expression type into its own helper function:

  • _translate_name_expr - handles name expressions (True, False, identifiers)
  • _translate_member_expr - handles member access (a.b.c)
  • _translate_index_expr - handles subscript expressions (List[int])
  • _translate_union_op - handles the | operator for unions
  • _translate_callable_argument - handles callable argument constructors
  • _translate_list_expr - handles list expressions for type lists
  • _translate_unary_expr - handles unary operators like -42
  • _translate_dict_expr - handles dict expressions for TypedDict
  • _get_base_fullname - helper for resolving Annotated types

The main function is now 60 lines and acts as a simple dispatcher. Each helper is focused on one specific expression type.

Why this helps

  • The main function is now just a clean dispatcher showing all supported expression types at a glance
  • Each expression type's logic is isolated, making it easier to understand and modify
  • The pattern follows what's already done throughout the codebase (similar to analyze_ref_expr in checkexpr.py)
  • All helper functions stay under 85 lines

Notes

All the new helpers are marked as private (underscore prefix) since they're internal implementation details. The public API remains unchanged.

rchristof and others added 2 commits November 6, 2025 14:26
Split the 189-line `expr_to_unanalyzed_type` function into smaller,
focused helper functions to improve readability and maintainability.

This addresses the issue of long functions in the codebase by:
- Extracting each expression type handler into a dedicated function
- Maintaining identical behavior and error handling
- Preserving all comments and documentation
- Using descriptive function names that clarify intent

Each helper function handles one expression type:
- `_translate_name_expr`: Handle NameExpr (True/False/identifiers)
- `_translate_member_expr`: Handle MemberExpr (dotted names)
- `_translate_index_expr`: Handle IndexExpr (generic types like List[int])
- `_translate_union_op`: Handle OpExpr with | operator (X | Y unions)
- `_translate_callable_argument`: Handle CallExpr for callable arguments
- `_translate_list_expr`: Handle ListExpr for type lists
- `_translate_unary_expr`: Handle UnaryExpr (e.g., -42)
- `_translate_dict_expr`: Handle DictExpr for TypedDict literals

Additional helper:
- `_get_base_fullname`: Extract logic for resolving Annotated types

The main function now serves as a clean dispatcher, making it easier
to understand the supported expression types at a glance. All helper
functions are private (prefixed with _) as they are implementation
details not meant for external use.

No functional changes - this is a pure refactoring to improve code
organization and reduce cognitive complexity.
@rchristof rchristof changed the title Refact Refactor expr_to_unanalyzed_type by extracting helper functions Nov 6, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 6, 2025

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant