10 Jan 2026
Planet Python
EuroPython: Humans of EuroPython: Jakub Červinka
EuroPython wouldn't exist if it weren't for all the volunteers who put in countless hours to organize it. Whether it's contracting the venue, selecting and confirming talks & workshops or coordinating with speakers, hundreds of hours of loving work have been put into making each edition the best one yet.
Read our latest interview with Jakub Červinka, a member of the EuroPython 2025 Operations Team and organizer of PyConCZ 2026.
Thank you for your service to EuroPython, Jakub!
Jakub Červinka, member of the Operations Team at EuroPython 2025
EP: What first inspired you to volunteer for EuroPython?
The community has always been the biggest draw for me. Having volunteered at our local Python conference previously, I already knew how rewarding it is to be part of the organizing team. When the opportunity to join EuroPython came up, I jumped at it without a second thought. I really like connecting with organizers, speakers, and attendees from across the continent.
EP: What&aposs one task you handled that attendees might not realize happens behind the scenes at EuroPython?
One year I took on the role of "designated driver", essentially the person who handles the last-minute, ad-hoc tasks that arise during the conference. It ranged from running out to buy a cart full of hygiene products for the bathrooms, to hauling cases of bottled water when we were about to run dry, to picking up emergency prints on one of the hottest days of the year. These are the kinds of small but critical jobs that keep everything running smoothly, and I enjoy making sure they get done.
EP: How did volunteering for EuroPython impact your relationships within the community?
In the best possible way. Over the years, I've built lasting friendships, met people I had only known from online talks and tutorials, and had the chance to become a familiar face in the community myself. Every EuroPython and every local conference strengthens those connections and leaves you with renewed energy and inspiration to keep contributing.
EP: What&aposs one thing you took away from the experience that you still use today?
The importance of recognition and appreciation. A simple "thank you" or "great job" from an attendee can mean a lot to volunteers. We're doing important work, but it's not our paid job. That experience has made me much more intentional about expressing gratitude to everyone who helps, whether they're fellow volunteers, staff, or people in service roles.
EP: Do you have any tips for first-time EuroPython volunteers?
Don't be afraid to ask questions or offer help, there's always something that needs doing, and everyone can contribute in their own way. Keep an eye out for small improvements you could suggest, introduce yourself to people, and most importantly, enjoy the experience. Volunteering is as much about building relationships and having fun as it is about getting tasks done.
EP: Thank you, Jakub!
10 Jan 2026 9:49am GMT
09 Jan 2026
Planet Python
Mike Driscoll: How to Switch to ty from Mypy
Python has supported type hinting for quite a few versions now, starting way back in 3.5. However, Python itself does not enforce type checking. Instead, you need to use an external tool or IDE. The first and arguably most popular is mypy.
Microsoft also has a Python type checker that you can use in VS Code called Pyright, and then there's the lesser-known Pyrefly type checker and language server.
The newest type checker on the block is Astral's ty, the maker of Ruff. Ty is another super-fast Python utility written in Rust.
In this article, you will learn how to switch your project to use ty locally and in GitHub Actions.
Installation
You can run ty with uvx if you do not want to install it by using the following command in your terminal: uvx ty
To install ty with uv, run the following:
uv tool install ty@latest
If you do not want to use uv, you can use the standalone installer. Instructions vary depending on your platform, so it is best to refer to the documentation for the latest information.
Note: Technically, you can use pip or pipx to install ty as well.
Running ty Locally
Running with uv
uv run ty
Running without Installation
uvx ty
Running ty Directly
ty check
Configuring ty
- pyproject.toml
- ty.toml
There are many rules that you can change. Check out the documentation for full details.
In general, if you run mypy in strict mode, then running ty without changing any of its settings is very similar. However, ty currently does not highlight missing type hints. If you need to enforce adding type hints, you can use Ruff's flake8-annotations.
Here is how to enable the flak8-annotations in your pyproject.toml file:

If you have other rules already selected, you can add "ANN" to the end of the list to enable it.
Running ty in GitHub Actions
.github/workflows/ty.yml
Make sure you include the leading period!
Next, inside your yaml file, you will add the following code:
name: ty
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch:
jobs:
build:
if: github.event.pull_request.draft == false
runs-on: self-hosted
steps:
- uses: actions/checkout@v3
- name: Install Python
uses: actions/setup-python@v4
with:
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install ty==0.0.7
- name: Run ty
run: ty check
continue-on-error: false
Now, when your team opens a new PR in your project, it will automatically run ty against it. Feel free to update the Python version to the one you are using. Also note that this GitHub Action sets the ty version to 0.0.7, which you may need to update as newer releases become available.
Using ty with pre-commit
- https://github.com/NSPC911/ty-pre-commit
- https://github.com/JacobCoffee/ty-pre-commit
- https://github.com/hoxbro/ty-pre-commit
- https://github.com/allganize/ty-pre-commit
- https://foundry.fsky.io/vel/ty-pre-commit
When Astral supports pre-commit itself, you should update your pre-commit configuration accordingly.
However, for this tutorial, you can use that first link which tells you to add the following to your .pre-commit-config.yaml:

