Everything You Need to Know About Typing Extensions in Python for Smarter Code

Introduction to Typing Extensions in Python

The typing-extensions library provides support for new type hints and typing-related utilities introduced in new versions of Python, enabling you to use these features even if you’re working with older Python environments. It’s a must-have for developers who want to adhere to type safety and leverage newer type-checking innovations without being constrained by their Python version. This post dives deep into the key features and APIs of typing-extensions, complete with illustrative examples and an app implementation.

Why Typing Extensions?

New features in Python’s typing module are generally introduced with every Python release. However, not everyone can upgrade their Python version right away. The typing-extensions package ensures you don’t miss out on these functionalities, bridging the gap between past and current Python releases. Let’s look at its rich set of APIs.

Key APIs in Typing Extensions with Examples

TypedDict

Typed dictionaries allow you to define dictionaries with a specific set of keys and associated value types.

  from typing_extensions import TypedDict

  class Book(TypedDict):
      title: str
      author: str
      pages: int

  my_book: Book = {"title": "1984", "author": "George Orwell", "pages": 328}
  

Literal

Use Literal to define variables or function parameters that can only take pre-specified values.

  from typing_extensions import Literal

  def color_name(color: Literal["red", "green", "blue"]) -> str:
      return f"The selected color is {color}"

  print(color_name("red"))
  

Final

Mark a variable as final to indicate that it should not be reassigned.

  from typing_extensions import Final

  MAX_CONNECTIONS: Final = 10

  # MAX_CONNECTIONS = 20  # This will raise a type checker error
  

Protocol

Defines a structural interface that a class can implement without explicit inheritance.

  from typing_extensions import Protocol

  class SupportsAdd(Protocol):
      def add(self, value: int) -> int:
          ...

  class Counter:
      def __init__(self, initial: int):
          self.total = initial

      def add(self, value: int) -> int:
          self.total += value
          return self.total

  counter: SupportsAdd = Counter(10)
  print(counter.add(5))
  

@override Decorator

The @override decorator helps ensure you’re properly overriding methods in derived classes.

  from typing_extensions import override

  class Base:
      def greet(self) -> str:
          return "Hello from Base"

  class Subclass(Base):
      @override
      def greet(self) -> str:
          return "Hello from Subclass"
  

Self

The Self type allows methods to explicitly declare a return type of the same class.

  from typing_extensions import Self

  class FluentCounter:
      def __init__(self, initial: int = 0):
          self.total = initial

      def increment(self, amount: int) -> Self:
          self.total += amount
          return self

  counter = FluentCounter().increment(5).increment(10)
  print(counter.total)
  

Putting It All Together An Example App

Let’s build a simple Python app using typing-extensions features to model a library system.

  from typing_extensions import TypedDict, Literal, Protocol, Self

  class Book(TypedDict):
      title: str
      author: str
      status: Literal["available", "borrowed"]

  class Patron(Protocol):
      def borrow(self, book: Book) -> Self:
          ...
      def return_book(self, book: Book) -> Self:
          ...

  class LibraryUser:
      def __init__(self, name: str):
          self.name = name
          self.borrowed_books = []

      def borrow(self, book: Book) -> Self:
          book["status"] = "borrowed"
          self.borrowed_books.append(book)
          return self

      def return_book(self, book: Book) -> Self:
          book["status"] = "available"
          self.borrowed_books.remove(book)
          return self

  # Example Usage
  library_book = {"title": "1984", "author": "George Orwell", "status": "available"}
  user = LibraryUser("Alice")
  user.borrow(library_book)
  print(library_book)
  user.return_book(library_book)
  print(library_book)
  

Conclusion

The typing-extensions library is a treasure trove for developers working with type hints in Python. With its various APIs, you can write safer, more reliable, and version-independent code. Download and start using typing-extensions today to transform your Python programming experience!

Leave a Reply

Your email address will not be published. Required fields are marked *