Type Hinting Support
Relevant source files
The following files were used as context for generating this wiki page:
- rope/base/oi/type_hinting/__init__.py
- rope/base/oi/type_hinting/providers/composite.py
- rope/base/oi/type_hinting/resolvers/types.py
- rope/base/oi/type_hinting/providers/pep0484_type_comments.py
- rope/base/oi/type_hinting/providers/numpydocstrings.py
- ropetest/type_hinting_test.py
- rope/contrib/codeassist.py
The Type Hinting Support system in Rope is designed to enhance static analysis by extracting and resolving type information from various sources within Python source code. This system allows the refactoring engine and code assistance tools to infer types that are not explicitly defined through standard assignments, thereby improving the accuracy of completions and refactorings.
The architecture relies on a provider-based model where different strategies (such as parsing PEP 0484 comments, NumPy docstrings, or standard docstrings) are aggregated to provide a unified type inference interface. This enables support for a wide range of Python coding styles and versions.
Sources: rope/base/oi/type_hinting/__init__.py, rope/contrib/codeassist.py
Architecture and Type Resolution Flow
The system uses a hierarchical approach to resolve types. When a type inquiry is made for a parameter or attribute, the TypeHintingProvider interface orchestrates the search through registered providers.
Core Components
| Component | Description |
|---|---|
TypeHintingProvider | Base interface for all type information sources. |
CompositeTypeHintingProvider | Aggregates multiple providers and returns the first valid type found. |
TypeResolver | Resolves string-based type hints into actual Rope PyObject instances. |
evaluate.compile | A custom parser that handles complex type strings like List[Thread] or Union[str, int]. |
Sources: rope/base/oi/type_hinting/__init__.py:1-20, rope/base/oi/type_hinting/providers/composite.py:1-15
Type Resolution Process
The following diagram illustrates how the system resolves a type from a docstring or comment:
The CompositeTypeHintingProvider iterates through its children until one provides a non-null type hint.
Sources: rope/base/oi/type_hinting/providers/composite.py, ropetest/type_hinting_test.py:340-360
Type Providers
Rope implements specific providers to handle different metadata formats used in the Python ecosystem.
PEP 0484 Type Comments
The PEP0484TypeCommentsProvider parses comments in the format # type: <type_str>. This is particularly useful for legacy codebases or variable assignments where inline annotations are not used. It identifies assignments and checks for trailing comments on the same line.
Sources: rope/base/oi/type_hinting/providers/pep0484_type_comments.py, ropetest/type_hinting_test.py:270-290
NumPy and Google Docstrings
The NumPyDocstringProvider extracts type information from function and class docstrings following the NumPy format. It specifically looks for Parameters and Returns sections to identify the types of arguments and return values.
Sources: rope/base/oi/type_hinting/providers/numpydocstrings.py, ropetest/type_hinting_test.py:35-55
Type Hint Parsing
The evaluate.compile function is responsible for turning a string representation of a type into a structure Rope can understand. It supports:
- Nested Types:
List[Dict[str, int]] - Union Types:
str | intorUnion[str, int] - Callables:
(int, int) -> bool
# Example of types handled by evaluate.compile
# Derived from ropetest/type_hinting_test.py:340-370
tests = [
("Foo[Bar]", "('[' (name Foo) [(name Bar)])"),
("(Foo, Bar) -> Baz", "('(' [(name Foo), (name Bar)] (name Baz))"),
("str | threading.Thread", "('|' (name str) (name threading.Thread))")
]
Sources: ropetest/type_hinting_test.py:340-380, rope/base/oi/type_hinting/resolvers/types.py
Integration with Code Assistance
The rope.contrib.codeassist module utilizes type hinting to provide accurate completions. When a user triggers code assist on a variable, the engine checks if a type hint is available to narrow down the possible attributes.
Implementation Details
The BaseTypeResolver class defines the logic for mapping resolved type names to specific collection types in Rope, such as list, set, dict, and tuple.
Parametrized Types Resolution
When resolving types like list[Thread], the ListResolver (and similar resolvers) extracts the internal type Thread and ensures that operations like iteration over the list return instances of Thread.
| Resolver | Handles | Logic |
|---|---|---|
ListResolver | list, Iterable | Returns the first parameter as the item type. |
DictResolver | dict | Maps index 0 to keys and index 1 to values. |
TupleResolver | tuple | Handles both homogeneous and heterogeneous tuples. |
Sources: rope/base/oi/type_hinting/resolvers/types.py:10-60, ropetest/type_hinting_test.py:150-200
Summary
Type Hinting Support in Rope provides a robust framework for static type inference. By combining multiple providers (PEP 0484, NumPy, and standard docstrings) with a sophisticated type string parser, Rope can accurately determine object types in complex scenarios, leading to safer and more effective refactoring and code completion.