skip to navigation
skip to content

Planet Python

Last update: August 19, 2025 04:42 AM UTC

August 18, 2025


Python Software Foundation

The 2024 Python Developer Survey Results are here!

August 18, 2025 04:51 PM UTC


PyCharm

This is a guest post from Michael Kennedy, the founder of Talk Python and a PSF Fellow. Welcome to the highlights, trends, and key actions from the eighth annual Python Developers Survey. This survey is conducted as a collaborative effort between the Python Software Foundation and JetBrains’ PyCharm team. My name is Michael Kennedy, and […]

August 18, 2025 04:41 PM UTC


Real Python

Single and Double Underscores in Python Names

Learn Python naming conventions with single and double underscores to design APIs, create safe classes, and prevent name clashes.

August 18, 2025 02:00 PM UTC


PyCharm

The State of Python 2025

August 18, 2025 11:42 AM UTC


Python Bytes

#445 Auto-activate Python virtual environments for any project

Topics include pyx - optimized backend for uv, Litestar is worth a look, Django remake migrations, and django-chronos.

August 18, 2025 08:00 AM UTC


Armin Ronacher

Your MCP Doesn’t Need 30 Tools: It Needs Code

August 18, 2025 12:00 AM UTC

August 17, 2025


Seth Michael Larson

How many RSS subscribers do I have?

August 17, 2025 12:00 AM UTC

August 16, 2025


Made With Mu

RIP Mu

Late last year we announced we’d retire Mu. The core maintainers have all moved onto other things, our lives have changed and the time we have available to maintain Mu has significantly decreased. Perhaps most of all, the world has moved on: when Mu started we were unique in the coding ecosystem. Now there are plenty of development environments focused on beginners.

August 16, 2025 05:00 PM UTC

August 15, 2025


Test and Code

238: So Long, and Thanks for All the Fish

A farewell to a fun 10 years.

Also, I should have tested it better. :)
In the audio I got the numbers wrong.  Doh!
This is episode 238, not 237. Oh well.

I'll still be around, of course, at:

Thanks for all the fun over the last 10 years.
I wish you the best.


Keep in touch


★ Support this podcast on Patreon ★

August 15, 2025 08:20 PM UTC


John Cook

Converting very long strings to integers in Python

In the process of writing the previous post, I wanted to confirm that the number in the post really is prime. This was useful in debugging my manual conversion of the image to text: errors did not result in a prime number. For example, I didn’t see the 9’s in the image at first, and […]

The post Converting very long strings to integers in Python first appeared on John D. Cook.

August 15, 2025 06:45 PM UTC


Real Python

The Real Python Podcast – Episode #261: Selecting Inheritance or Composition in Python

When considering an object-oriented programming problem, should you prefer inheritance or composition? Why wouldn't it just be simpler to use functions? Christopher Trudeau is back on the show this week, bringing another batch of PyCoder's Weekly articles and projects.

August 15, 2025 12:00 PM UTC


Glyph Lefkowitz

The Futzing Fraction

At least some of your time with genAI will be spent just kind of… futzing with it.

August 15, 2025 07:51 AM UTC


Seth Michael Larson

Nintendo Switch Online + Expansion Pack is great for digital and physical GameCube players

August 15, 2025 12:00 AM UTC

August 14, 2025


Python Insider

Python 3.14.0rc2 and 3.13.7 are go!

August 14, 2025 03:37 PM UTC


Python Software Foundation

Announcing the PSF Board Candidates for 2025!

August 14, 2025 12:19 PM UTC

August 13, 2025


Ari Lamstein

🚀 Join Me Tonight for a Hands-On Streamlit Workshop!

I’m excited to announce that I’ll be running a live workshop tonight on Streamlit—the Python framework that makes it easy to build interactive web apps for data projects. This session is designed for those with an interest in data apps and no prior experience with Streamlit. You will walk through the fundamentals with a practical, […]

August 13, 2025 04:37 PM UTC


Django Weblog

Building better APIs: from Django to client libraries with OpenAPI

tl;dr

A summary of resources and learnings related to building REST API I put together over the last couple of years. Complete API development workflow from Django backend to frontend clients using Django REST Framework, drf-spectacular for OpenAPI spec generation, and automated client generation with openapi-generator. Big productivity boost!