Now, when you commit a file locally, pre-commit will run ty to check it for you automatically.
Wrapping Up
Type checkers can be really helpful in finding subtle bugs in your Python code. However, remembering to run them before pushing your code can be difficult, so make your life easier by adding the type checker to your CI!
Have fun and happy coding!
The post How to Switch to ty from Mypy appeared first on Mouse Vs Python.
09 Jan 2026 3:16pm GMT
The Python Coding Stack: Parkruns, Python’s enumerate and zip, and Why Python Loops Are Different from Other Languages • [Club]
If you live in the UK, you're probably familiar with the Parkrun tradition: a friendly 5k run held every Saturday morning in hundreds of parks across the UK. Runners range from Olympians to people trying to lose some weight. It's a well-oiled format replicated across all 893 Parkrun locations.
And here's how they deal with the finish line logistics. Runners don't wear bibs with numbers. When they cross the finish line, they enter a "funnel" marked by plastic cones and are handed a token with their position number. They then proceed to another official, who scans their personal barcode, which runners carry in their pockets or on a wristband, and the position token they received a few seconds earlier. This process matches the runner with their finishing position.
What's this got to do with Python loops? And how does it help us understand why Python does loops differently from other languages?
First step, let's create the Parkrun funnel. I'll just put the first five finishers in this example:
>>> funnel = ["Jonathan", "Michael", "Samantha", "Jessica", "Daniel"]
Now, here's something you definitely know already because it's always one of the first things you're taught when learning Python: Don't loop through this list like this:
# Avoid this when coding in Python
>>> i = 0
>>> while i < len(funnel):
... name = funnel[i]
... print(name)
... i += 1
...
Jonathan
Michael
Samantha
Jessica
Daniel
This style mimics how other languages may work: you manually define and increment the index. To be fair, most people who shift from other languages are more likely to write the following version at some point:
# Also best to avoid this in Python
>>> for i in range(len(funnel)):
... name = funnel[i]
... print(name)
...
Jonathan
Michael
Samantha
Jessica
Daniel
This version may seem more Pythonic since it uses Python tools such as range(), but still fails to make the most of Python's iteration protocol. The Pythonic way of looping through this list is the following:
>>> for name in funnel:
... print(name)
...
Jonathan
Michael
Samantha
Jessica
Daniel
A question that's often asked but rarely answered is: Why is this version preferred over the other two? I'll write another short post to answer this question soon as I want to keep these The Club posts short whenever possible. So, let me state just a few reasons (there are more) and then I'll move on to my main topic for today.
-
It's more readable
-
It's more efficient (try timing the versions above using
timeit-remove theprint()calls first) -
It's less prone to errors and bugs
-
It works with a broader selection of data structures, not just sequences
While you wait for my follow-up post on this, you can read more about Python's Iterator Protocol, iterables, and iterators here:
But let's move on.
Let's say you want to print out the names alongside each runner's position. You'd like the following output:
1. Jonathan
2. Michael
3. Samantha
4. Jessica
5. Daniel
"Aha!" I'm often told by some learners, "This is when you need to use the for i in range(len(funnel)) idiom, since you need the index!"
Python's for loop doesn't explicitly use the index, so you don't have access to the index within the for loop. Many revert to the non-Pythonic idioms for this.
But Python provides tools that let you stay within the pure Pythonic style. Python's for loop needs an iterator-it will create one from the iterable you provide. All Python iteration needs iterators, not just for loops. Iterators are Python's tool for any iteration.
And there are some bespoke iterators in Python that handle most of your iteration needs. I recently wrote a series about the itertools module. The itertools module contains many such tools. Here's the series: The itertools Series.
But there are also two built-in tools that many forget, but are extremely useful. The first one is enumerate().
Here's how you can use it to display the Parkrun results:
>>> for index, name in enumerate(funnel, start=1):
... print(f"{index}. {name}")
...
1. Jonathan
2. Michael
3. Samantha
4. Jessica
5. Daniel
09 Jan 2026 1:57pm GMT
Real Python: The Real Python Podcast – Episode #279: Coding Python With Confidence: Beginners Live Course Participants
Are you looking for that solid foundation to begin your Python journey? Would the accountability of scheduled group classes help you get through the basics and start building something? This week, two members of the Python for Beginners live course discuss their experiences.
[ Improve Your Python With 🐍 Python Tricks 💌 - Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
09 Jan 2026 12:00pm GMT
08 Jan 2026
Planet Python
Rodrigo Girão Serrão: Recursive structural pattern matching
![]()
Learn how to use structural pattern matching (the match statement) to work recursively through tree-like structures.
In this short article you will learn to use structural pattern matching in recursive, tree-like data structures.
The examples from this article are taken from a couple of recent issues of my weekly newsletter.
A recursive data structure
Structural pattern matching excels at... matching the structure of your objects! For the two examples in this article, we'll be using a number of dataclasses that you can use to build abstract Boolean expressions:
from dataclasses import dataclass
class Expr:
pass
@dataclass
class And(Expr):
exprs: list[Expr]
@dataclass
class Or(Expr):
exprs: list[Expr]
@dataclass
class Not(Expr):
expr: Expr
@dataclass
class Var(Expr):
name: str
For example, the code Not(And([Var("A"), Var("B")])) represents the Boolean expression not (A and B).
Evaluating a Boolean expression
Suppose you have a Boolean expression built out of the components shared above. How do you evaluate that formula if you are given the assignments that map the variables to their values?
For example, if you have the assignments {"A": True, "B": False} (for example, a dictionary that maps variable names to values), how can you determine that the expression Not(And([Var("A"), Var("B")])) is True?
This is where structural pattern matching can be applied recursively and it's where it really shines!
To solve this problem, you will write a function called evaluate(expression: Expr, assignments: dict[str, bool]) -> bool. Your function accepts an expression and the assignments in the form of a dictionary and it returns the final Boolean value the expression evaluates to.
Since you're accepting an expression, you're going to use the match statement on the full expression and then create a case branch for each of the possible expressions you might have:
- a variable;
- an
Andexpression; - an
Orexpression; or - a
Notexpression.
The structure of the code looks like this:
def evaluate(expression: Expr, assignments: dict[str, bool]) -> bool:
match expression:
case Var(): pass
case And(): pass
case Or(): pass
case Not(): pass
The trick here is realising that you're using Expr as the type of the argument but really, you always expect the argument to be an instance of one of the subclasses of Expr, and not a direct Expr instance.
However, to make sure you don't trip on a weird bug later on, and because this matching is supposed to be exhaustive - you're supposed to have one case for each subclass of Expr - you can defend yourself by including a catch-all pattern that raises an error.
When I'm being lazy, I just raise a RuntimeError:
def evaluate(expression: Expr, assignments: dict[str, bool]) -> bool:
match expression:
case Var(): pass
case And(): pass
case Or(): pass
case Not(): pass
case _:
raise RuntimeError(
f"Couldn't evaluate expression of type {type(expression)}."
)
Now, it's just a matter of implementing the evaluation logic. In the case of a variable, all you have to do is fetch the variable value from the corresponding dictionary. However, to make it more convenient to...
08 Jan 2026 3:22pm GMT
Stéphane Wirtel: Automating TLS Certificate Monitoring with GitHub Actions, certificate_watcher, and Slack
Introduction
As a consultant constantly working with clients, I found myself in a familiar predicament: my head was always down, focused on delivering value to customers, but my own infrastructure monitoring was non-existent. I had no simple way to track SSL/TLS certificate expirations across the multiple domains I managed - personal sites, client projects, and community services.
I needed a solution, but I had several constraints:
- No time for complex setup: I couldn't afford to spend days installing, configuring, and deploying yet another monitoring service
- Easy maintenance: Whatever I built had to be low-maintenance - I didn't want another system to babysit
- Transparency and control: I wanted a simple text file in Git listing the hosts to monitor, so I could see exactly what was being checked and track changes over time
- Zero infrastructure: No servers to provision, patch, or pay for
Around this time, a friend named Julien shared his project called certificate_watcher, a lightweight Python tool for checking SSL certificate expiration. I contributed a few patches (if memory serves), and it clicked: what if I could combine this with GitHub Actions and Slack notifications?
08 Jan 2026 12:00am GMT
07 Jan 2026
Planet Python
Real Python: How to Build a Personal Python Learning Roadmap
If you want to learn Python or improve your skills, a detailed plan can help you gauge your current status and navigate toward a target goal. This tutorial will help you craft a personal Python learning roadmap so you can track your progress and stay accountable to your goals and timeline:
The steps in this tutorial are useful for Python developers and learners of all experience levels. While you may be eager to start learning, you might want to set aside an hour or two to outline a plan, especially if you already know your learning goals. If you don't yet have clear goals, consider spreading that reflection over a few shorter sessions across several days to clarify your direction.
Before you start, gather a few practical tools to support building your plan. This might include a notebook, a calendar or planner (digital or physical), a list of projects or goals you want to work toward, and any Python books or online resources you plan to use.
Note: If you learn best with structure and accountability, you can also follow your roadmap inside a cohort-based live course delivered by Real Python experts, with weekly live classes and live Q&A.
You can download a Personal Python Learning Roadmap worksheet to help you create your plan by clicking the link below:
Get Your Python Learning Roadmap: Click here to download a free, fillable Python learning roadmap PDF to help you set your aims and track your progress.
This tutorial will guide you through the planning process, starting with clarifying what you want to achieve and why. From there, you'll map out the practical steps that will turn your goals into a realistic, actionable roadmap.
Step 1: Define Your Goals and Motivation
To create an effective learning roadmap, you first need to know what you want to achieve and what your motivation is. For this step, you'll consider the following reflection prompt:
What do I want to accomplish with Python, and why?
Taking the time to answer this question sets the foundation for every decision you'll make as you build your roadmap.
Define Your Goals
Start by deciding what you want to accomplish with Python, then write it down. Research shows that this small step can make a meaningful difference. In a study conducted by psychology researcher Dr. Gail Matthews at Dominican University of California, participants who wrote down their goals were significantly more likely to achieve them than those who didn't.
If you're not sure yet about your goals, here are some questions for you to consider:
-
Are there specific projects-or types of projects-that you'd like to work on? For example, data analysis, game development, or building a web app.
-
In what context or setting would you like to use your Python skills? For example, at work, in school, or as part of a personal interest or side project.
Remember to write these answers down either in your notebook or on the Personal Python Learning Roadmap worksheet included in this tutorial's downloads. Having them written down will provide helpful context as you continue formulating your roadmap.
Determine Your Motivation
Once you have a general goal in mind, think about why you want to achieve it. Your motivation plays a key role in whether you'll stick with your plan over time. As clinical psychology professor Dr. Jennifer Crawford explains:
If we don't care about why we're doing [a goal], then it makes it really difficult to stick with that new behavior.
- Dr. Jennifer Crawford
She also encourages goal-setters to ask how their goals connect with something that's important to them.
This idea is echoed by psychology professor Angela Duckworth in her book Grit, where she emphasizes that a strong sense of purpose helps you persevere when you encounter obstacles that might otherwise derail your progress.
Some possible reasons behind your "why" might include:
- A personal interest or a love of learning
- A desire to start or advance a career in software development
- A goal of earning a computer science degree
- An interest in volunteering your skills-for example, creating a Python application that supports a cause you care about
As you consider your motivation, see if you can dive deeper into the root of your reasons. A deeper look can add even more meaning and staying power to your goals. For example:
Read the full article at https://realpython.com/build-python-learning-roadmap/ »
[ Improve Your Python With 🐍 Python Tricks 💌 - Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
07 Jan 2026 2:00pm GMT
Stéphane Wirtel: dsmtpd 1.2.0: Test Your Emails Risk-Free
The Test Email That Never Should Have Been Sent
You know that feeling? You're developing a new email feature, you run your test script, and boom - you realize 3 seconds too late that you used the production database. Your CEO just received an email with the subject "TEST - DO NOT READ - LOREM IPSUM".
Or worse: you configured a cloud SMTP server for testing, forgot to disable actual sending, and now your Mailgun account is suspended for "suspicious activity" because you sent 847 emails to test@example.com in 5 minutes.
07 Jan 2026 12:00am GMT
Python⇒Speed: Unit testing your code's performance, part 1: Big-O scaling
When you implement an algorithm, you also implement tests to make sure the outputs are correct. This can help you:
- Ensure your code is correct.
- Catch problems if and when you change it in the future.
If you're trying to make sure your software is fast, or at least doesn't get slower, automated tests for performance would also be useful. But where should you start?
My suggestion: start by testing big-O scaling. It's a critical aspect of your software's speed, and it doesn't require a complex benchmarking setup. In this article I'll cover:
- A reminder of what big-O scaling means for algorithms.
- Why this is such a critical performance property.
- Identifying your algorithm's scalability, including empirically with the
bigOlibrary. - Using the
bigOlibrary to test your Python code's big-O scalability.
07 Jan 2026 12:00am GMT
06 Jan 2026
Planet Python
PyCoder’s Weekly: Issue #716: Performance Numbers, async Web Apps, uv Speed, and More (Jan. 6, 2026)
#716 - JANUARY 6, 2026
View in Browser »
PyCoder's Weekly 2025 Top Articles & Hidden Gems
PyCoder's Weekly included over 1,500 links to articles, blog posts, tutorials, and projects in 2025. Christopher Trudeau is back on the show this week to help wrap up everything by sharing some highlights and uncovering a few hidden gems from the pile.
REAL PYTHON podcast
Python Numbers Every Programmer Should Know
Ever wonder how much memory an empty list takes? How about how long it takes to add two integers in Python? This post contains loads of performance data for common Python operations.
MICHAEL KENNEDY
Webinar: Building Deep Agents with Scale AI & Temporal
Build AI agents that don't stop running. Join Scale AI and Temporal to learn how Agentex and Python enables long-running, fault-tolerant agents with human-in-the-loop workflows, plus a live procurement agent demo →
TEMPORAL sponsor
What async Really Means for Your Python Web App?
Python continues to get better async support and with that comes pressure to switch. See the realistic effects that switching to async would have on your web servers.
ARTEM CHERNYAK
How uv Got So Fast
uv's speed comes from engineering decisions, not just Rust. Static metadata, dropping legacy formats, and standards that didn't exist five years ago.
ANDREW NESBITT
Articles & Tutorials
Python 3.6-3.14 Performance
One of the maintainers of Knave has been tracking Python performance data for a while and a recent upgrade of one of their machines meant they now had more info across different hardware. This post compares their performance test across Apple M1 & M5, Zen2 and Cascade Lake chips.
CREWTECH
Static Protocols in Python: Behaviour Over Inheritance
Static protocols bring structural typing to Python: type compatibility based on behaviour, not inheritance. This article explains how protocols differ from ABCs, goose typing, and classic duck typing, and how static type checkers use them to catch errors early.
PATRICKM.DE • Shared by Patrick Müller
Get Job-Ready With Live Python Training
Real Python's 2026 cohorts are open. Python for Beginners teaches fundamentals the way professional developers actually use them. Intermediate Python Deep Dive goes deeper into decorators, clean OOP, and Python's object model. Live instruction, real projects, expert feedback. Learn more at realpython.com/live →
REAL PYTHON sponsor
How to Build Internal Developer Tools With a Small Team
This opinion piece talks about how to build internal dev tools. It provides a mental model of product engineering to help decide whether to prioritise improving stability or adding new features.
PATRICKM.DE • Shared by Patrick Müller
How to Securely Store Secrets in Environment Variables
You shouldn't store API keys, tokens, or other secrets with your code, they need to be protected separately. In this post, Miguel discusses how he handles secrets with environment variables.
MIGUEL GRINBERG
2025 Python Year in Review
Talk Python interviews Barry Warsaw, Brett Cannon, Gregory Kapfhammer, Jodie Burchell, Reuven Lerner, and Thomas Wouters and the panel discusses what mattered for Python in 2025.
TALK PYTHON podcast
Python Supply Chain Security Made Easy
Learn how to integrate Python's official package scanning technology into your processes to help ensure the security of your development environment.
MICHAEL KENNEDY
PyPI in 2025: A Year in Review
Dustin summarizes all the happenings with the Python Packaging Index in 2025, including 130,000 new projects and over 2.5 trillion requests served.
DUSTIN INGRAM
Top Python Libraries of 2025
Explore Tryo-labs' 11th annual Top Python Libraries roundup, featuring two curated Top 10 lists: one for General Use and one for AI/ML/Data tools.
DESCOINS & BELLO
Implicit String Concatenation
Python automatically concatenates adjacent string literals thanks to implicit string concatenation. This feature can sometimes lead to bugs.
TREY HUNNER
Safe Django Migrations Without Server Errors
How to run schema-changing Django migrations safely, avoiding schema/code mismatches and server errors during rolling deployments.
LOOPWERK
Projects & Code
vresto: Interface for Copernicus Sentinel Data
An elegant Python interface for discovering and retrieving Copernicus Sentinel data.
GITHUB.COM/KALFASYAN • Shared by Yannis Kalfas
Liberty Mail: Email Client for Sales Outreach
GITHUB.COM/EYEOFLIBERTY • Shared by [Ivan Kuzmin]
Events
Weekly Real Python Office Hours Q&A (Virtual)
January 7, 2026
REALPYTHON.COM
Python Atlanta
January 9, 2026
MEETUP.COM
PyDelhi User Group Meetup
January 10, 2026
MEETUP.COM
DFW Pythoneers 2nd Saturday Teaching Meeting
January 10, 2026
MEETUP.COM
PiterPy Meetup
January 13, 2026
PITERPY.COM
Leipzig Python User Group Meeting
January 13, 2026
MEETUP.COM
Happy Pythoning!
This was PyCoder's Weekly Issue #716.
View in Browser »
[ Subscribe to 🐍 PyCoder's Weekly 💌 - Get the best Python news, articles, and tutorials delivered to your inbox once a week >> Click here to learn more ]
06 Jan 2026 7:30pm GMT
Django Weblog: Django bugfix releases issued: 5.2.10, 6.0.1
Today we've issued the 5.2.10 and 6.0.1 bugfix releases.
The release packages and checksums are available from our downloads page, as well as from the Python Package Index.
The PGP key ID used for these releases is Jacob Walls: 131403F4D16D8DC7
06 Jan 2026 6:00pm GMT
Real Python: Tips for Using the AI Coding Editor Cursor
Cursor is an AI-powered integrated development environment (IDE) based on the Visual Studio Code codebase. It comes with a multi-agent interface and the Composer model for fast, agentic coding while keeping a familiar editor workflow with project-aware chat, code completion, and inline edits.
In this course, you will:
- Understand why Cursor might work for you
- Learn how to use different modes & models
- See how to run multiple agents at a time
- Resolve a tiny merge conflict
- Run a project and fix a bug
- Learn commands and practice with the terminal
[ Improve Your Python With 🐍 Python Tricks 💌 - Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
06 Jan 2026 2:00pm GMT
Seth Michael Larson: “Food JPEGs” in Super Smash Bros & Kirby Air Riders
Have you ever noticed that the food graphics in Super Smash Bros. and Kirby Air Riders is flat "billboarded" stock images of food?
This artistic decision from director Masahiro Sakurai has persisted through 8 games over nearly 25 years. I've seen a few folks online remarking about the "JPEG" or "PNG"-like quality of the images in the most recent release: Kirby Air Riders.
While researching every game with this art style and all 150+ unique food images I ended up fixing wikis, reviewing a seasonal KitKat flavor, and preserving an uncatalogued image of tempura soba.

Burgers from Super Smash Bros. Melee (2001), Kirby Air Ride (2003), Super Smash Bros. Brawl (2008), Super Smash Bros. Ultimate (2018), and Kirby Air Riders (2025).
Masahiro Sakurai is the director for every game on this list, so clearly this is his artistic decision. Super Smash Bros. Melee was the first game to contain this food art style, published in 2001. This style was then repeated in Kirby Air Ride (2003), Super Smash Bros. Brawl (2008), Super Smash Bros. for 3DS and Wii U (2014), Super Smash Bros. Ultimate (2018), and most recently in Kirby Air Riders (2025).
Credit to Nintendo, HAL Laboratories, SORA Ltd., and Bandai Namco Studios as developers and publishers of these games. Artwork was sourced from the Spriters Resource.
Super Smash Bros. Melee (2001)

Where it all began! Super Smash Bros. Melee for the GameCube started off with 28 distinct food items, often found in "Party Balls". Each type of food had a different "nutritional value" and "yumminess quotient" according to the in-game trophy dedicated to the food items.
Melee included many foods specific to Japanese cuisine, such as unagi (eel), omurice, soba, dango, and gyūdon. I do distinctly remember growing up as a "culinarily sheltered" kid in the midwest United States and not understanding what many of these food items were.
The original stock images of Super Smash Bros. Melee and the next game, Kirby Air Ride, have been partially discovered and documented by a group called "Render96". The stock images are from a company called "Sozaijiten". Many of the food images come from Material Dictionary CDs Volume 14 (Vegetables & Fruits), Volume 22 (Food & Dishes), and Volume 73 (Cooking Japanese, Western, & Chinese). The apple stock image in particular was re-used all the way through Super Smash Bros. Ultimate (2018). The burger, milk, dango, and donut are still missing their primary source.
Kirby Air Ride (2003)




Kirby Air Ride for the GameCube had significantly fewer distinct food items (12) compared to Melee and maintained many of the same food stock images from Melee, including the apple, burger, chicken, curry, omurice, onigiri, and ramen. Nigiri was included, but the image was changed from a sushi board to a plate.
The stock images had their saturation increased and the black borders around the images are thicker, sometimes 2-3 pixels instead of only 1 pixel for Melee.

I paid $50 plus shipping on eBay for this PNG. This is the closest I'll get to NFTs.
While researching the foods in Kirby Air Ride I discovered a wiki description of a "tempura soba" item that I'd never heard of and wasn't included in the Spriters Resource spritesheets for Kirby Air Ride. Turns out that this item was changed to a "hotdog" in the NSTC-M and PAL releases of Kirby Air Ride.
I was unable to find a non-blurry image of the tempura soba sprite online, so of course I had to preserve this sprite myself. I purchased a Japanese copy of Kirby Air Ride, dumped the ROM using the FlippyDrive Disc Backup Utility, and ran the ROM using Dolphin with "Dump Textures" mode enabled to archive the sprite directly from the game.

Kirby Air Ride cover artwork (left: JP, right: US, PAL). Images from the GameTDB.
In the process I also learned that the cover of Kirby Air Ride changed between the Japanese and international releases. The Japanese cover art features a smiling happy Kirby where the international cover has Kirby with a furrowed brow and serious look.
Super Smash Bros. Brawl (2008)

Super Smash Bros. Brawl for the Wii has only one more food item compared to Melee (29) and introduces 11 new food items including bread, cake, candy, chocolate, cookie, melon soda, parfait, peaches, pie, pineapple, and steak.
About half of the Japanese-specific foods from both Melee and Kirby Air Ride were replaced: curry, omurice, onigiri, and ramen.
The art is less saturated and more "realistic" which is in-line with the rest of the game's art direction. The images lost their black outline, likely to draw less attention to the "arcade-y" feel that the previous titles had with food items.
Super Smash Bros 3DS and Wii U (2014)

Super Smash Bros. Wii U and 3DS have the same total number of food items as Brawl (29). These games change the food art style completely, again! It's brighter, saturated, and looks delicious.
The soda item was changed from a melon cream soda to a dark cola with lemon. The omurice was changed to a pair of fried eggs with bacon. These games are also the only ones without the "burger" food item.
Super Smash Bros. for 3DS uses the same food artwork used in Super Smash Bros. for Wii U downscaled to 64x64 pixels from 256x256 pixels with some minor editing.

Super Smash Bros. Wii U and 3DS added the "Mont Blanc" food item, which is a French dessert that is popular in Japan. I've seen multiple guides and wikis mistakenly label this food item as "noodles" due to the "vermicelli" shape of the puréed chestnuts. Yummy!
While researching and writing this blog post I happened across "Mont Blanc"-flavored KitKats. These are apparently a limited-time flavor for autumn. The KitKats are creamy and have plenty of chestnut flavor, but they are very sweet (apparently Mont Blanc is quite sweet, too, so this is to be expected).

Mont Blanc food item from Super Smash Bros Wii U, 3DS, and Ultimate
"Mont Blanc flavored limited-time KitKats"
Super Smash Bros. Ultimate (2018)

Super Smash Bros. Ultimate uses the same 29 foods from the Wii U and 3DS and adds 9 more foods for a total of 38. Many of the newly added foods are call-backs to food items in previous titles, below highlighted in pink.
The 9 new foods in Ultimate are burgers, cheese, corndogs, donuts, dumplings, daisies, pizza, pineapple, and steak.
It's clear that the "Sozaijiten" stock images were still in use even in 2018: 17 years later! The apple, cheese, and chicken stock images for Super Smash Bros. Melee match the stock images used in Ultimate.
Kirby Air Riders (2025)

Kirby Air Riders released for the Switch 2 has the most foods of any game with this art style with 45 distinct food items.
Massive thank-you to Charles Bernardo for sending me carefully cropped images of the food in Kirby Air Riders.
Kirby Air Riders is the first game in this series to use completely new models for all food items: not even the apple or cheese are the same from any previous game. Kirby Air Riders is also the first game in this series not to have a "roast chicken" item, breaking from an established video-game food trope.

Kirby Air Riders adds a new food-centric mode called "Gourmet Race" where riders earn points by consuming food as quickly as possible in a small arena. Gourmet Race introduces a new food concept: "Large Foods". Large food items are worth 15 points instead of 1 point per food item. There are 14 large food items, some presenting as "upgraded" versions of regular-sized foods.
The large food items are: a bunch of 12 bananas instead of 3, a bread-basket, a double cheeseburger, a whole cake instead of a slice, donuts, a fruit basket, a board of nigiri instead of a plate, fruit parfait, pizza, popcorn, salad, rainbow shave ice instead of blue only, a tempura bowl, and a whole watermelon instead of a slice.
Prior to this article there was not yet a complete list of foods in Kirby Air Riders documented on a wiki or spritesheet. I added this list to the Kirby wiki, but I've also included the list below:
List of food items in Kirby Air Riders
- Apple
- Bananas
- Bread Basket
- Cabbage
- Cake (Slice)
- Cake (Whole)
- Cheese
- Cheeseburger
- Cheeseburger (Double)
- Chocolate
- Cola
- Cupcake
- Donuts
- Dumpling
- Omurice
- French Fries
- Fried Rice
- Fruit Basket
- Gelatin
- Grapes
- Hamburg Steak
- Hotdog
- Icecream
- Jelly Beans
- Melon Cream Soda
- Nigiri (Plate)
- Nigiri (Board)
- Orange
- Orange Juice
- Pancakes
- Parfait
- Spaghetti
- Pizza
- Popcorn
- Ramen
- Salad
- Sambusas
- Sandwich
- Shave Ice (Blue)
- Shave Ice (Rainbow)
- Prime Rib Steak
- Tempura Bowl
- Watermelon (Slice)
- Watermelon (Whole)
Unique food items

There are 16 total food items that only appear in a single title across the 25-year span of games. Kirby Air Riders and Super Smash Bros. Melee have by far the most unique food items with 8 and 5 respectively.
| Game | Count | Foods |
|---|---|---|
| Super Smash Bros. Melee | 5 | Dango, Gyūdon, Mushroom, Soba, Unagi |
| Kirby Air Ride | 0 | |
| Super Smash Bros. Brawl | 1 | Cookie |
| Super Smash Bros. Wii U/3DS | 0 | |
| Super Smash Bros. Ultimate | 2 | Daisy, Corndog |
| Kirby Air Riders | 8 | Cabbage, Cupcake, French Fries, Fruit Basket, Gelatin, Jelly Beans, Sambusas, Sandwich |
Comparing food across games
Finally, here is a table with every image so you can compare how each changed across different titles:
| SSB Melee 2001 |
Kirby Air Ride 2003 |
SSB Brawl 2008 |
SSB Wii U/3DS 2014 |
SSB Ultimate 2018 |
Kirby Air Riders 2025 |
|
|---|---|---|---|---|---|---|
| Apple | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Bananas | ![]() |
![]() ![]() |
||||
| Bread | ![]() |
![]() |
![]() |
![]() |
||
| Burger | ![]() |
![]() |
![]() |
![]() |
![]() ![]() |
|
| Cabbage | ![]() |
|||||
| Cake | ![]() |
![]() |
![]() |
![]() ![]() |
||
| Candy | ![]() |
![]() |
![]() |
|||
| Cheese | ![]() |
![]() |
![]() |
![]() |
||
| Cherries | ![]() |
![]() |
||||
| Chicken | ![]() |
![]() |
![]() |
![]() |
![]() |
|
| Chocolate | ![]() |
![]() |
![]() |
![]() |
||
| Cola | ![]() |
![]() |
![]() |
|||
| Cookie | ![]() |
|||||
| Corndog | ![]() |
|||||
| Cupcake | ![]() |
|||||
| Curry | ![]() |
![]() |
||||
| Daisy | ![]() |
|||||
| Dango | ![]() |
|||||
| Donut | ![]() |
![]() |
![]() |
![]() |
||
| Dumplings | ![]() |
![]() |
||||
| Eggs | ![]() |
![]() |
![]() |
![]() |
![]() |
|
| Fried Rice | ![]() |
![]() |
![]() |
|||
| Fries | ![]() |
|||||
| Fruit Basket | ![]() |
|||||
| Gelatin | ![]() |
|||||
| Grapes | ![]() |
![]() |
![]() |
![]() |
![]() |
|
| Gyūdon | ![]() |
|||||
| Hamburg Steak | ![]() |
![]() |
![]() |
|||
| Hotdog | ![]() |
![]() |
![]() |
![]() |
![]() |
|
| Icecream | ![]() |
![]() |
![]() |
![]() |
||
| Jellybeans | ![]() |
|||||
| Kebab | ![]() |
![]() |
||||
| Kiwi | ![]() |
![]() |
||||
| Lemons | ![]() |
![]() |
||||
| Melon | ![]() |
![]() |
||||
| Melon Soda | ![]() |
![]() |
||||
| Milk | ![]() |
![]() |
![]() |
![]() |
||
| Mont Blanc | ![]() |
![]() |
||||
| Mushroom | ![]() |
|||||
| Nigiri | ![]() |
![]() |
![]() |
![]() ![]() |
||
| Onigiri | ![]() |
![]() |
![]() |
![]() |
||
| Orange | ![]() |
![]() |
||||
| Orange Juice | ![]() |
![]() |
![]() |
|||
| Pancakes | ![]() |
![]() |
![]() |
|||
| Parfait | ![]() |
![]() |
||||
| Pasta | ![]() |
![]() |
![]() |
![]() |
||
| Peach | ![]() |
![]() |
![]() |
|||
| Pear | ![]() |
![]() |
||||
| Pie | ![]() |
![]() |
![]() |
|||
| Pineapple | ![]() |
![]() |
||||
| Pizza | ![]() |
![]() |
![]() |
![]() |
||
| Popcorn | ![]() |
![]() |
![]() |
|||
| Ramen | ![]() |
![]() |
![]() |
|||
| Salad | ![]() |
![]() |
![]() |
|||
| Sambusas | ![]() |
|||||
| Sandwich | ![]() |
|||||
| Shave Ice | ![]() ![]() |
|||||
| Shumai | ![]() |
![]() |
![]() |
|||
| Soba | ![]() |
|||||
| Soup | ![]() |
![]() |
||||
| Steak | ![]() |
![]() |
![]() |
|||
| Strawberry | ![]() |
![]() |
||||
| Tea | ![]() |
![]() |
![]() |
![]() |
||
| Tempura | ![]() |
![]() |
![]() |
![]() |
||
| Unagi | ![]() |
|||||
| Watermelon | ![]() |
![]() |
![]() ![]() |
Thanks for keeping RSS alive! ♥
06 Jan 2026 12:00am GMT
05 Jan 2026
Planet Python
PyCharm
The next edit suggestions feature is now enabled in all JetBrains IDEs for JetBrains AI Pro, AI Ultimate, and AI Enterprise subscribers.
Yes, you read that right! JetBrains-native diff suggestions are available right in your editor. Global support for optimized latency. Out-of-the-box IDE actions for reliability. And the best part? It doesn't consume your AI quota.
What are next edit suggestions?
Like the suggestions provided by AI code completion, next edit suggestions (NES) appear as you type. The difference is that NES can be proposed beyond the immediate vicinity of your caret, and they can modify existing code instead of exclusively adding new code. This feature is a natural extension of code completion, and together they comprise the in-flow Tab-Tab experience.

The NES feature runs silently in the background, generating suggestions as you modify your code. It then gives you the option to review and decide whether to accept them in a small in-editor diff view (the NES UI). The feature adapts how it presents the suggestions, showing them to you in the least intrusive way to avoid interfering with your work. Large changes appear in a dedicated diff view, while smaller suggestions are shown in a larger popup.

Overall, NES provide a smart code editing experience. Let's agree to share responsibilities as follows: you can simply type and continue development as you used to, and we suggest small digestible diffs that help you do your job faster. Deal?
Who can use NES?
With the latest AI Assistant update, next edit suggestions are enabled by default for all users with AI Pro, AI Ultimate, or AI Enterprise subscriptions. Unlike AI code completion, the next edit suggestions feature is currently unavailable for AI Free license holders. Stay tuned, though - we are actively working on bringing it to a wider audience!
You can always learn more about which AI features are available in different pricing tiers on our official page.
How do NES work?
Trust us, there is a lot we could say about the internals, but we'll try to keep things simple here.
Long story short, next edit suggestions are where AI meets 🤝 the intelligence of JetBrains IDEs. Under the hood, the feature calls our cloud-based custom AI model and leverages deterministic IDE actions where possible.
AI model
Currently, at their core, NES rely mostly on suggestions provided by a model fine-tuned specifically for this task.
Much like Mellum, the model is a small language model (SLM) that leverages cloud GPU infrastructure to provide the best possible latency all around the world. Unlike Mellum, however, the underlying model is bigger and leverages a different type of context: the history of your recent changes as opposed to the current file and RAG.
Bigger does not always mean slower! Our inference pipelines differ for code completion and next edit suggestions generation. NES employ several inference tricks that keep latency under 200 ms for the majority of requests, even at the busiest times of the day 💪. If you ever thought that completion in JetBrains IDEs was slow, it's time to reconsider!
IDE actions (code insights)
Developers love our IDEs because of their reliability, and next edit suggestions put that aspect at your fingertips.
As part of their pipeline, when invoked, NES look for available code insights provided by the IDE and show them in the NES UI if they are appropriate. One of the easiest ways to see this interaction at work would be to look at a suggestion that renames an identifier in a file. The next edit suggestion will activate the IDE's Rename refactoring, and usages will be conveniently updated. This even works with multi-file search!

The integration between next edit suggestions and IDE code insights is not yet fully complete. Because even frontier models struggle with out-of-distribution tools, or even just having a large number of tools in general, we are intentionally adding new IDE actions to NES slowly. We are prioritizing the ones that are useful the most often, as well as the ones the models can use most effectively. Let us know in the comments which IDE actions you would find useful in NES!
Summary
Next edit suggestions don't replace the existing forms of code completion, but complement them, ensuring the best speed and relevance. Where code completion provides suggestions for new material, the next edit suggetions model works in the field of, well, edits. It is optimised to propose changes to existing code, but sometimes the best edit is simply to add something new. In those cases, the suggestions will look like completions because they are presented the same way - as inline gray text.
The simple scheme below explains which suggestion provider can be handled by which UI.

Settings panel update
In addition to enabling this new feature, we are redesigning the settings for AI code completion and next edit suggestions. Shortly after the start of the new year, the settings for these features will be simplified. Instead of having to navigate multiple views, you will be able to view everything on a single screen, with all the most important options available.
Here's a sneak peek of the new design:

As you can see, the settings for local completion, cloud-based completion, and next edit suggestions are all combined on a single page where you can decide what you want and what you don't.

AI code completion and NES cheat sheet
Deciding which types of suggestions to enable may feel a bit overwhelming, so we've put together a short cheat sheet to help clarify which settings to enable in the new settings panel, depending on your preferred workflow.
Case 1: You don't want AI in your editor
Simply turn off inline completion and next edit suggestions on this panel. We'll make sure you don't see any results of matrix multiplications.
Case 2: You don't want cloud-based suggestions
Just turn on inline completion with local models. Those models are already bundled into your IDE and work without an internet connection. Good ol' full line code completion will have your back.
If you want your own local solution, you can plug any open-source model into the IDE via LM Studio or Ollama. This option is available on the AI Assistant | Models settings page. Note that, currently, this option only works for code completion. We will closely monitor the level of quality that is possible with local inference for NES, with the aim of eventually including it as well.
Case 3: You like completion but NES seem off
In this case, the best solution is to turn on inline completion with the Cloud and local models option and make sure that next edit suggestions are turned off. You will get the best from the Mellum model, and the IDE will automatically fall back to local models if your internet connection is unstable.
Case 4: You like full-blown in-editor AI assistance
Turn on both cloud models for inline completion and next edit suggestions to get code snippet suggestions as you modify your source code.
What's next for NES?
Here is a quick look at some of the improvements we're already working on:
- Smarter and more precise suggestions
- More IDE actions for NES to use
- Longer tab sequences
Many other developments are on our radar, and we'll keep you updated as they come closer to fruition.
Thank-you note
While you update your AI Assistant and GPUs go brrr, we would like to thank everyone who participated in the open Beta test for the next edit suggestions feature this fall.
Over the last few months, the feature has been available to JetBrains AI subscribers who were willing to try it and share anonymous usage statistics. With your help, we were able to make sure the feature was ready and properly prepare the cloud infrastructure for a full-scale release. Thank you so much! ❤️
Tab-Tab,
Your AI completion team
05 Jan 2026 7:41pm GMT
Real Python: Learn From 2025's Most Popular Python Tutorials and Courses
As we welcome 2026, it's time to look back on an exciting year for Python. Python 3.14 arrived with a wave of developer-focused improvements, from lazy annotations that finally resolve long-standing type hinting quirks to clever new t-strings that give you more control over string interpolation.
Meanwhile, 2025 was the year AI tools truly became part of everyday Python development. From agentic coding with LangGraph to connecting LLMs to your data via MCP servers, Python solidified its position as the language of choice for AI-powered workflows.
Here at Real Python, we're excited to showcase the tutorials and video courses that resonated most with our community throughout 2025. Whether you're just starting out with Python, leveling up your skills, or diving into advanced topics, this collection has something for you.
Join Now: Click here to join the Real Python Newsletter and you'll never miss another Python tutorial, course, or news update.
Take the Quiz: Test your knowledge with our interactive "Python Skill Test" quiz. You'll receive a score upon completion to help you track your learning progress:
Interactive Quiz
Python Skill TestTest your Python knowledge in a skills quiz with basic to advanced questions. Are you a Novice, Intermediate, Proficient, or Expert?
Strengthen Your Python Foundations
If you're just getting started with Python, building a solid foundation is the best investment you can make. The fundamentals you learn now will support everything you do later, from data analysis to web development to AI.
These beginner-friendly tutorials and courses help you sharpen the core skills you'll use every day in Python, including loops, operators, lists, and functional techniques:
- How to Join Strings in Python
- Skip Ahead in Loops With Python's continue Keyword
- Nested Loops in Python
- Python Operators and Expressions
- Exploring Python's list Data Type With Examples
- Using Functional Programming in Python
If you're looking to accelerate your learning with live instruction, then check out our Python for Beginners Live Course, where you can learn alongside other students and get real-time feedback from experienced instructors.
And don't forget to grab our downloadable Python 3 Cheat Sheet to keep essential syntax and concepts at your fingertips:
Explore What's New in Python 3.14
Python 3.14 brought a collection of thoughtful improvements that make writing and debugging code more enjoyable. The REPL now feels like a proper modern shell, making third-party REPLs like IPython, ptpython, and bpython less necessary. Type hints behave more intuitively, error messages point you in the right direction faster, and t-strings open up new possibilities for string processing.
These tutorials walk you through the updates you'll want to start using right away:
- Python 3.14: Cool New Features for You to Try
- Python 3.14: Lazy Annotations
- Python 3.14: REPL Autocompletion and Highlighting
- Python 3.14: Better Syntax Error Messages
- Python 3.14: Template Strings (T-Strings)
If you're curious about any other new features, you can also read the 3.14 release notes. Staying current with new Python releases helps you write cleaner code and take advantage of performance improvements as they land.
Read the full article at https://realpython.com/popular-python-tutorials-2025/ »
[ Improve Your Python With 🐍 Python Tricks 💌 - Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
05 Jan 2026 2:00pm GMT
Real Python: Quiz: How to Properly Indent Python Code
In this quiz, you'll test your understanding of How to Indent in Python.
By working through this quiz, you'll revisit how to properly indent Python code, choose helpful editor settings, use spaces properly, apply code formatters, and explain why indentation is required.
[ Improve Your Python With 🐍 Python Tricks 💌 - Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
05 Jan 2026 12:00pm GMT





