Comprehensive Guide to Typing Extensions for Python Developers

Comprehensive Guide to Typing Extensions for Python Developers

The typing-extensions module is a crucial library for Python developers who need to maintain compatibility across different versions of Python while leveraging advanced type-hinting capabilities. It provides backports of new type hinting features introduced in newer versions of Python to older versions.

What is Typing Extensions?

The typing-extensions library extends the standard typing module shipped with Python. By importing from typing-extensions, developers can access typing features that may be unavailable in their current Python version.

APIs in Typing Extensions with Examples

1. TypedDict

TypedDict is used for specifying the type of dictionary objects with fixed keys and specified value types.

  from typing_extensions import TypedDict

  class Movie(TypedDict):
      title: str
      year: int

  movie: Movie = {"title": "Inception", "year": 2010}
  print(movie)

2. Literal

Literal restricts a variable to a specific set of values.

  from typing_extensions import Literal

  def get_status_code(code: Literal[200, 400, 404]) -> str:
      if code == 200:
          return "OK"
      elif code == 400:
          return "Bad Request"
      elif code == 404:
          return "Not Found"

  print(get_status_code(200))

3. Protocol

Protocol is a way to define structural subtyping, allowing objects to be considered as instances of a protocol if they implement specific attributes or methods.

  from typing_extensions import Protocol

  class Flyer(Protocol):
      def fly(self) -> None:
          ...

  class Bird:
      def fly(self) -> None:
          print("Flying high!")

  def check_flyer(entity: Flyer) -> None:
      entity.fly()

  bird = Bird()
  check_flyer(bird)

4. Final

Final is used to indicate that a variable or a method is not to be overridden or reassigned.

  from typing_extensions import Final

  MAX_USERS: Final = 10
  print(MAX_USERS)

5. Annotated

Annotated allows adding metadata or constraints to type hints.

  from typing import List
  from typing_extensions import Annotated

  PositiveInt = Annotated[int, "Must be a positive integer"]

  def process_numbers(data: List[PositiveInt]) -> None:
      for num in data:
          if num < 0:
              raise ValueError("All numbers must be positive!")
      print(data)

  process_numbers([1, 2, 3])

6. Self

Self simplifies type hints for methods that return an instance of their class.

  from typing_extensions import Self

  class Node:
      def add_child(self, name: str) -> Self:
          self.child = name
          return self

  root = Node().add_child("child")

Real-World Example

Here, we’ll create a small application to catalog books using several typing-extensions APIs.

  from typing_extensions import TypedDict, Final, Literal

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

  MAX_BOOKS: Final = 5

  def add_book(catalog: list[Book], book: Book) -> Literal["Success", "Full"]:
      if len(catalog) >= MAX_BOOKS:
          return "Full"
      catalog.append(book)
      return "Success"

  catalog = []
  new_book = {"title": "1984", "author": "George Orwell", "published_year": 1949}
  status = add_book(catalog, new_book)
  print(f"Add book status: {status}")
  print(catalog)

Conclusion

The typing-extensions library is indispensable for Python developers who work with type hints and want backward compatibility. With features like TypedDict, Literal, Protocol, and more, you can write more robust and maintainable code in Python. Don't hesitate to incorporate these APIs in your next project for cleaner and better code!

Leave a Reply

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