Feature Request: Infer TypeVar Bounds from assert issubclass Statements
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Feature
I would like to request an enhancement in mypy to allow it to infer TypeVar bounds from assert issubclass(...) statements. Currently, mypy uses such assertions for local type refinement within the scope of the assertion, but it does not propagate these refinements globally, particularly for type variables. This leads to cases where developers must manually specify TypeVar bounds, even though the bound could be logically inferred from the assertions in the code.
Use Case:
Consider a scenario where a function takes a Type[T] parameter, and an assert issubclass(cls, MyAbstractClass) check is used to ensure that cls is a subclass of MyAbstractClass. Despite this assertion, mypy does not infer that T is bound by MyAbstractClass, which can lead to type-checking issues where mypy cannot guarantee that cls has the necessary methods or attributes.
Example:
from typing import Type, TypeVar, BinaryIO
from abc import ABC, abstractmethod
class MyAbstractClass(ABC):
@classmethod
@abstractmethod
def from_binary_io(cls, data: BinaryIO) -> 'MyAbstractClass':
pass
T = TypeVar('T')
def create_instance(cls: Type[T], data: BinaryIO) -> T:
assert issubclass(cls, MyAbstractClass)
return cls.from_binary_io(data)
# Example subclass implementation
class MyConcreteClass(MyAbstractClass):
def __init__(self, content: bytes):
self.content = content
@classmethod
def from_binary_io(cls, data: BinaryIO) -> 'MyConcreteClass':
content = data.read()
return cls(content)
In this example, mypy does not infer that T is bound by MyAbstractClass, leading to type-checking issues when calling cls.from_binary_io(data).
Proposed Enhancement:
mypy should be able to infer the bound of T as MyAbstractClass based on the assert issubclass(cls, MyAbstractClass) statement. This enhancement would allow developers to avoid manually specifying bounds for TypeVar when they can be logically deduced from the code.
Pitch
Benefits:
- Improved Type Inference: Reduces the need for explicit TypeVar bounds, leading to cleaner and more maintainable code.
- Better Developer Experience: Simplifies code and reduces potential for type-related errors, especially in complex generic scenarios.
Potential Challenges:
- Implementation Complexity: This feature would require mypy to track and propagate type refinements beyond the local scope, potentially increasing the complexity of type inference.
- Performance Considerations: Careful consideration would be needed to ensure that this additional type inference does not negatively impact the performance of mypy.
I believe this feature would significantly improve mypy's type inference capabilities and make it even more powerful for developers working with generics and abstract base classes.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The issue names no implementation files or tests. Start by reproducing the create_instance example with mypy, then trace the handling of assert issubclass(cls, MyAbstractClass) and TypeVar refinement; done means the asserted bound is propagated sufficiently for cls.from_binary_io(data) to type-check without a manually bounded TypeVar.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers, devtools
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100