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!
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 […]
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.
PyCharm
The State of Python 2025
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.
Armin Ronacher
Your MCP Doesn’t Need 30 Tools: It Needs Code
August 17, 2025
Seth Michael Larson
How many RSS subscribers do I have?
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 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:
- pythontest.com - where I write about developing software with tests
- pythonbytes.fm - Python news and headlines, delivered directly to your earbuds
Thanks for all the fun over the last 10 years.
I wish you the best.
Keep in touch
- Sign up for the PythonTest Newsletter
- Join the PythonTest Community
- Or pick up a pytest course or pytest book
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.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.
Glyph Lefkowitz
The Futzing Fraction
At least some of your time with genAI will be spent just kind of… futzing with it.
Seth Michael Larson
Nintendo Switch Online + Expansion Pack is great for digital and physical GameCube players
August 14, 2025
Python Insider
Python 3.14.0rc2 and 3.13.7 are go!
Python Software Foundation
Announcing the PSF Board Candidates for 2025!
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, […]
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:
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
In case you want to follow along, here is a step-by-step guide from the repository I showed during the presentation:
- Create a Django project
- Add a Django app
- Models and database migrations
- DRF serializers
- DRF views
- Configure URLs
- Add and configure drf spectacular
- Generate OpenAPI
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:
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!
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!
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 […]
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?
- We don’t have to write three separate functions with different names.
- We don’t have to repeat the same details in each function (
assert
,add_nums()
,==
). - The differences between the tests (the actual data) are written succinctly all in one place.
- Adding another test case is as simple as adding another line of data to the decorator.
Seth Michael Larson
Transferring “UTF8.XYZ”
Quansight Labs Blog
Python Wheels: from Tags to Variants
The story of how the Python Wheel Variant design was developed
August 12, 2025
PyCoder’s Weekly
Issue #694: Performance, Classes, t-strings, and More (Aug. 12, 2025)
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.
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/
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.