There is a lot of discussion about frameworks for building REST APIs, some of them being even able to generate OpenAPI specs directly for you. Django is not quite known for that, but there are ways of doing this by automating most of the process while being very productive and offering your team a clean developer experience.

Overview

The stack I prefer makes use of several additional modules you will require: django-rest-framework and drf-spectacular alongside Django. REST Framework helps you extend your application in order to have a REST API, while drf-spectacular will help you the ability to generate the OpenAPI spec (standalone post: Create OpenAPI spec for Django REST Framework APIs.

After having the OpenAPI spec, you can generate clients with openapi-generator. Here is an example I mapped out of generating an Angular client:

Diagram of the flow from OpenAPI, to code via openapi-generator, then npm publish, live on npm, them npm install api-client, then Angular

Step-by-step process

There is also a recording from my GLT 2025 talk where I summarize most of these ideas.

Building better APIs from Django to Client Libraries with OpenAPI by Harald Nezbeda Building Better APIs - From Django to Client Libraries with OpenAPI

In case you want to follow along, here is a step-by-step guide from the repository I showed during the presentation:

From the last step, you can generate the API clients for the platform you require. You can follow the README and the examples available in my glt25-client repository.

Maintaining compatibility over time

The final tool you can use is openapi-diff, which will help you keep your documentation compatible. This is very important once your REST API is used in production:

Example of a compatible change: glt25-demo v1 to v2

docker run --rm -t openapitools/openapi-diff:latest https://github.com/nezhar/glt25-demo/releases/download/v1/openapi.yaml https://github.com/nezhar/glt25-demo/releases/download/v2/openapi.yaml

Example of a breaking change: glt25-demo v2 to v3

docker run --rm -t openapitools/openapi-diff:latest https://github.com/nezhar/glt25-demo/releases/download/v2/openapi.yaml https://github.com/nezhar/glt25-demo/releases/download/v3/openapi.yaml

Automating the maintenance

The process can be automated even further using GitHub Actions and Dependabot. Here are what the steps look like with this full continuous delivery setup:

GitHub Release Published, then Generate OpenAPI Schema, then Upload Schema to Release, then Build Client, then Publish to npm

Takeways

Building a complete API development workflow from Django to client libraries using OpenAPI creates a powerful and maintainable development experience. By combining Django REST Framework with drf-spectacular for automatic OpenAPI spec generation and openapi-generator for client creation, you can eliminate manual API documentation and reduce integration errors.

If you want to go even further, you can automate the integration of error codes inside the OpenAPI spec. This way you can better support languages that are even more strict when consuming the REST API!


Thank you to Harald Nezbeda for proposing this guest post on the Django blog!

August 13, 2025 02:03 PM UTC


Real Python

Python's with Statement: Manage External Resources Safely

Understand Python's with statement and context managers to streamline the setup and teardown phases in resource management. Start writing safer code today!

August 13, 2025 02:00 PM UTC


PyCharm

Lightning-Fast Python: Mastering the uv Package Manager

Check out our recent livestream from August 7 on uv, a next-generation Python package manager revolutionizing Python development with speeds 10-100x faster than pip. Released just last year and written in Rust, uv replaces long-standing Python dependency management challenges with a single, lightning-fast tool that just works. Join us as we demonstrate uv‘s game-changing capabilities […]

August 13, 2025 01:13 PM UTC


Ned Batchelder

Starting with pytest’s parametrize

Writing tests can be difficult and repetitive. Pytest has a feature called parametrize that can make it reduce duplication, but it can be hard to understand if you are new to the testing world. It’s not as complicated as it seems.

Let’s say you have a function called add_nums() that adds up a list of numbers, and you want to write tests for it. Your tests might look like this:

def test_123():
    assert add_nums([1, 2, 3]) == 6

def test_negatives():
    assert add_nums([1, 2, -3]) == 0

def test_empty():
    assert add_nums([]) == 0

This is great: you’ve tested some behaviors of your add_nums() function. But it’s getting tedious to write out more test cases. The names of the function have to be different from each other, and they don’t mean anything, so it’s extra work for no benefit. The test functions all have the same structure, so you’re repeating uninteresting details. You want to add more cases but it feels like there’s friction that you want to avoid.

If we look at these functions, they are very similar. In any software, when we have functions that are similar in structure, but differ in some details, we can refactor them to be one function with parameters for the differences. We can do the same for our test functions.

Here the functions all have the same structure: call add_nums() and assert what the return value should be. The differences are the list we pass to add_nums() and the value we expect it to return. So we can turn those into two parameters in our refactored function:

def test_add_nums(nums, expected_total):
    assert add_nums(nums) == expected_total

Unfortunately, tests aren’t run like regular functions. We write the test functions, but we don’t call them ourselves. That’s the reason the names of the test functions don’t matter. The test runner (pytest) finds functions named test_* and calls them for us. When they have no parameters, pytest can call them directly. But now that our test function has two parameters, we have to give pytest instructions about how to call it.

To do that, we use the @pytest.mark.parametrize decorator. Using it looks like this:

import pytest

@pytest.mark.parametrize(
    "nums, expected_total",
    [
        ([1, 2, 3], 6),
        ([1, 2, -3], 0),
        ([], 0),
    ]
)
def test_add_nums(nums, expected_total):
    assert add_nums(nums) == expected_total

There’s a lot going on here, so let’s take it step by step.

If you haven’t seen a decorator before, it starts with @ and is like a prologue to a function definition. It can affect how the function is defined or provide information about the function.

The parametrize decorator is itself a function call that takes two arguments. The first is a string (“nums, expected_total”) that names the two arguments to the test function. Here the decorator is instructing pytest, “when you call test_add_nums, you will need to provide values for its nums and expected_total parameters.”

The second argument to parametrize is a list of the values to supply as the arguments. Each element of the list will become one call to our test function. In this example, the list has three tuples, so pytest will call our test function three times. Since we have two parameters to provide, each element of the list is a tuple of two values.

The first tuple is ([1, 2, 3], 6), so the first time pytest calls test_add_nums, it will call it as test_add_nums([1, 2, 3], 6). All together, pytest will call us three times, like this:

test_add_nums([1, 2, 3], 6)
test_add_nums([1, 2, -3], 0)
test_add_nums([], 0)

This will all happen automatically. With our original test functions, when we ran pytest, it showed the results as three passing tests because we had three separate test functions. Now even though we only have one function, it still shows as three passing tests! Each set of values is considered a separate test that can pass or fail independently. This is the main advantage of using parametrize instead of writing three separate assert lines in the body of a simple test function.

What have we gained?

August 13, 2025 10:14 AM UTC


Seth Michael Larson

Transferring “UTF8.XYZ”

August 13, 2025 12:00 AM UTC


Quansight Labs Blog

Python Wheels: from Tags to Variants

The story of how the Python Wheel Variant design was developed

August 13, 2025 12:00 AM UTC

August 12, 2025


PyCoder’s Weekly

Issue #694: Performance, Classes, t-strings, and More (Aug. 12, 2025)

August 12, 2025 07:30 PM UTC


Python Morsels

Checking for string prefixes and suffixes in Python

Python's strings have methods for checking whether a string starts or ends with specific text and for removing prefixes and suffixes.

Table of contents

  1. Slicing works, but there's a better way
  2. The startswith and endswith methods
  3. Checking for multiple string prefixes/suffixes
  4. Removing a string prefix or a suffix in Python
  5. How is this different from the strip method?
  6. Finding and removing string prefixes and suffixes

Slicing works, but there's a better way

We have a couple strings and we'd like to check whether one string is a prefix of another:

>>> filename = "report_housing_2030.pdf"
>>> prefix = "report_"

We could do that by getting the length of the prefix string and then slicing the other string to get the same prefix from it, and then comparing those strings to see whether they're equal:

>>> filename[:len(prefix)] == prefix
True

If we wanted to check whether one string was a suffix of another, we could do the same thing using negative indexes and slicing from the end of the string:

>>> tag = "app:v2.1.0-alpine"
>>> suffix = "-alpine"
>>> tag[-len(suffix):] == suffix
True

This all works, but this code is more awkward that it needs to be.

The startswith and endswith methods

Strings in Python have a …

Read the full article: https://www.pythonmorsels.com/prefixes-and-suffixes/

August 12, 2025 02:15 PM UTC


Real Python

Working With Python's .__dict__ Attribute

Explore Python's .__dict__ attribute to manage class and instance attributes directly for more flexible, low-level control of your objects.

August 12, 2025 02:00 PM UTC