Python Bytes is a weekly podcast hosted by Michael Kennedy and Brian Okken. The show is a short discussion on the headlines and noteworthy news in the Python, developer, and data science space.

#439 That Astral Episode

July 07, 2025 00:26:36 4.46 MB ( 22.49 MB less) Downloads: 0
Topics covered in this episode:
Watch on YouTube

About the show

Sponsored by Sentry: pythonbytes.fm/sentry

Connect with the hosts

Join us on YouTube at pythonbytes.fm/live to be part of the audience. Usually Monday at 10am PT. Older video versions available there too.

Finally, if you want an artisanal, hand-crafted digest of every week of the show notes in email form? Add your name and email to our friends of the show list, we'll never share it.

Michael #1: ty documentation site and uv migration guide

Brian #2: uv build backend is now stable + other Astral news

  • The uv build backend is now stable

    • Tim Hopper via Python Developer Tooling Handbook
  • From Charlie Marsh

    • “The uv build backend is now stable, and considered ready for production use. An alternative to setuptools, hatchling, etc. for pure Python projects, with a focus on good defaults, user-friendly error messages, and performance. When used with uv, it's 10-35x faster.”
    • “(In a future release, we'll make this the default.)”

      [build-system]
      requires = ["uv_build>=0.7.19,<0.8.0"]
      build-backend = "uv_build"
      
    • I believe it’s faster, but I agree with Brett Cannon in asking “What's being benchmarked? I'm not sure what a "backend sync" is referring to other than maybe installing the build back-end?”

  • See also: uv: Making Python Local Workflows FAST and BORING in 2025 - Hynek

Brian #3: Refactoring long boolean expressions

  • Trey Hunner

  • This is applied boolean logic, and even folks who learned this in a CS program probably did so early on, and may have forgotten it.

  • How can you improve the readability of long Boolean expressions in Python?

    • Put parens around the whole expression and separate clauses onto different lines

    • Where to put boolean operators between clauses? at the end of the line or the beginning?

      • PEP8 recommends the beginning
        if (expression1
        and expression2
        and expression3):
        ...
        
    • Naming sub-expressions with variables

      • Odd downside that wouldn’t occur to me. All expressions are evaluated, thus not taking advantage of expression short-circuiting.
    • Naming operations with functions

      • Less readable, but takes advantage of short-circuiting
    • Using De Morgan’s Law : replacing a compound expression with a similar (and hopefully easier to read) expression

      # neither: we want both to be false
      not (a or b) == (not a) and (not b)
      
      # never_both: at least one false
      not (a and b) == (not a) or (not b)
      

Michael #4: fastapi-ml-skeleton

  • FastAPI Skeleton App to serve machine learning models production-ready.
  • This repository contains a skeleton app which can be used to speed-up your next machine learning project.
  • The code is fully tested and provides a preconfigured tox to quickly expand this sample code.
  • A sample regression model for house price prediction is included in this project.
  • Short write up on "What does set -a do?"

Extras

Brian:

Michael:

  • via Wei Lee

  • Extra Airflow ruff rules:

    Starting from Ruff version 0.11.13, most changes from Airflow 2 to Airflow 3 can be automated using AIR3. (It’s still in preview so a “—-preview” flag is needed)

    e.g., if you have the following Airflow 2 code

    import datetime
    
    from airflow.models import DAG
    from airflow.operators.empty import EmptyOperator
    
    with DAG(
      dag_id="my_dag_name",
      start_date=datetime.datetime(2021, 1, 1),
      schedule_interval="@daily",
    ):
    EmptyOperator(task_id="task")
    

    it can be fixed with uvx ruff check --select AIR3 --fix --unsafe-fixes --preview

    import datetime
    
    from airflow.sdk import DAG
    from airflow.providers.standard.operators.empty import EmptyOperator
    
    with DAG(
      dag_id="my_dag_name",
      start_date=datetime.datetime(2021, 1, 1),
      schedule="@daily",
    ):
    EmptyOperator(task_id="task")
    

    which works with Airflow 3.

Joke: