Modern Python

Automate and integrate modern Python workflows with up-to-date best practices

Modern Python is a community skill for writing contemporary Python code following current best practices, covering type hints, dataclasses, async patterns, structural pattern matching, and modern standard library usage for Python development.

What Is This?

Overview

Modern Python provides tools for leveraging recent Python language features and idioms. It covers type hints that annotate function signatures and variable declarations with static type information for tooling and documentation, dataclasses that define structured data containers with automatic initialization, comparison, and representation methods, async patterns that implement concurrent IO operations using async/await syntax with asyncio event loops, structural pattern matching that uses match/case statements for expressive conditional logic on complex data structures, and modern standard library usage that applies improvements from recent Python versions including walrus operators, union types, and improved error messages. The skill enables developers to write cleaner Python code using current language capabilities.

Who Should Use This

This skill serves Python developers upgrading codebases to modern patterns, teams establishing coding standards around recent language features, and educators teaching contemporary Python practices.

Why Use It?

Problems It Solves

Python code written with older patterns misses readability and safety improvements from recent language versions. Manual class boilerplate for data containers adds repetitive code that dataclasses eliminate. Callback-based async code is harder to read and maintain than structured async/await patterns. Complex conditional chains using if/elif become unwieldy where pattern matching provides clearer structure.

Core Highlights

Type annotator adds static type hints for better tooling and documentation support. Dataclass builder generates structured containers from field declarations. Async manager implements concurrent IO with structured concurrency. Pattern matcher applies match/case logic for complex data handling.

How to Use It?

Basic Usage

from dataclasses import (
  dataclass, field)
from typing import (
  Optional)

@dataclass
class Config:
  name: str
  version: str = '1.0'
  features: list[str]\
    = field(
      default_factory=list)
  debug: bool = False

@dataclass
class APIResponse:
  status: int
  data: dict
  error: Optional[str]\
    = None

  @property
  def ok(self) -> bool:
    return (
      200 <= self.status
      < 300)

def handle_response(
  resp: APIResponse
) -> str:
  match resp:
    case APIResponse(
      status=200,
      data=d
    ):
      return (
        f'OK: {len(d)}'
        f' items')
    case APIResponse(
      status=404
    ):
      return 'Not found'
    case APIResponse(
      error=e
    ) if e:
      return (
        f'Error: {e}')
    case _:
      return 'Unknown'

Real-World Examples

import asyncio
from dataclasses import (
  dataclass)

@dataclass
class FetchResult:
  url: str
  status: int
  body: str

class AsyncFetcher:
  def __init__(
    self,
    concurrency:
      int = 5
  ):
    self.sem = (
      asyncio.Semaphore(
        concurrency))

  async def fetch(
    self,
    session,
    url: str
  ) -> FetchResult:
    async with (
      self.sem):
      async with (
        session.get(
          url)
      ) as resp:
        body = await (
          resp.text())
        return (
          FetchResult(
            url=url,
            status=(
              resp.status),
            body=body))

  async def fetch_all(
    self,
    session,
    urls: list[str]
  ) -> list[
    FetchResult
  ]:
    tasks = [
      self.fetch(
        session, url)
      for url in urls]
    results = await (
      asyncio.gather(
        *tasks,
        return_exceptions
          =True))
    return [
      r for r
      in results
      if isinstance(
        r, FetchResult)]

Advanced Tips

Use Protocol classes from typing for structural subtyping that defines interfaces without requiring inheritance. Apply the walrus operator in list comprehensions and while loops to combine assignment with conditional checks. Use TypeAlias and type statement from Python 3.12 for cleaner type alias definitions.

When to Use It?

Use Cases

Refactor a codebase to use dataclasses instead of manually written init and repr methods. Implement concurrent API calls using async/await with semaphore-based rate limiting. Replace complex if/elif chains with pattern matching for handling API response variants.

Related Topics

Python, type hints, dataclasses, async/await, pattern matching, modern idioms, and Python best practices.

Important Notes

Requirements

Python 3.10 or later for pattern matching support. Python 3.12 or later for newest type syntax features. Type checker like mypy or pyright for type hint validation.

Usage Recommendations

Do: add type hints to public function signatures for documentation and tooling benefits. Use dataclasses for data containers instead of plain dicts or manual classes. Apply async patterns for IO-bound concurrent operations.

Don't: add type hints to every internal variable when the type is obvious from context. Use pattern matching for simple conditions where if/else is more readable. Apply async to CPU-bound code since it provides no concurrency benefit without IO waits.

Limitations

Modern syntax features require minimum Python version compatibility that older environments may not support. Type hints are not enforced at runtime and require separate type checkers for validation. Async patterns add complexity to codebases that may not benefit from concurrent execution.