Introduction to typing-extensions
Python is a versatile and dynamic programming language, constantly evolving to add more features and enhancements. One of the game-changing additions to Python has been the introduction of type hints in Python 3.5, which provide optional type checking for better code clarity and error prevention. However, not all type hinting features are immediately available in every Python version. This is where the typing-extensions
module comes in. It backports new type hinting features to older Python versions, making your code compatible without sacrificing functionality.
Key APIs from typing-extensions with Examples
The typing-extensions
library provides dozens of useful tools to enhance type hinting in Python. Let’s explore some of the most important features with practical examples.
1. @final
The @final
decorator indicates that a method or class cannot be overridden or subclassed.
from typing_extensions import final @final class ImmutableClass: pass @final def cannot_override(): print("This method cannot be overridden.")
2. Literal
Literal
is used to define a narrow range of acceptable values for a variable.
from typing_extensions import Literal def set_mode(mode: Literal['r', 'w', 'x']) -> None: print(f"Setting mode to {mode}") set_mode('r') # Valid set_mode('z') # Error
3. TypedDict
TypedDict
allows you to define dictionaries with a specific, static structure.
from typing_extensions import TypedDict class Point(TypedDict): x: int y: int point: Point = {'x': 10, 'y': 20} # Valid
4. Protocol
Protocol
makes it possible to specify structural subtyping (or “duck typing”).
from typing_extensions import Protocol class DuckProtocol(Protocol): def quack(self) -> None: pass class Duck: def quack(self) -> None: print("Quack!") def use_protocol(duck: DuckProtocol) -> None: duck.quack() use_protocol(Duck()) # Valid
5. Self
Using Self
, you can hint that an instance method returns an instance of its class.
from typing_extensions import Self class Builder: def add_component(self, component: str) -> Self: print(f"Adding {component}") return self
6. NotRequired
and Required
These hints can be employed with TypedDict
to specify whether a key is optional or mandatory.
from typing_extensions import TypedDict, NotRequired class User(TypedDict): name: str age: NotRequired[int]
App Example: Using Typing Extensions
Let’s build an app example utilizing the APIs introduced above to demonstrate their practical use.
from typing_extensions import Literal, TypedDict, Protocol, final @final class Config: DEFAULT_MODE: Literal['r', 'w'] = 'r' class Settings(TypedDict): theme: str notifications: bool class StartupProtocol(Protocol): def load(self) -> None: pass class App: def __init__(self): self.settings: Settings = {'theme': 'dark', 'notifications': True} def start(self) -> None: print("Starting application...") app = App() app.start()
By combining multiple components of typing-extensions
, you can create robust, error-safe, and backward-compatible Python applications with strong type hinting support.
Conclusion
The typing-extensions
library is an invaluable tool for Python developers who want to adopt modern type hinting features while maintaining compatibility with older Python versions. We introduced several APIs such as @final
, Literal
, TypedDict
, Protocol
, and more, along with their usage examples. Start incorporating typing-extensions
into your projects to write better Python code today!