Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Adding Intersection Types (&) to Python Type Hints #1906

Closed
kamalfarahani opened this issue Dec 29, 2024 · 2 comments
Closed

Proposal: Adding Intersection Types (&) to Python Type Hints #1906

kamalfarahani opened this issue Dec 29, 2024 · 2 comments
Labels
topic: feature Discussions about new features for Python's type annotations

Comments

@kamalfarahani
Copy link

kamalfarahani commented Dec 29, 2024

Introduction

Python's type hinting system, introduced in PEP 484 and expanded in subsequent PEPs, has become a powerful tool for static type checking and improving code readability. However, one feature that is currently missing is intersection types, which allow specifying that a value must satisfy multiple types or protocols simultaneously. This feature is particularly useful for expressing complex constraints, such as requiring an object to implement multiple interfaces (similar to Rust's trait bounds).

This proposal suggests adding support for the & operator in Python's type hints to represent intersection types.


Motivation

  1. Expressing Multiple Constraints:

    • Currently, Python lacks a concise way to specify that a value must satisfy multiple type constraints. For example, if a function requires an object that implements both Speak and Walk protocols, there is no straightforward way to express this in type hints.
    • Workarounds like Union[Type1, Type2] or Type1 with runtime checks are either incorrect or cumbersome.
  2. Alignment with Other Languages:

    • Many statically typed languages (e.g., TypeScript, Rust, Scala) support intersection types or similar constructs. Adding this feature would bring Python's type system closer to these languages, making it easier for developers to transition between them.
  3. Improved Static Analysis:

    • Intersection types would enable static type checkers (e.g., mypy, pyright) to perform more precise type inference and validation, reducing the likelihood of runtime errors.
  4. Better Code Documentation:

    • Intersection types would make it easier to document complex requirements in function signatures, improving code readability and maintainability.

Proposed Syntax

The & operator would be used to denote intersection types in type hints. For example:

def perform_actions(animal: Speak & Walk) -> None:
    animal.speak()
    animal.walk()

Here, Speak & Walk indicates that the animal parameter must satisfy both the Speak and Walk protocols.


Semantics

  1. Compatibility:

    • An object is considered compatible with an intersection type A & B if it satisfies both A and B. For example:
       from abc import ABC, abstractmethod
       
       # Define "traits" as abstract base classes
       class Speak(ABC):
           @abstractmethod
           def speak(self):
               pass
       
       class Walk(ABC):
           @abstractmethod
           def walk(self):
               pass
       
       # Implement the "traits" in a class
       class Dog(Speak, Walk):
           def speak(self):
               print("Woof!")
       
           def walk(self):
               print("The dog is walking.")
       
       # Function that requires an object implementing both "traits"
       def perform_actions(animal: Speak & Walk):
           animal.speak()
           animal.walk()
       
       # Usage
       my_dog = Dog()
       perform_actions(my_dog)
  2. Static Type Checking:

    • Static type checkers would validate that the object passed to a function with an intersection type hint satisfies all the required types.
  3. Runtime Behavior:

    • Intersection types would have no runtime impact. They are purely for static type checking and documentation.

Backward Compatibility

  • The addition of the & operator for intersection types would be fully backward compatible. Existing code that does not use this feature would remain unaffected.
@kamalfarahani kamalfarahani added the topic: feature Discussions about new features for Python's type annotations label Dec 29, 2024
@TeamSpen210
Copy link

This is a duplicate of #213, also see the dedicated repo. Intersections are desirable, but unfortunately there's lots of difficult edge cases to consider.

@JelleZijlstra
Copy link
Member

Closing as a duplicate. The activity on the linked repo seems to have died down; this idea may need a new champion.

@JelleZijlstra JelleZijlstra closed this as not planned Won't fix, can't repro, duplicate, stale Dec 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: feature Discussions about new features for Python's type annotations
Projects
None yet
Development

No branches or pull requests

3 participants